Monday, November 07, 2005

multithreading issue

ok, here is my task:
i have a dialog (main thread) and i have a worker thread running which updates a progressbar on the GUI.
when i press the close button i want the main thread and the worker thread to end cleanly (i want tthe threads to be closed nicely, without any TerminateThread or anything)

now, the problem stay in the fact that when i signal (using an event or something) the worker thread to end and then wait for it to end (using WaitForSingleObject for example) it is possible that in this time the worker thread to send a message to the GUI to update the progressbar(using SendMessage). Now, some may say why that SendMessage is a mistake but maybe not.

I want to be sure that the GUI and worker are synchronized perfectly (i dont want to use PostMessage; in some situations, for example when a buffer is needed to be sent, PostMessage only will not work (the buffer needs to be available when the message arrive to the receiver queue), hence, for PostMessage, some queue mechanism might be needed, if a text buffer for example is sent.

I came across a simple solution:
AtlWaitWithMessageLoop
its a function which use MsgWaitForMultipleObjects and does the job (in fact you can use your own implementation instead)

the idea is that, the main thread needs to be still getting messages for processing but in the same time, it will wait till the given synchronization object becomes invalid (beacause we may have 2 statements which can wait to eachother, a deadlock may appear; we can have the WaitForSingleObject(hWorkerThread); from main thread and the SendMessage from the workerthread)


//
//Stop the 'LoadLogs' thread, if its runnning
//
void CLogPage::StopLoadLogsThread()
{

if(m_hThreadLoadLogs)
{
//thread is accessing the log-file using CFile and it must be stopped before deleting the log-file
//stop the thread and wait till thread is stopped
InterlockedExchange(&m_snRunThread, 0);
AtlWaitWithMessageLoop(m_hThreadLoadLogs);
}

}

No comments: