Click here to Skip to main content
15,892,298 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
COM object worker thread
I just added a simple worker thread to an old C++ COM object, consumed from a C++ MFC application.
The problem is that when I close the main application which uses the COM library the worker thread won’t exit and the COM object will hang in the purgatory forever.
It’s very weird because neither the application ExitInstance()
Nor the COM object ExitInstance()functions will be called so I’m not able to close the worker thread handle and clean the mutex.

Mind you it’s not synchronization problem since even I remove the synchronization the problem persists.

Here is a little simplified code snippet:

//start the thread
BOOL CMyApp::StartParamThread() 
{
	unsigned idThread;
	ASSERT(m_hParamRefreshThread == NULL);
	
	try
	{
		bParamRefreshRunning = true;
		m_hParamRefreshThread = (HANDLE)_beginthreadex(NULL, 0, & CMyApp::RefreshDBParams, NULL, 0, &idThread);
	}
	catch(...)
	{
		return false;
	}
	ASSERT( m_hParamRefreshThread );	
	return true;
}

//thread function
unsigned __stdcall CMyApp::RefreshDBParams(LPVOID pParam)
{
	((CMyApp *) AfxGetApp())->hParamsMutex = CreateMutex (NULL, FALSE, NULL); class
	TRY
	{
		while(bParamRefreshRunning)
		{
			Sleep(5*60*1000); // 5 minutes
			WaitForSingleObject(((CMyApp *) AfxGetApp())->hParamsMutex, INFINITE);
			
			{do some important stuff}
			ReleaseMutex(THISAPP->hParamsMutex);
		}
	}
	CATCH (CException, e)
	{
		THISAPP->LogError(e);
		ReleaseMutex(((CMyApp *) AfxGetApp())->hParamsMutex);
		return 0;
	}
	END_CATCH
	return 0;
}


Any suggestions will be appreciated, thank you in advance.
Posted
Updated 11-Nov-11 9:41am
v2

check if you call Release() properly so when you close your app, there no references to COM object
 
Share this answer
 
I am not sure what you mean by:

"Mind you it's not synchronization problem since even I remove the synchronization the problem persists."

To answer your question your thread function does 2 things:

1. Sleep for 5 minutes.
2. Wait for mutex to be signaled.

While it is doing either of those it is unresponsive and nothing else will happen.

1. Take out the sleep
2. Make bParamRefreshRunning = false then signal the mutex when you want to shut down the thread. You may have to add a little more code to get around {do some important stuff}.
3. call _endthread() then wait on the thread handle to ensure thread has exited.
4. CloseHandle(threadhandle)
5. CloseHandle(mutex)

OR:

The best way to use WaitForSingleObject is to check the return value.
This way the timeout can be changed from INFINITE to some small value - some seconds to allow the thread function to fall through regularly.

//thread function
unsigned __stdcall CMyApp::RefreshDBParams(LPVOID pParam)
{
	((CMyApp *) AfxGetApp())->hParamsMutex = CreateMutex (NULL, FALSE, NULL);
	TRY
	{
		while(bParamRefreshRunning)
		{

			DWORD retval = WaitForSingleObject(((CMyApp *) AfxGetApp())->hParamsMutex, 1000);

			if(WAIT_OBJECT_0 == retval)
			{

				if(bParamRefreshRunning)
				{	do some important stuff}


				ReleaseMutex(THISAPP->hParamsMutex);

			}

		}
	}
	CATCH (CException, e)
	{
		THISAPP->LogError(e);
		ReleaseMutex(((CMyApp *) AfxGetApp())->hParamsMutex);
		return 0;
	}
	END_CATCH
	return 0;
}
 
Share this answer
 
v5

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900