[gnutls-dev] Re: living without global variables

Bryan Henderson bryanh at giraffe-data.com
Sat Dec 24 10:44:53 CET 2005


>The entire tree is constant as well.

That's great.  I really couldn't tell just what information is in there.
What is it, anyway?  Something you can explain quickly?

The information from Nikos that reference counting will be implemented
solves another part of the problem (but I'm a little skeptical about that
because the old code seemed to be pretty deliberate in not doing reference
counting; it actually looks like there was reference counting before and
someone undid it for some reason).

But there's still more work to do.  It isn't thread-safe.  Often, a
program is modular in that two threads are executing separate code
independently.  If both of those threads decide to use the facilities
of the gnutls library, they might simultaneously call
gnutls_global_init() and the reference count would get screwed up.

On the other hand, in what I propose each thread has its own memory
and there can't possibly be a conflict.  (The synchronization point
moves to malloc(), which is a reliable place for it).

>Remember that API changes are bad.

But API _additions_ are no big deal.  I'm talking about adding three
new functions for people to use optionally in place of three existing
ones, and people who use the existing ones will see no difference at
all.

>I think it would be useful to see exactly what changes you are
>thinking of in more detail.

I don't want to go so far as coding a patch if you don't buy into the
basic idea, because it would be too much work.  But let me try a more
detailed explanation.  This is nothing revolutionary -- it's how lots
of libraries work in order to cater to threaded, modular, object
oriented programs.

A program calls gnutls_create_session_group() instead of
gnutls_global_init().  This new function returns a "session group" handle.
The program then calls gnutls_session_init_group() instead of
gnutls_session_init().  This new function takes that session group handle
as an argument.  When it's all done, the program calls
gnutls_destroy_session_group(handle) instead of gnutls_global_deinit().

The session handle is really a pointer to a descriptor (struct) that
contains root pointers for the "global" trees.  So each session group
has its own copy of the trees.

The session group handle gets added to the session descriptor, and
everything in gnutls that references the trees references them via the
relevant session group descriptor instead of direct reference to
global variables.  Some internal functions need to get an extra
parameter so they know which tree to access.

So that the existing API keeps working, there is a global session
group descriptor that takes the place of the two global tree pointers.
gnutls_global_init() does a gnutls_create_session_group() of that
descriptor and gnutls_session_init() does a
gnutls_session_init_group() with the global handle.

>I'm not sure exactly what real problem you are having.

I thought the basic global variable issue was widely enough known that
there wouldn't be a need to describe a particular scenario, but I'll
tell you where I'm coming from.  I don't have a program that crashed.
I distribute a library (XML-RPC for C/C++) that uses gnutls.
(Actually, it's worse.  It uses Curl, and Curl uses gnutls).  My users
want to write object oriented programs with multiple threads.  I know
that because Curl has a global init function, and one reason it has
that is because gnutls does, I can't give my users that because my
code has to initialize gnutls and I have no way to keep my gnutls
initialization from conflicting with gnutls initializations that the
user does for other purposes (it's the simultaneous reference count
update problem I described above).

The best I can do is expose the deep underlying use of gnutls (no easy
thing, since gnutls is only one of Curl's SSH options and Curl is only
one of Xmlrpc-c's HTTP options) and tell the user he has to supply an
already initialized gnutls environment to me.

But with the session group concept, it's a snap.  I just give each
Xmlrpc-c client object its own Curl client object and each Curl client
object its own gnutls session group, and I can't possible interfere
with the user's other uses of gnutls.  The only thing I'm sharing with
them is the code of gnutls.

-- 
Bryan Henderson                                    Phone 408-621-2000
San Jose, California




More information about the Gnutls-devel mailing list