Skip to main content
gamedev.net
🔒 Locked

MsgWaitForMultipleObjects return value?

Started by johndirect Jan 27, 2008 at 12:14 PM 3 replies 3k views
Original Post
johndirect
johndirect
I have a question about the MsgWaitForMultipleObjects function. If I am waiting using a MsgWaitForMultipleObjects, 1) if I use the PostThreadMessage in the child thread to post a message to the main thread, MsgWaitForMultipleObjects returns with a value of WAIT_OBJECT_0 + nCount (where nCount is the total number of threads) 2) if I use the PostQuitMessage in the child thread, MsgWaitForMultipleObjects returns with a value of WAIT_OBJECT_0 + threadhandle index. why do these 2 post messages cause the difference in return value of MsgWaitForMultipleObjects? I am looking for a way to retrieve the threadhandle index in the first case.
SiCrane
SiCrane
Well how are you calling the function?
johndirect
johndirect
Below is my main function code

INT WINAPI wWinMain( HINSTANCE hInst, HINSTANCE, LPWSTR, INT ){	DWORD *pdwThreadIds, dwThrdParam = 1;         HANDLE *phThreads; 	UINT uiNumThreads=3;	pdwThreadIds = new DWORD [uiNumThreads];	phThreads	= new HANDLE [uiNumThreads];	for (UINT uiCnt=0; uiCnt < uiNumThreads; uiCnt++)	{		phThreads[uiCnt] = CreateThread( 				NULL,                        // default security attributes 				0,                           // use default stack size 				(LPTHREAD_START_ROUTINE)ThreadFunc,// thread function 				&dwThrdParam,                // argument to thread function 				0,                           // use default creation flags 				&pdwThreadIds[uiCnt]);                // returns the thread identifier 		if (phThreads[uiCnt] == NULL) 		{			printf( "CreateThread failed (%d)\n", GetLastError() ); 			exit(0);		}	}   // The message loop lasts until we get a WM_QUIT message,    // upon which we shall return from the function.	UINT uiNum=uiNumThreads;	    while (uiNum)    {        // block-local variable         DWORD result ; 		MSG msg ;         // Read all of the messages in this next loop,         // removing each message as we read it.		        while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))         {             // If it is a quit message, exit.            if (msg.message == WM_QUIT)                  return 1; 			            // Otherwise, dispatch the message.            DispatchMessage(&msg);         } // End of PeekMessage while loop.		        // Wait for any message sent or posted to this queue         // or for one of the passed handles be set to signaled.        result = MsgWaitForMultipleObjects(uiNum, phThreads,                  False, INFINITE, QS_ALLPOSTMESSAGE);         // The result tells us the type of event we have.        if (result == (WAIT_OBJECT_0 + uiNumThreads))        {            // New messages have arrived.             // Continue to the top of the always while loop to             // dispatch them and resume waiting.            continue;        } 		else// One of the handles became signaled. 		{			if (msg.message == WM_DESTROY)  			{				UINT temp = result - WAIT_OBJECT_0;				CloseHandle( phThreads[temp] );				for (UINT cnt=temp; cnt < uiNum; cnt++) phThreads[cnt] = phThreads[cnt+1];				uiNum-=1;			}					}            } // End of the always while loop. 	return 0;}
johndirect
johndirect
Thanks for your response and sorry for not providing suffiecient information.
Some additional code below:

I am experimenting with various thread functions since i am new to threading. Below is a portion of my code.
Basically, I am spawning threads; Within the threads, I am creating a window to draw some primitives. When I close the window (or do some other task in the future), the message handling procedure needs to send a message to the parent thread;


This is my link to my last post
http://www.codeguru.com/forum/showthread.php?p=1677494#post1677494

Below is my code

//-----------------------------------------------------------------------------// Name: MsgProc()// Desc: The window's message handler in the thread//-----------------------------------------------------------------------------LRESULT MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ){	switch( msg )    {        case WM_DESTROY:                                //m_dwPThrId is the ThreadId of the parent thread		PostThreadMessage(m_dwPThrId, msg,wParam,lParam);            //PostQuitMessage( 0 );            return 0;    }    return DefWindowProc( hWnd, msg, wParam, lParam );}INT WINAPI wWinMain( HINSTANCE hInst, HINSTANCE, LPWSTR, INT ){	DWORD *pdwThreadIds, dwThrdParam = 1;         HANDLE *phThreads; 	UINT uiNumThreads=3;	pdwThreadIds = new DWORD [uiNumThreads];	phThreads	= new HANDLE [uiNumThreads];	for (UINT uiCnt=0; uiCnt < uiNumThreads; uiCnt++)	{		phThreads[uiCnt] = CreateThread( 				NULL,                        // default security attributes 				0,                           // use default stack size 				(LPTHREAD_START_ROUTINE)ThreadFunc,// thread function 				&dwThrdParam,                // argument to thread function 				0,                           // use default creation flags 				&pdwThreadIds[uiCnt]);                // returns the thread identifier 		if (phThreads[uiCnt] == NULL) 		{			printf( "CreateThread failed (%d)\n", GetLastError() ); 			exit(0);		}	}   // The message loop lasts until we get a WM_QUIT message,    // upon which we shall return from the function.	UINT uiNum=uiNumThreads;	    while (uiNum)    {        // block-local variable         DWORD result ; 		MSG msg ;         // Read all of the messages in this next loop,         // removing each message as we read it.		        while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))         {             // If it is a quit message, exit.            if (msg.message == WM_QUIT)                  return 1; 			            // Otherwise, dispatch the message.            DispatchMessage(&msg);         } // End of PeekMessage while loop.		        // Wait for any message sent or posted to this queue         // or for one of the passed handles be set to signaled.        result = MsgWaitForMultipleObjects(uiNum, phThreads,                  False, INFINITE, QS_ALLPOSTMESSAGE);         // The result tells us the type of event we have.        if (result == (WAIT_OBJECT_0 + uiNumThreads))        {            // New messages have arrived.             // Continue to the top of the always while loop to             // dispatch them and resume waiting.            continue;        } 		else// One of the handles became signaled. 		{			if (msg.message == WM_DESTROY)  			{				UINT temp = result - WAIT_OBJECT_0;				CloseHandle( phThreads[temp] );				for (UINT cnt=temp; cnt < uiNum; cnt++) phThreads[cnt] = phThreads[cnt+1];				uiNum-=1;			}					}            } // End of the always while loop. 	return 0;}
Vorpy
Vorpy
The MSDN page describes the return values.

In your case, posting a thread message to the main thread returns WAIT_OBJECT_0 + nCount because this return value indicates that one of the messages you were waiting on has arrived. The source of the message is not relevant, all that matters is that there is a new message posted to the thread.

Posting a quit message in one of the child threads causes the child thread to die (or at least, it should). A thread enters the signalling state when it dies, and the main thread was waiting on the thread, so it is signalled. The return value indicates which of the objects generated the signal (in this case, the nth thread you were waiting on).

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.