[gnutls-devel] [TLS] multiple clients in one process (was: Re: Deployment ... Re: This working group has failed)

Nikos Mavrogiannopoulos nmav at gnutls.org
Sun Dec 1 10:40:54 CET 2013

On Sat, 2013-11-30 at 20:14 -0600, Nico Williams wrote:
> On Sat, Nov 30, 2013 at 3:08 AM, Nikos Mavrogiannopoulos
> <nmav at gnutls.org> wrote:
> > On Fri, 2013-11-29 at 18:10 -0600, Nico Williams wrote:
> >> 4) DO NOT USE ELF .ini sections for thread-safe initialization, [...]
> >
> > Have you considered or tried using that approach in your branch of
> > openssl and backed off? If dependencies are avoided it looks like an
> > ideal fix, especially if you consider that a global initialization
> > function would do much more than just initializing mutexes (e.g.
> > precalculations or CPU type detection).
> .init sections have all of these problems:
>  - they aren't standard (not part of POSIX)
>  - they're not necessarily available in static linking cases (after
> all, they are not standard)
>  - they require more autoconf/source/build complexity
>  - the order in which dependencies are loaded and their .init sections
> run is unstable -- you can help yourself a bit by having no
> dependencies on anything other than -lc and -lpthread in your .init
> section, but you can't help anyone else who has a dependency on your
> library in their .init sections(!)
> Whereas using pthread_once() and friends is all standard.  You can
> build a pthread_once/InitOnceInitialize out of mutexes if you have
> static mutex initializers, and you can build those if you have CAS.
> Besides, the once approach is elegant and lends itself well to doing
> the Right Thing, which is: automatically and thread-safely
> self-initialize.

The more I think about static initialization of mutexes the more I think
they are not a good idea for a library. How would you deinitialize a
statically initialized mutex? Never? Then you get a memory/resource leak
in the PAM case you are referring to. As these modules are opened with
dlopen() and dlclosed later they leave the static mutex initialized.

If you deinitialize on the last call to the deinitialization function
then assuming you have other threads calling the global initialization
function in parallel you may even get crashes during that
deinitialization if they try to lock it.

There is no easy solution there instead of using a destructor to
deinitialize the static mutex. Thus again you are using the
"non-standard" destructors.

Thus the only elegant solution I see is initialization on a constructor
and deinitialization on a destructor. That works on ELF libraries and
DLL libraries (yes it doesn't work on static libraries), but that is
already a significant fraction of what we want to support.


More information about the Gnutls-devel mailing list