N
NPCraig
Guest
I recently read the quality response to this posting "Thread Issue in C++ COM Server after C# call COM Interface" by Lim Bio Liong and that gave me hope that someone could explain a failure we are seeing. We have a legacy MFC dll with a COM method that starts a data pump. The method is called Start and the first line of code in the function is DWORD iWait = WaitForSingleObject( eventStartingPump, 10000 ); The class containing the Start method is constructed when the dll is loaded. The event object, eventStartingPump, is created as signaled in the constructor of the class. The Start method is called from a COM interface class. The interface method is called by a C# worker thread that waits here Monitor.Wait (m_locker); and is released by the C# main thread in OnRender by calling Monitor.Pulse (this.m_locker); On the C++ side the event handle is declared as static and initialize as HANDLE Foo::eventStartingPump = NULL; In the class constructor the event is created like so:
eventStartingPump = ::CreateEvent(NULL, // no security attributes
FALSE, // manual-reset
TRUE, // initially signaled
NULL);// anonymous
The WaitForSingleObject was chosen both to prevent more than one thread running in the function and to enforce a long delay of a second thread before returning. The problem is that this works about 95% of the time as expected but about 5% of the time the WaitForSingleObject times out. We have instrumented the code to ensure the execution is as expected both in the constructor and within the start function. If the WaitForSingleObject doesn't time out on the first execution after the program starts it will always execute as expected. The failure is that the first thread to enter the function times out about 5% of the time. However, once it fails it will always fail unless we change the code to call SetEvent(eventStartingPump); after the time out. In other words the event object is acting as though it was not created as signaled. This interface worked 100% of the time when it was MFC GUI to MFC server.
Continue reading...
eventStartingPump = ::CreateEvent(NULL, // no security attributes
FALSE, // manual-reset
TRUE, // initially signaled
NULL);// anonymous
The WaitForSingleObject was chosen both to prevent more than one thread running in the function and to enforce a long delay of a second thread before returning. The problem is that this works about 95% of the time as expected but about 5% of the time the WaitForSingleObject times out. We have instrumented the code to ensure the execution is as expected both in the constructor and within the start function. If the WaitForSingleObject doesn't time out on the first execution after the program starts it will always execute as expected. The failure is that the first thread to enter the function times out about 5% of the time. However, once it fails it will always fail unless we change the code to call SetEvent(eventStartingPump); after the time out. In other words the event object is acting as though it was not created as signaled. This interface worked 100% of the time when it was MFC GUI to MFC server.
Continue reading...