Release in thread created by timer
-
Got a problem, exhausted all of my ideas: I have an MFC / ATL-com-server project. Upon final release, I want the COM object to wait for a timer to fire one last time and run it's thread to completion before unloading itself. Here are some attempts: 1) AddRef() in the com object and then once the timer thread has fired it's last time, Release() from that thread. This causes a crash in the main window of the app in CWnd::DestrowWindow function with this code:
if (pWnd != NULL) { // Should have been detached by OnNcDestroy
#ifdef _DEBUG
ASSERT(pMap->LookupPermanent(hWndOrig) == NULL);
#endif
}- In the CSSLogCOM::InternalRelease() function (which I've overridden), wait for a flag to be set when the timer thread fires and completes with
while(bWait) Sleep(1000);
. This doesn't work because the timer won't fire once we're in this function! ??? 3) I would try to post a WM_QUIT message to the main window, but the ATL server can host many copies of the same COM object in a single instance and if one of them posts the quit message, other running instances will be stopped early. Anyone have any idea how I can "delay" the final release of a COM object from closing the ATL server until my worker thread has completed? Thanks ~Steve
- In the CSSLogCOM::InternalRelease() function (which I've overridden), wait for a flag to be set when the timer thread fires and completes with
-
Got a problem, exhausted all of my ideas: I have an MFC / ATL-com-server project. Upon final release, I want the COM object to wait for a timer to fire one last time and run it's thread to completion before unloading itself. Here are some attempts: 1) AddRef() in the com object and then once the timer thread has fired it's last time, Release() from that thread. This causes a crash in the main window of the app in CWnd::DestrowWindow function with this code:
if (pWnd != NULL) { // Should have been detached by OnNcDestroy
#ifdef _DEBUG
ASSERT(pMap->LookupPermanent(hWndOrig) == NULL);
#endif
}- In the CSSLogCOM::InternalRelease() function (which I've overridden), wait for a flag to be set when the timer thread fires and completes with
while(bWait) Sleep(1000);
. This doesn't work because the timer won't fire once we're in this function! ??? 3) I would try to post a WM_QUIT message to the main window, but the ATL server can host many copies of the same COM object in a single instance and if one of them posts the quit message, other running instances will be stopped early. Anyone have any idea how I can "delay" the final release of a COM object from closing the ATL server until my worker thread has completed? Thanks ~Steve
How about using CreateEvent/SetEvent/WaitForSingleObject/SignalObjectAndWait? Create two events before the worker starts, one called "StopNow" and "DidStop". Let the worker thread do it's thing, periodically checking the "StopNow" event with WaitForSingleObject. When your server is about to terminate, make it use the function SignalObjectAndWait. This'll set the "StopNow" event, thus triggering the worker thread. It'll also make the server wait for the "DidStop" event. Meanwhile, the thread exits gracefully, but before finally quitting, it sets the event "DidStop", which will give the main thread clearance to continue termination.
// Server code
void OnTerminate() {
SignalObjectAndWait(hStopNow, hDidStop, INFINITE, FALSE);
...
}// Worker thread
void ThreadProc() {
while(...) {
...
if(WaitForSingleObject(hStopNow, 0)) {
SetEvent(hDidStop);
// clean up and exit
}
}
}-- Seraphim Shock. Gold for your ears.
- In the CSSLogCOM::InternalRelease() function (which I've overridden), wait for a flag to be set when the timer thread fires and completes with
-
How about using CreateEvent/SetEvent/WaitForSingleObject/SignalObjectAndWait? Create two events before the worker starts, one called "StopNow" and "DidStop". Let the worker thread do it's thing, periodically checking the "StopNow" event with WaitForSingleObject. When your server is about to terminate, make it use the function SignalObjectAndWait. This'll set the "StopNow" event, thus triggering the worker thread. It'll also make the server wait for the "DidStop" event. Meanwhile, the thread exits gracefully, but before finally quitting, it sets the event "DidStop", which will give the main thread clearance to continue termination.
// Server code
void OnTerminate() {
SignalObjectAndWait(hStopNow, hDidStop, INFINITE, FALSE);
...
}// Worker thread
void ThreadProc() {
while(...) {
...
if(WaitForSingleObject(hStopNow, 0)) {
SetEvent(hDidStop);
// clean up and exit
}
}
}-- Seraphim Shock. Gold for your ears.
Thanks for the tip, and the example code. Looks promising, I'll give it a go... ~Steve