The DllMain() help in the PSDK has the following tidbit:
While it is acceptable to create synchronization objects in DllMain, you should not perform synchronization in DllMain (or a function called by DllMain) because all calls to DllMain are serialized. Waiting on synchronization objects in DllMain can cause a deadlock.
Does ReactOS serialize calls to DllMain? I would think if it was, CreateRemoteThread() would block waiting for DLL_THREAD_ATTACH until DLL_PROCESS_DETACH had finished.
(And then of course, there are other issues to be dealt with because the DLL is unloaded.)
ExitProcess() PSDK has the following tidbit which might also help:
The ExitProcess, ExitThread, CreateThread, CreateRemoteThread functions, and a process that is starting (as the result of a call by CreateProcess) are serialized between each other within a process. Only one of these events can happen in an address space at a time. This means the following restrictions hold:
During process startup and DLL initialization routines, new threads can be created, but they do not begin execution until DLL initialization is done for the process. Only one thread in a process can be in a DLL initialization or detach routine at a time. If any process is in its DLL initialization or detach routine, ExitProcess does not return.
Hope this helps.
Thanks,
Joseph
Ge van Geldorp wrote:
While working on proper logoff/shutdown processing, I'm running into an interesting race condition inside kernel32. The shutdown command (apps/utils/shutdown) calls ExitWindowsEx() and then terminates, which causes kernel32's DllMain() function to be called with the DLL_PROCESS_DETACH reason. This will clean up kernel32 resources, like calling RtlDeleteCriticalSection(&ConsoleLock).
Now, before the process is completely shutdown, CSRSS will send it a CTRL_LOGOFF_EVENT. To deliver this event, CSRSS calls CreateRemoteThread(). So CreateRemoteThread() is called while the main thread is executing DLL_PROCESS_DETACH cleanup. During handling of CTRL_LOGOFF_EVENT, the new thread will try to enter the ConsoleLock critical section, which was already deleted by the main thread. Chaos results.
To solve this, first I was looking for a way to disable new thread creation when a process enters ExitProcess(), but that won't solve the problem. We can still have a thread A which calls ExitProcess(), have a context switch to existing thread B of the same process which does something that needs the ConsoleLock. Then I considered SuspendThread()ing all other threads of the process when ExitProcess() is called, but that could potentially lead to deadlocks if the suspended threads hold synchronization objects. So now I'm inclined to believe that the solution is to just not do the resource cleanup during DLL_PROCESS_DETACH handling. But that doesn't feel very clean either. Anyone have a better idea?
GvG
_______________________________________________ Ros-dev mailing list Ros-dev@reactos.org http://www.reactos.org/mailman/listinfo/ros-dev