Reputation: 373
Read the problem carefully first.
There is a worker thread which gets spawned from a CreateInstance of CTest class. Here is the prototype of the class. hThread is the handle to thread and hEventShutdown is the event used to shutdown thread when program exits. WaitForShutdown is the public function which is used to signal hEventShutdown and wait on handle to thread till thread exits gracefully. WaitForShutdown is invoked from Exit of Application.
//pseudocode
CTest
{
public:
CTest* CreateInstance();
static threadproc(void *pv);
void WaitForShutdown();
public:
HANDLE hThread;
HANDLE hEventShutdown;
}
void CTest::CTest* CreateInstance()
{
// spawn a thread, pass 'this' pointer to thread , use beginthreadex
hThread = beginthreadex ( threadproc, this );
}
unsigned int CTest::threadproc( void *pv)
{
Ctest *ptest = (Ctest*)pv;
do
{
HANDLES hArray[2] = { pv->hEventShutdown, someotherhandle }
dwResult = Waitformultipleobjects( hArrary , 2);
if ( dwResult == WAIT_OBJECT_0)
delete pTest; // since it is allocated dynamically ( This is required due to some known reasons in my code)
if(dwResult == WAIT_OBJECT_0 + 1)
Doprocessing(); //DoProcessing when other thread signal someotherhandle
}while (1)
void CTest::WaitForShutdown()
{
SetEvent ( hEventShutdown);
WaitForSingleObject ( hThread,INFINITE);
}
void CTest::~CTest()
{
Closehandle(hThread)
Closehandle(hEventShutdown);
}
Now if you look at the code carefully, you will find that event is signaled from WaitForShutdown function, thread comes out of WaitForMultipleOjbects and deletes pointer of CTest. It means destructor of CTest is invoked which will obviously close thread handle ( hThread). But WaitForSingleObject from WaitForShutdown is actually waiting on thread handle. So here behavior will be undefined ( I think so, you can correct me if I am wrong). Another problem is destructor of Ctest is invoked when WaitForSingleObject is waiting on its member hThread which is not correct. I can not remove delete pTest from thread since it has to be there due to some reasons.
How will you suggest the solution to the above ?
Couple of Solution which I can think of :
Correct me.
Your feedback appreciated.
Upvotes: 1
Views: 4771
Reputation: 960
I have run this piece as is. Seems it works, and it doesn't crash.
Strangely that we can call CloseHandle(hthread)
, before we go out of WaitforSingleObject(hThread,INFINITE)
.
Of course, "academic" way to join thread is firstly WaitForSingleObject(hThread,INFINITE)
than CloseHandle(hThread)
. So that is my suggestion - do in this way.
I don't have to add anymore.
Upvotes: 1
Reputation: 231383
The simplest way to handle this would be to simply delete the thread from WaitForShutdown, after WaitForSingleObject
returns. This ensures all the handles you need - and more importantly, the object itself - remain alive to the end.
Upvotes: 2