|
List Info
Thread: MFC message handler re-entrancy problem...
|
|
| MFC message handler re-entrancy
problem... |

|
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... |
  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?
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... |

|
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 < CheneyC wsdot.wa.gov">CheneyC wsdot.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: MSVC PEACH.EASE.LSOFT.COM" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)">MSVC PEACH.EASE.LSOFT.COM] On Behalf Of Cleopatra Von
Ludwig Sent: Thursday, June 14, 2007 8:01 AM To:
MSVC PEACH.EASE.LSOFT.COM" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)">MSVC PEACH.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
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",
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
--------------------------------------------------------------------------
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]
|
|