Thread in COM DLL
Hello,
I am implementing a Shell extension and it create a virtual folder to map to d:\\temp,
I create a thread use ReadDirectoryChange to watch d:\\temp have any write action,
the thread is in COM dll shell extension's EnumObject function(the create's place maybe not the root cause),
and want when user close the explorer, I'll tell the thread to exit(means no more need to watch any write action in virtual folder).
Right now the only place I can thourht is when call DllMain's process_detach,
I have following scenario,
1. when I use SetEvent(hStopEvent) to set a global event in DllMain's process_detach tell thread to stop, the thread's waitforsingleobject(hStopEvent, Infinite) to wait the global event didn't wait the event signal, it still block in waitforsingleobject(hStopEvent, Infinite),
But when I move the SetEvent(hStopEvent) to other place, not in Dllmain's process_detach, it works fine, the thread will wait htat event succes anf exit himself.
2. I can't solve the question one, Because the only place I know can stop thread is DllMain's process_detach, so I decide set a global boolean bStopThread, the thread will keep check that boolean to decide stop thread or not, and set bStopThread to TRUE in DLLMAIN's process_detach,
But after I set the bollean to TRUE, it seems thread didn't run to check bollean point, then the DLL is exit, so I don't know thread is end or not, I thought it didn't end, because I use debug mode to trace, thread didn't run to check bollean point, but the DLL already exit.
Question is,
1. In scenario two, the thread is end or not? it seems thread didn't end? but I can delete that dll afte dll exit, so it means the thread have already end?
2. how to slove Scenario one, to let thread can wait a global event and set event in DLLmains process_detach?
Thanks for your help~!!
[2004 byte] By [
Ryan_Mao] at [2007-11-20 0:51:24]

# 1 Re: Thread in COM DLL
First and foremost - DllMain is the wrong place to allocate resouces.
Have an Initialize and DeInitialize function if you really need one. 1. when I use SetEvent(hStopEvent) to set a global event in DllMain's process_detach tell thread to stop, the thread's waitforsingleobject(hStopEvent, Infinite) to wait the global event didn't wait the event signal, it still block in waitforsingleobject(hStopEvent, Infinite),
But when I move the SetEvent(hStopEvent) to other place, not in Dllmain's process_detach, it works fine, the thread will wait htat event succes anf exit himself.I think there is a mistake in the way you put things above - i.e. did the WFSO not wait, or did it block?
In any case, as mentioned - you are using the wrong place to manipulate the event object.
1. In scenario two, the thread is end or not? it seems thread didn't end? but I can delete that dll afte dll exit, so it means the thread have already end? In general to check if a thread has ended or not, read this (http://www.dev-archive.com/forum/showthread.php?t=397697).
But, like I already pointed out - your implementation needs a change.
2. how to slove Scenario one, to let thread can wait a global event and set event in DLLmains process_detach? Using separate functions exported from the DLL that should do the job of initializing and de-initializing.
Also, note that you call this a COM DLL, but seem to be using exported functions to do your job. Why not use a COM-based approach, i.e. instantiate a COM Class that creates threads, sets events and does your primary activity instead of relying on DllMain, exported functions, et al?
# 3 Re: Thread in COM DLL
The reason for your problems is that when code is executing in DllMain no thread switching is allowed. So if you set an event to let the worked thread die and then wait for it to die then you will have a dead lock.
This is just the way DllMain works and there are reasons for this behavior. Please read up on it on msdn (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/dllmain.asp).
What I would do if I had worker threads in a COM dll and used ATL then I would "override" the AtlModule Lock/Unlock functions. When the global dll lock goes from 0 to 1 I would initialize the worker thread. When it goes from 1 to 0 I would uninitialize it.
Or I would initialize the worker thread in the constructor of the COM object and destroy it in the destructor. All depending on the problem.
Neither of these functions are run in the context of DllMain and thus you won't experience dead-locking or related DllMain problems.
Hope this helps