[Gc] Win32 thread support

Ben Hutchings ben.hutchings at businesswebsoftware.com
Wed Mar 30 08:07:01 PST 2005


Boehm, Hans wrote:
> I'm looking at the win32 threading code in the gc7 tree again.
> 
> Basically this code is really ugly due to DllMain semantics.
> Unfortunately, the DllMain manual
> entry doesn't seem to have improved as
> much as I had hoped.  Are there any win32 experts who know
> if the _DETACH calls are guaranteed to be made
> in an ordinary thread context, and can thus lock?
> It looks like there is no sane reason for that not to be the
> case (unlike the _ATTACH calls).  But the documentation
> seems a bit contradictory on this particular point.

Actually all calls to DllMain are made in a standard context.  Here's 
what I wrote in my local code, which does use a lock during DllMain:

/*
  * DllMain is called by the dynamic linker after the DLL is loaded,
  * when it is about to be unloaded, and whenever a thread begins or
  * exits (cleanly) in a process the DLL is loaded into.
  *
  * The MSDN Library documentation says that this "should not attempt
  * to communicate with other threads or processes" but this is overly
  * conservative.  The dynamic linker synchronises access to its state
  * with a mutex called the "loader lock" and holds this while loading
  * modules and whenever it calls DllMain.  This means that any lock
  * acquired by DllMain other than during process attachment (when
  * there should be no other threads running) must be lower in the lock
  * hierarchy than the "loader lock", which in turn must be lower than
  * any locks that could be held by a thread when it loads a DLL.  We
  * attempt to satisfy this requirement by locking only GC_threads_ml
  * during thread attachment and placing GC_threads_ml at the bottom of
  * the lock hierarchy.
  *
  * Note also that during process attachment we should not call
  * functions in DLLs other than kernel32.dll since those DLLs may not
  * yet have been initialised.  We break this rule if we call ABORT()
  * since that calls MessageBox from user32.dll.  There is no obvious
  * solution to this.
  */

This is based on explanations in MS blogs, in particular 
<http://blogs.gotdotnet.com/cbrumme/permalink.aspx/dac5ba4a-f0c8-42bb-a5cf-097efb25d1a9>
(search for "The OS Loader Lock").

<snip>
> I can think of several options:
> 
> 1) Default: Continue along the current path.  If we can't lock
> in the _DETACH path in DllMain, this may be impractical.
> In any case, it looks more and more like a mess.
> 
> 2) Split this into two different win32 thread support layers, one 
> that relies on explicit interception of thread calls, and one
> the relies on the DllMain hack.  The former could work a
> lot more like the pthreads version.  This seems cleaner to
> me.  It does mean that you need to compile differently for
> different thread registration methods.
> 
> 3) Drop the DllMain support entirely.  I suspect this is
> dubious because people are relying on it.  But I'm not
> sure.
> 
> I'm leaning towards (2).  Opinions?

Our experience, which admittedly does not include testing on Win9x, is 
that locking in DllMain is safe if done with great care.  However if 
this turns out not to be generally safe then I would favour (2).

Ben.


More information about the Gc mailing list