Re: Multithreading problem: losing message ptr after a PostThreadMessage() to a UI thread
From: Joseph M. Newcomer (newcomer_at_flounder.com)
Date: 04/05/04
- Next message: Joseph M. Newcomer: "Re: Order of the jobs in a printer queue"
- Previous message: Tom Junior: "Re: Passing structure to Thread"
- In reply to: Hetal: "Multithreading problem: losing message ptr after a PostThreadMessage() to a UI thread"
- Next in thread: Hetal: "Re: Multithreading problem: losing message ptr after a PostThreadMessage() to a UI thread"
- Reply: Hetal: "Re: Multithreading problem: losing message ptr after a PostThreadMessage() to a UI thread"
- Messages sorted by: [ date ] [ thread ]
Date: Mon, 05 Apr 2004 15:41:00 -0400
Not surprising. You should not be using PostThreadMessage to a thread that is not known to
have a message pump. Until you know the thread has actually gotten as far as its initial
PeekMessage/GetMessage sequence, you cannot reliably post a message to it.
What I do is have the OnIdle handler test a boolean (initialized to FALSE), and if it is
not set, it does a PostMessage to the main UI thread to indicate that it has started (by
the time OnIdle is called, the message queue exists). I then set the boolean to TRUE to
indicate I've sent the notification. The main GUI thread, when it receives the message,
knows the UI thread is now ready to accept communication and can do a PostThreadMessage to
it and know it will be received.
Otherwise, the thread has no message queue and PostThreadMessgae merely discards the
message.
On 5 Apr 2004 11:32:17 -0700, Patel_Hetal@msn.com (Hetal) wrote:
>Hey All,
>
>Ive created a UI thread by deriving a class from CWinThread. After I
>get a reference to the Thread Object from AfxBeginThread, I do a
>PostThreadMessage using a user defined message map.
>
>In the thread class, I am getting my handler function to run, meaning
>the message was received. However Im also passing a character array
>thru wparam. In message handler function wparam is null, and thus am
>not able to get my data! Any idea why this is happening. The memory
>was initially allocated on the heap.
>
>Below is some sample code from my project:
>
>// Class declaration
>const UINT WM_SN_LLC_MSG2 = WM_APP + 10;
>class CTestMsgPump : public CWinThread
>{
> DECLARE_DYNCREATE(CTestMsgPump)
>protected:
> CTestMsgPump(); // protected constructor used by dynamic
>creation
>
>......
>public:
> afx_msg LRESULT OnRecvMessage(WPARAM wp, LPARAM lp);
>
>...
> DECLARE_MESSAGE_MAP()
>};
>
>// defnition Class
>IMPLEMENT_DYNCREATE(CTestMsgPump, CWinThread)
>CTestMsgPump::CTestMsgPump()
>{
>}
>
>CTestMsgPump::~CTestMsgPump()
>{
>}
>
>.....
>BEGIN_MESSAGE_MAP(CTestMsgPump, CWinThread)
> ON_MESSAGE(WM_SN_LLC_MSG2, OnRecvMessage)
>END_MESSAGE_MAP()
>...
>
>LRESULT CTestMsgPump::OnRecvMessage(WPARAM wp, LPARAM lp)
>{
> char* pchMsg;
> pchMsg = (char*)wp; //***** wp is NULL !!! **** PROBLEM
> return 0;
>}
>
>// Main / Calling thread
>
> CRuntimeClass* ptrMsgPump = RUNTIME_CLASS( CTestMsgPump );
> pThreadpump1 = AfxBeginThread(ptrMsgPump);
>
> DWORD dwThreadID = pThreadpump1->m_nThreadID;
> UINT wmMsg = WM_SN_LLC_MSG2;
>
> char * pchMessage = new char[100];
> wParam = (WPARAM)pchMessage;
*****
The thread is almost certainly not yet running, has no message queue, so the
PostThreadMessage is guaranteed to fail
****
>
> bRet = ::PostThreadMessage(dwThreadID, wParam, lParam, 0);
> // until message queue is initialized
****
This is meaningless. Why do you think Sleep(0) is going to do anything useful? It won't,
and it won't guarantee that the thread is running. Bottom line: if you have to add a
Sleep() call to make your threading system work, it doesn't, won't, and can't be made to
unless it gets a redesign.
****
> for(int nIndex = 0; (nIndex < 10 && !bRet); nIndex++)
> {
> Sleep(0);
> bRet = ::PostThreadMessage(dwThreadID, wmMsg, 0, 0);
> }
>
>Has anyone seen something like this below ? I have no idea whats
>happening here.
****
Key here is to stop thinking sequentially. You are thinking sequentially, and that is why
it fails. You are thinking because you have created the thread, a PostThreadMessage will
work. It doesn't, it won't, and unless you build a positive-acknowledgement protocol like
I described, it cannot be made to work reliably, or possibly even at all.
****
>thanks,
>Hetal.
Joseph M. Newcomer [MVP]
email: newcomer@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
- Next message: Joseph M. Newcomer: "Re: Order of the jobs in a printer queue"
- Previous message: Tom Junior: "Re: Passing structure to Thread"
- In reply to: Hetal: "Multithreading problem: losing message ptr after a PostThreadMessage() to a UI thread"
- Next in thread: Hetal: "Re: Multithreading problem: losing message ptr after a PostThreadMessage() to a UI thread"
- Reply: Hetal: "Re: Multithreading problem: losing message ptr after a PostThreadMessage() to a UI thread"
- Messages sorted by: [ date ] [ thread ]
Relevant Pages
|