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

Andy Lutomirski luto at amacapital.net
Sun Dec 1 16:21:07 CET 2013


On Dec 1, 2013 1:41 AM, "Nikos Mavrogiannopoulos" <nmav at gnutls.org> wrote:
>
> 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.

I think that this "leak" is okay.  First, unloading a library before exit
is rare.  Second, there isn't actually a leak on sensible platforms (Linux)
where an unlocked mutex is literally just the memory occupied by the struct
pthread_mutex_t.

As far as I know, Windows is the only platform that distinguishes library
unload from process shutdown in destructors, and destroying mutexes at
process shutdown risks annoying crashes if a multithreaded program calls
exit.

--Andy

>
> 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.
>
> regards,
> Nikos
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: </pipermail/attachments/20131201/1c8f386f/attachment.html>


More information about the Gnutls-devel mailing list