Holy cow, I wrote a book!
The thread that gets the DLL_PROCESS_DETACH
notification is not necessarily the one that got the
This is obvious if you think about it,
because the thread that got the
DLL_PROCESS_ATTACH notification might not
even exist any longer when the DLL is unloaded.
How can something that doesn't exist send a notification?
Even so, many people fail to realize this.
You can't do anything with thread affinity in your
since you have no guarantee about which thread will
be called upon to handle these process notifications.
Of course, you're not supposed to be doing anything particularly
interesting in your DLL_PROCESS_ATTACH handler anyway,
but things with thread affinity are doubly bad.
The classic example of this,
which I'm told the Developer Support
team run into with alarming frequency,
is a DLL that creates a window in its
and destroys it in its
Now, creating a window in DllMain
is already a horrifically bad idea
since arbitrary code can run during the creation of a window
(for example, there may be a global hook),
but the lack of a thread guarantee makes it downright insane.
The DLL calls DestroyWindow in its
but since that notification comes in on a thread
different from the one that received the
the attempt to destroy the window fails
since you must call DestroyWindow from the same
thread that created it.
Result: The DLL's attempt to destroy its window fails,
a message comes in, and the process crashes since the
window procedure no longer exists.