List Info

Thread: MFC message handler re-entrancy problem...




MFC message handler re-entrancy problem...
user name
2007-06-14 10:01:15
Hi folks,

We just stumbled across something that is apparently known behavior, so I guess I'm soliciting advice on the best way to fix it for an already existing, customer-released application...

Here's a simplified version of our architecture:

We have an MFC-based GUI application that has a second non-UI data thread that processes requests to the server and receives notifications from the server. When this secondary thread has finished a "job" (either a request or a notification), it calls PostMessage to alert the UI thread of the job, and the UI picks up the job in its ON_MESSAGE message handler (don't get caught up in the details too much -- the message posted contains only a job number, and the UI retrieves it from a job manager who is yet another thread, so nobody has to wait for anything).

Here9;s the problem that we discovered, and I can't believe it took us over 6 months to see... I discovered a crash yesterday that involved our UI data getting updated out from underneath itself -- almost like the UI has two threads, which it does not (the debugger proved this). The culprit was a job completion function that, when handled by the UI, pops up a message box to the user (using MessageBox) and waits for a response. Apparently, the UI doesn't actually wait for a response, and when another job was completed (this time a notification), the UI thread happily processes it, thus changing the data that the message-box-posting function is about to use.

We're a bit surprised by this behavior -- we would've thought that popping up a modal message box would suspend any message pumping, other than WM_PAINT messages. The fact that it doesn't is pretty horrible for us -- it basically means that we need to find a way to synchronize a single thread with itself. I've seen others post things like, "Use a boolean", which is cheesy but may work... but even if you "use a boolean", what do you do when you've picked up a message from the message handler, and you can't process it yet because a message box is open?? I don't want to stick it back on the MFC message queue, because then it will be out of order. It implies that I will have to create my own queue within the UI thread on which I'll stick the job numbers that need to be processed, and at the end of processing a job, I'll have to check the queue to see if other stuff came in while I was busy.

This hurts. :-(

Sorry for the long post. I appreciate any words of wisdom you can provide!

Thanks,
-cleopatra

-------------------------------------------------------------------------- The MSVC list is hosted on a Windows NT(TM) machine running L-Soft international's LISTSERV(R) software. For subscription/signoff info and archives, see http://peach.ease.lsoft.com/archives/msvc.html .
COPYRIGHT INFO:
http://peach.ease.lsoft.com/scripts/wa.exe?SHOWTPL=COPYRIGHT&L=MSVC
Re: MFC message handler re-entrancy problem...
country flaguser name
United States
2007-06-14 11:26:33
Why don't you give the message-box-posting function a copy of the data so that it is not changed mid-function?

From: Microsoft Visual C++ programmers list [mailto:MSVCPEACH.EASE.LSOFT.COM] On Behalf Of Cleopatra Von Ludwig
Sent: Thursday, June 14, 2007 8:01 AM
To: MSVCPEACH.EASE.LSOFT.COM
Subject: MFC message handler re-entrancy problem...

Hi folks,

We just stumbled across something that is apparently known behavior, so I guess I'm soliciting advice on the best way to fix it for an already existing, customer-released application...

Here's a simplified version of our architecture:

We have an MFC-based GUI application that has a second non-UI data thread that processes requests to the server and receives notifications from the server. When this secondary thread has finished a "job" (either a request or a notification), it calls PostMessage to alert the UI thread of the job, and the UI picks up the job in its ON_MESSAGE message handler (don't get caught up in the details too much -- the message posted contains only a job number, and the UI retrieves it from a job manager who is yet another thread, so nobody has to wait for anything).

Here's the problem that we discovered, and I can't believe it took us over 6 months to see... I discovered a crash yesterday that involved our UI data getting updated out from underneath itself -- almost like the UI has two threads, which it does not (the debugger proved this). The culprit was a job completion function that, when handled by the UI, pops up a message box to the user (using MessageBox) and waits for a response. Apparently, the UI doesn't actually wait for a response, and when another job was completed (this time a notification), the UI thread happily processes it, thus changing the data that the message-box-posting function is about to use.

We're a bit surprised by this behavior -- we would've thought that popping up a modal message box would suspend any message pumping, other than WM_PAINT messages. The fact that it doesn't is pretty horrible for us -- it basically means that we need to find a way to synchronize a single thread with itself. I've seen others post things like, "Use a boolean", which is cheesy but may work... but even if you "use a boolean", what do you do when you've picked up a message from the message handler, and you can't process it yet because a message box is open?? I don't want to stick it back on the MFC message queue, because then it will be out of order. It implies that I will have to create my own queue within the UI thread on which I'll stick the job numbers that need to be processed, and at the end of processing a job, I'll have to check the queue to see if other stuff came in while I was busy.

This hurts. :-(

Sorry for the long post. I appreciate any words of wisdom you can provide!

Thanks,
-cleopatra

-------------------------------------------------------------------------- The MSVC list is hosted on a Windows NT(TM) machine running L-Soft international's LISTSERV(R) software. For subscription/signoff info and archives, see http://peach.ease.lsoft.com/archives/msvc.html .
COPYRIGHT INFO:
http://peach.ease.lsoft.com/scripts/wa.exe?SHOWTPL=COPYRIGHT&L=MSVC
Re: MFC message handler re-entrancy problem...
user name
2007-06-14 12:09:07
Hi Christian,

Thanks for the response. Unfortunately, the data that is getting manipulated out from underneath of the message-box-posting function is the UI data -- information about how many rows are in the grid or how many nodes are in the tree, for example. This data is stored at a very low-level (in our base UI classes) and changing the implementation of those classes would impact a lot of applications (not to mention the fact that we'd only be narrowing the window of data integrity issues, not eliminating them).

I guess I'm going to try the old boolean approach, with an int-based queue in the main window that stores any messages that come in while the message box is open... I'm just afraid it's going to have unforeseen impact, you know?

Thanks again,
-cleopatra

On 6/14/07, Cheney, Christian < CheneyCwsdot.wa.gov">CheneyCwsdot.wa.gov> wrote:
Why don't you give the message-box-posting function a copy of the data so that it is not changed mid-function?


From: Microsoft Visual C++ programmers list [mailto: MSVCPEACH.EASE.LSOFT.COM" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)">MSVCPEACH.EASE.LSOFT.COM] On Behalf Of Cleopatra Von Ludwig
Sent: Thursday, June 14, 2007 8:01 AM
To: MSVCPEACH.EASE.LSOFT.COM" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)">MSVCPEACH.EASE.LSOFT.COM
Subject: MFC message handler re-entrancy problem...

Hi folks,

We just stumbled across something that is apparently known behavior, so I guess I'm soliciting advice on the best way to fix it for an already existing, customer-released application...

Here&#39;s a simplified version of our architecture:

We have an MFC-based GUI application that has a second non-UI data thread that processes requests to the server and receives notifications from the server. When this secondary thread has finished a "job&quot; (either a request or a notification), it calls PostMessage to alert the UI thread of the job, and the UI picks up the job in its ON_MESSAGE message handler (don't get caught up in the details too much -- the message posted contains only a job number, and the UI retrieves it from a job manager who is yet another thread, so nobody has to wait for anything).

Here';s the problem that we discovered, and I can't believe it took us over 6 months to see... I discovered a crash yesterday that involved our UI data getting updated out from underneath itself -- almost like the UI has two threads, which it does not (the debugger proved this). The culprit was a job completion function that, when handled by the UI, pops up a message box to the user (using MessageBox) and waits for a response. Apparently, the UI doesn't actually wait for a response, and when another job was completed (this time a notification), the UI thread happily processes it, thus changing the data that the message-box-posting function is about to use.

We're a bit surprised by this behavior -- we would9;ve thought that popping up a modal message box would suspend any message pumping, other than WM_PAINT messages. The fact that it doesn't is pretty horrible for us -- it basically means that we need to find a way to synchronize a single thread with itself. I've seen others post things like, "Use a boolean&quot;, which is cheesy but may work... but even if you "use a boolean&quot;, what do you do when you've picked up a message from the message handler, and you can't process it yet because a message box is open?? I don't want to stick it back on the MFC message queue, because then it will be out of order. It implies that I will have to create my own queue within the UI thread on which I'll stick the job numbers that need to be processed, and at the end of processing a job, I'll have to check the queue to see if other stuff came in while I was busy.

This hurts. :-(

Sorry for the long post. I appreciate any words of wisdom you can provide!

Thanks,
-cleopatra

-------------------------------------------------------------------------- The MSVC list is hosted on a Windows NT(TM) machine running L-Soft international's LISTSERV(R) software. For subscription/signoff info and archives, see http://peach.ease.lsoft.com/archives/msvc.html .
COPYRIGHT INFO:
http://peach.ease.lsoft.com/scripts/wa.exe?SHOWTPL=COPYRIGHT&L=MSVC
-------------------------------------------------------------------------- The MSVC list is hosted on a Windows NT(TM) machine running L-Soft international's LISTSERV(R) software. For subscription/signoff info and archives, see http://peach.ease.lsoft.com/archives/msvc.html .
COPYRIGHT INFO:
http://peach.ease.lsoft.com/scripts/wa.exe?SHOWTPL=COPYRIGHT&L=MSVC

-------------------------------------------------------------------------- The MSVC list is hosted on a Windows NT(TM) machine running L-Soft international's LISTSERV(R) software. For subscription/signoff info and archives, see http://peach.ease.lsoft.com/archives/msvc.html .
COPYRIGHT INFO:
http://peach.ease.lsoft.com/scripts/wa.exe?SHOWTPL=COPYRIGHT&L=MSVC
[1-3]

about | contact  Other archives ( Real Estate discussion Medical topics )