MFC DLL - ExitInstance hang on WaitForSingleObject
Hi,
Here is a simple pooling class implemented into a MFC DLL project.
------------------------------------------------------------------------
BOOL CPooler::StartPooling()
{
// Create startup event
m_hStartupEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
// Create main thread
m_hMainThread = CreateThread( NULL, 0, MainThreadProc,
static_cast<LPVOID>( this ), 0, &g_dwThreadID);
// Check for startup event
switch( WaitForSingleObject( m_hStartupEvent, 1000) )
{
case WAIT_TIMEOUT :
bRet = FALSE; // Thread time-out
break;
case WAIT_OBJECT_0 :
bRet = TRUE; // Thread sucessfully started
break;
}
// Close startup handle
CloseHandle(m_hStartupEvent);
m_hStartupEvent = NULL;
return bRet;
}
BOOL CPooler::StopPooling()
{
// Singal to main thread to stop
SetEvent(m_hEventKill);
// Check thread state
if (WaitForSingleObject( m_hMainThread, 10000) == WAIT_TIMEOUT)
{
// If thread is still running then stop it brutally
if (m_hMainThread != NULL)
{
TerminateThread( m_hMainThread, 0 );
}
}
// Thread is null
CloseHandle( m_hMainThread );
m_hMainThread = NULL;
return TRUE;
}
DWORD WINAPI CPooler::MainThreadProc(LPVOID lpParameter)
{
// Get pointer on CModBusTcpPooler class object
CPooler *pThis = reinterpret_cast< CPooler *>( lpParameter ) ;
// Cretae kill event (for main thread)
pThis->m_hEventKill = CreateEvent(NULL, FALSE, FALSE, NULL);
// Signal startup event
SetEvent( pThis->m_hStartupEvent );
// Loop until kill event has not been signaled
UINT32 un32Index = 0;
while(WaitForSingleObject( pThis->m_hEventKill, 5) != WAIT_OBJECT_0)
{
// Do pooler job
// Give time to CPU
Sleep(5);
}
// No need this handle anymore
CloseHandle(pThis->m_hEventKill);
pThis->m_hEventKill = NULL;
return FALSE;
}
CPooler::~CPooler(void)
{
// Stop main thread
StopPooling();
}
------------------------------------------------------------------------
Now, always in this DLL, I have implemented a wrapper containing an
array of 100 available CPooler that can be created, started, stopped
and removed. Here is the more important part.
------------------------------------------------------------------------
CPooler* g_Pooler[100];
extern "C" POOLER_LIB_API INT32 __cdecl PoolerCreate(...)
{
// Look for empty place in the array and create the Pooler
int i = 0;
while( i < MAX_POOLER && g_Pooler[i] != NULL ) ++i;
// If empty space was found
CPooler* pTcpPooler = NULL;
if (i < MAX_POOLER)
{
// Create new pooler
pPooler = new CPooler(...);
// Start it !
if ( pPooler->StartPooling() )
{
g_Pooler[in32Result = i] = pPooler;
}
else
{
// Cannot start so delete instance and return error
delete pPooler;
in32Result = -2;
}
}
else
{
// No more space to create a pooler
in32Result = -1;
}
return in32Result;
}
------------------------------------------------------------------------
Now simply to test the class, inside the InitInstance function, I created
a new Pooler and then I delete it just after. Like this
------------------------------------------------------------------------
BOOL CPoolerLibraryApp::InitInstance()
{
CWinApp::InitInstance();
CPooler* p = new CPooler();
p->StartPooling()
delete p; // PROBLEM HERE !
return TRUE;
}
------------------------------------------------------------------------
But I got some very strange behavior while the delete operation and after !
Like the heap was corrupted or I don't know. Anyway the application is
freezing
on this line :
if (WaitForSingleObject( m_hMainThread, 10000) == WAIT_TIMEOUT) inside the
function CPooler::StopPooling().
I put a brake point on the "return FALSE;" line of the function
CPooler::MainThreadProc. While the destructor is called the thread is well
stopped
but the WaitForSingleObject still wait for thread ending. WHY ?
I already try to create a Pooler inside the InitInstance and destroying it
inside
the ExitInstance and I get the same result.
PS : To call the function of this DLL I made a simple MFC dialog project,
use LoadLibray, GetProcAddress, etc...
Any help should be VERY appreciated because I worked on this problem
while 16 hours :(
Best regards,
Martin