[gnutls-dev] Re: living without global variables

Bryan Henderson bryanh at giraffe-data.com
Sun Dec 25 19:47:18 CET 2005


>It is the ASN.1 schema for various PKCS and PKIX standards, in a
>compiled form for libtasn1.

I have no idea what those words mean, but I guess I don't have to.

>Perhaps GnuTLS should deallocate these variables in an `atexit' hook
>instead.  Then it seem all of this problem would go away.  In GNU
>libc, atexit hooks are even called if GnuTLS was dlopen+dlclose'd.
>gnutls_global_deinit() would then only call gc_done().

If you're willing to do that, you should be willing just to skip the
deallocate altogether.  On process termination, memory allocation
becomes irrelevant.  Most engineers I know prefer to have more
modularity -- the library doesn't know about process termination or
program lifetime; it has a matching setup and shutdown and after
shutdown, everything is back the way it was before setup.  But this
would be acceptable to me (acceptable means I would still use GnuTLS).

You know, I've seen the code of dozens of Unix libraries and hundreds
of Unix programs, and I don't think I've ever seen atexit() used.  And
while I've been reminded of its existence from time to time, I've
never been able to come with a use for it in my own code.

>That is a memory leak, but a pretty insignificant one, and one
>that would happen rarely.  There is no serious problem, that cannot
>easily be solved by the caller, as far as I can see.  Nothing else bad
>will happen, as far as I can see.

You're probably right, though I prefer not to attempt analyses of this
kind.  It's easier just to say it's thread safe or it's not.  In this
case, it's not, and you're pointing out that the user can tolerate
that as he does any non-thread-safe library -- make sure he doesn't
call it simultaneously from two different threads.  I also agree that
the damage is slight and very unlikely, and a user may be willing just
to sweep it under the carpet.  But I've never seen anyone take the
position that just a little thread unsafety or a little memory leak is
OK in published code -- computer people are always interested in
precision.

>Alternatively, each thread could do a mutex around the call to
>gnutls_global_init:

And that's the nonmodularity I'm trying to get around.  Each thread has
to be aware that other modules in other threads might be using the same
library and agree with them on a locking protocol.

>For example, many libraries has chosen to only support one thread
>library, and then use mutexes from that thread library to solve
>problems like this.  GnuTLS could have done that too, and wrapped
>gnutls_global_init and gnutls_global_deinit around thread mutexes.
>But I believe that is too inflexible for GnuTLS, consider this:

Yes, I agree.

There are only two methods I've seen to make a stateful library thread-safe:

  1) the library routines use locks

  2) the library routines each take a complete context as an argument
     (usually thought of as the object oriented approach).

I prefer (2).

>Read-only constant global variables are not a serious problem as far
>as I know.

These aren't read only, of course -- they get set twice.  But the exemption
still holds as long as a global variable is repeatably settable.  For
example,

   static struct {
      int version;
      int maxConnections;
   } globalStuff;

   void
   global_init() {
     globalStuff.version = 3;
     globalStuff.maxConnections = 1024;
   }

is acceptable as an alternative to having the loader set those
constants with a C initial value declaration.  But when there's a
malloc involved, you don't have the repeatability (i.e. subsequent
sets are not idempotent).

What I haven't seen so far in all the fishing for an alternative is
what is the drawback to adding the 3 functions to allow a thread to
have totally private context if it wants?

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



More information about the Gnutls-dev mailing list