When user trying to quit program while thread is running  
Author Message
raghava





PostPosted: Thu Jun 23 18:58:41 CDT 2005 Top

MFC >> When user trying to quit program while thread is running Hi guys, I have a memory leak problem. When I tried to quit program by click
'x' at top right corner while my ui thread and its child worker thread are
running, debugger display following messages:

The thread 0x570 has exited with code 0 (0x0).
The thread 0x574 has exited with code 0 (0x0).
Detected memory leaks!
Dumping objects ->
c:\work\MyProject\MyUIthread.cpp(396) : {717} normal block at 0x00C17CA8, 4
bytes long.
a CWinThread object at $00C17BF0, 112 bytes long
c:\work\MyProject\MyUIthread.cpp(96) : {550} normal block at 0x00C17FC0, 12
bytes long.
Data: < > CD CD CD CD CD CD CD CD CD CD CD CD
c:\work\MyProject\MyUIthread.cpp(94) : {549} normal block at 0x00C17398, 12
bytes long.
Data: < 0 > C2 30 00 00 F2 C9 00 02 D1 01 00 00
c:\work\MyProject\mainfrm.cpp(746) : {535} client block at 0x00C17E40,
subtype 0, 128 bytes long.
a CMyUIThread object at $00C17E40, 128 bytes long
Object dump complete.
The thread 0x304 has exited with code 0 (0x0).
The program c:\work\MyProject\Debug\MyProject.exe' has exited with code 0
(0x0).

In my program, ui thread is created when certain selection made from combo
box and shutdown, deleted when combo box selection. Ui thread creates one
worker thread for communication with embeded system via COM port. So in a
normal situation(combo box changed), shutdown prccedure is like this: First,
main frame PostThreadMessage(QUIT) to ui thread. Ui thread set 'running'
flag to FALSE to let worker thread exit its while(running) loop. Just before
exit, worker thread sends another QUIT packet to embeded system to power off
then PostMessage(THREAD_QUIT) to main frame. Message handler in main frame
wait for m_hThread and delete pThread. Debugger doesn't complain about this
normal shutdown and the program looks just fine when I try without debugger.
Can I neglect this situation?
Where can I insert this shutdown procedure when program is forced to quit
while threads running?
Any suggestion appreciated. Cheers

Visual Studio344  
 
 
Scott





PostPosted: Thu Jun 23 18:58:41 CDT 2005 Top

MFC >> When user trying to quit program while thread is running bbg wrote:

> Hi guys, I have a memory leak problem. When I tried to quit program by click
> 'x' at top right corner while my ui thread and its child worker thread are
> running, debugger display following messages:
>
> The thread 0x570 has exited with code 0 (0x0).
> The thread 0x574 has exited with code 0 (0x0).
> Detected memory leaks!
> Dumping objects ->
> c:\work\MyProject\MyUIthread.cpp(396) : {717} normal block at 0x00C17CA8, 4
> bytes long.
> a CWinThread object at $00C17BF0, 112 bytes long
> c:\work\MyProject\MyUIthread.cpp(96) : {550} normal block at 0x00C17FC0, 12
> bytes long.
> Data: < > CD CD CD CD CD CD CD CD CD CD CD CD
> c:\work\MyProject\MyUIthread.cpp(94) : {549} normal block at 0x00C17398, 12
> bytes long.
> Data: < 0 > C2 30 00 00 F2 C9 00 02 D1 01 00 00
> c:\work\MyProject\mainfrm.cpp(746) : {535} client block at 0x00C17E40,
> subtype 0, 128 bytes long.
> a CMyUIThread object at $00C17E40, 128 bytes long
> Object dump complete.
> The thread 0x304 has exited with code 0 (0x0).
> The program c:\work\MyProject\Debug\MyProject.exe' has exited with code 0
> (0x0).
>
> In my program, ui thread is created when certain selection made from combo
> box and shutdown, deleted when combo box selection. Ui thread creates one
> worker thread for communication with embeded system via COM port. So in a
> normal situation(combo box changed), shutdown prccedure is like this: First,
> main frame PostThreadMessage(QUIT) to ui thread. Ui thread set 'running'
> flag to FALSE to let worker thread exit its while(running) loop. Just before
> exit, worker thread sends another QUIT packet to embeded system to power off
> then PostMessage(THREAD_QUIT) to main frame. Message handler in main frame
> wait for m_hThread and delete pThread. Debugger doesn't complain about this
> normal shutdown and the program looks just fine when I try without debugger.
> Can I neglect this situation?
> Where can I insert this shutdown procedure when program is forced to quit
> while threads running?
> Any suggestion appreciated. Cheers

Handle the WM_CLOSE message in CMainFrame. It is sent when the user
clicks the 'X' close button. Start the thread shutdown sequence, then
either postpone the close by not calling CFrameWnd::OnClose until you
have received your THREAD_QUIT message, or use WaitForMultipleObjects to
wait for the thread handles before calling CFrameWnd::OnClose.

--
Scott McPhillips [VC++ MVP]

 
 
Joseph





PostPosted: Thu Jun 23 17:50:30 CDT 2005 Top

MFC >> When user trying to quit program while thread is running It is your responsibility to make sure that all threads cleanly terminate. How do you mean
that a thread is "deleted"?

Note that setting a running flag to FALSE for a worker thread works only if the thread in
question is (a) compute bound in a tight loop, and polling for the flag or (b) has a way
to come out of a wait and check the flag.

What is QUIT? A user-defined message, or is it WM_QUIT? If it is a user-defined message,
you should probably use a better name, such as UWM_QUIT or something like that.

What was allocated in MyUIThread.cpp(396)? At mainfrm.cpp(746)? etc. It looks suspicious;
I'd worry about it, and would try to solve it by trying to make sure that all values were
properly freed.
joe
On Fri, 24 Jun 2005 10:17:55 +1200, "bbg" <EMail@HideDomain.com> wrote:

>Hi guys, I have a memory leak problem. When I tried to quit program by click
>'x' at top right corner while my ui thread and its child worker thread are
>running, debugger display following messages:
>
>The thread 0x570 has exited with code 0 (0x0).
>The thread 0x574 has exited with code 0 (0x0).
>Detected memory leaks!
>Dumping objects ->
>c:\work\MyProject\MyUIthread.cpp(396) : {717} normal block at 0x00C17CA8, 4
>bytes long.
>a CWinThread object at $00C17BF0, 112 bytes long
>c:\work\MyProject\MyUIthread.cpp(96) : {550} normal block at 0x00C17FC0, 12
>bytes long.
> Data: < > CD CD CD CD CD CD CD CD CD CD CD CD
>c:\work\MyProject\MyUIthread.cpp(94) : {549} normal block at 0x00C17398, 12
>bytes long.
> Data: < 0 > C2 30 00 00 F2 C9 00 02 D1 01 00 00
>c:\work\MyProject\mainfrm.cpp(746) : {535} client block at 0x00C17E40,
>subtype 0, 128 bytes long.
>a CMyUIThread object at $00C17E40, 128 bytes long
>Object dump complete.
>The thread 0x304 has exited with code 0 (0x0).
>The program c:\work\MyProject\Debug\MyProject.exe' has exited with code 0
>(0x0).
>
>In my program, ui thread is created when certain selection made from combo
>box and shutdown, deleted when combo box selection. Ui thread creates one
>worker thread for communication with embeded system via COM port. So in a
>normal situation(combo box changed), shutdown prccedure is like this: First,
>main frame PostThreadMessage(QUIT) to ui thread. Ui thread set 'running'
>flag to FALSE to let worker thread exit its while(running) loop. Just before
>exit, worker thread sends another QUIT packet to embeded system to power off
>then PostMessage(THREAD_QUIT) to main frame. Message handler in main frame
>wait for m_hThread and delete pThread. Debugger doesn't complain about this
>normal shutdown and the program looks just fine when I try without debugger.
>Can I neglect this situation?
>Where can I insert this shutdown procedure when program is forced to quit
>while threads running?
>Any suggestion appreciated. Cheers
>

Joseph M. Newcomer [MVP]
email: EMail@HideDomain.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
 
 
bbg





PostPosted: Sun Jun 26 16:17:11 CDT 2005 Top

MFC >> When user trying to quit program while thread is running Thank you Scott for your pin-point answer. I will start to write code like
this:
void CMainFrame::OnClose()
{
if (COMBO_SELECTION == SELECTION_1)
{
//......
}
else
CFrameWnd::OnClose();
}

"Scott McPhillips [MVP]" <org-dot-mvps-at-scottmcp> wrote in message
news:EMail@HideDomain.com...
> bbg wrote:
>
> > Hi guys, I have a memory leak problem. When I tried to quit program by
click
> > 'x' at top right corner while my ui thread and its child worker thread
are
> > running, debugger display following messages:
> >
> > The thread 0x570 has exited with code 0 (0x0).
> > The thread 0x574 has exited with code 0 (0x0).
> > Detected memory leaks!
> > Dumping objects ->
> > c:\work\MyProject\MyUIthread.cpp(396) : {717} normal block at
0x00C17CA8, 4
> > bytes long.
> > a CWinThread object at $00C17BF0, 112 bytes long
> > c:\work\MyProject\MyUIthread.cpp(96) : {550} normal block at 0x00C17FC0,
12
> > bytes long.
> > Data: < > CD CD CD CD CD CD CD CD CD CD CD CD
> > c:\work\MyProject\MyUIthread.cpp(94) : {549} normal block at 0x00C17398,
12
> > bytes long.
> > Data: < 0 > C2 30 00 00 F2 C9 00 02 D1 01 00 00
> > c:\work\MyProject\mainfrm.cpp(746) : {535} client block at 0x00C17E40,
> > subtype 0, 128 bytes long.
> > a CMyUIThread object at $00C17E40, 128 bytes long
> > Object dump complete.
> > The thread 0x304 has exited with code 0 (0x0).
> > The program c:\work\MyProject\Debug\MyProject.exe' has exited with code
0
> > (0x0).
> >
> > In my program, ui thread is created when certain selection made from
combo
> > box and shutdown, deleted when combo box selection. Ui thread creates
one
> > worker thread for communication with embeded system via COM port. So in
a
> > normal situation(combo box changed), shutdown prccedure is like this:
First,
> > main frame PostThreadMessage(QUIT) to ui thread. Ui thread set 'running'
> > flag to FALSE to let worker thread exit its while(running) loop. Just
before
> > exit, worker thread sends another QUIT packet to embeded system to power
off
> > then PostMessage(THREAD_QUIT) to main frame. Message handler in main
frame
> > wait for m_hThread and delete pThread. Debugger doesn't complain about
this
> > normal shutdown and the program looks just fine when I try without
debugger.
> > Can I neglect this situation?
> > Where can I insert this shutdown procedure when program is forced to
quit
> > while threads running?
> > Any suggestion appreciated. Cheers
>
> Handle the WM_CLOSE message in CMainFrame. It is sent when the user
> clicks the 'X' close button. Start the thread shutdown sequence, then
> either postpone the close by not calling CFrameWnd::OnClose until you
> have received your THREAD_QUIT message, or use WaitForMultipleObjects to
> wait for the thread handles before calling CFrameWnd::OnClose.
>
> --
> Scott McPhillips [VC++ MVP]
>


 
 
bbg





PostPosted: Sun Jun 26 16:56:13 CDT 2005 Top

MFC >> When user trying to quit program while thread is running Joe, I'm greatly depending on knowledges obtained from your essays when
writing threads codes, many appreciates for sharing your know-hows.

> It is your responsibility to make sure that all threads cleanly terminate.
How do you mean
> that a thread is "deleted"?

When combo selection changed to other one, main frame sends following
message to ui thread to shutdown threads:

pMyUIThread->PostThreadMessage(UWM_BUTTON_PRESSED,
(WPARAM)(BYTE)QUIT,0);

Then ui thread set some volatile flag so that worker thread detects it and
set running flag to FALSE to exit while loop.
Worker thread also send back following message to main frame:

AfxGetMainWnd()->PostMessage(UWM_THREAD_1,
(WPARAM)(BYTE)THREAD_1_QUIT,0);

Then main frame's thread message handler may think that worker thread has
shutdown and does following jobs to terminate ui thread:

LRESULT CMainFrame::OnThreadMessage(WPARAM wParam, LPARAM lParam)
{
BYTE WhatHappened = (BYTE)wParam;
//...........
else if (WhatHappened == THREAD_DISPLAY_STATUS_INFO)
{
CString * s = (CString *)lParam;
m_wndStatusBar.SetPaneText (1, *s, TRUE);
delete s;
}
else if (WhatHappened == THREAD_QUIT)
{
pMyUIThread->PostThreadMessage(WM_QUIT, 0, 0); // as you recomended...
it works well in not 'X' button case
VERIFY(WaitForSingleObject(pMyUIThread->m_hThread, INFINITE) ==
WAIT_OBJECT_0);
delete pMyUIThread;
}
return 0;
}

Now, I'm trying to write CMainFrame::OnClose() to handle 'X' button case and
trouble is that....
In my shutodwn method, main frame may know when it can send WM_QUIT to
terminate ui thread by waiting message from worker thread.
But in 'X' button case, message handler doesn't have a chance to handle that
message, so codes below are not working properly.

void CMainFrame::OnClose()
{
if (COMBO_SELECTION == CHOICE_1) // if ui/worker threads were working,
try to shutdown them
{
// send QUIT to MyUIThread to shutdown worker thread and ui thread itself
pMyUIThread->PostThreadMessage(UWM_BUTTON_PRESSED, (WPARAM)(BYTE)QUIT,0);
// MyUIThread will send back UWM_THREAD_MSG(QUIT).
// But no chance to be handled in 'X' button case
pMyUIThread->PostThreadMessage(WM_QUIT, 0, 0);
VERIFY(WaitForSingleObject(pMyUIThread->m_hThread, INFINITE) ==
WAIT_OBJECT_0);
delete pMyUIThread;
}
else
CFrameWnd::OnClose();
}

Thanks
bbg

> On Fri, 24 Jun 2005 10:17:55 +1200, "bbg" <EMail@HideDomain.com>
wrote:
>
> >Hi guys, I have a memory leak problem. When I tried to quit program by
click
> >'x' at top right corner while my ui thread and its child worker thread
are
> >running, debugger display following messages:
> >
> >The thread 0x570 has exited with code 0 (0x0).
> >The thread 0x574 has exited with code 0 (0x0).
> >Detected memory leaks!
> >Dumping objects ->
> >c:\work\MyProject\MyUIthread.cpp(396) : {717} normal block at 0x00C17CA8,
4
> >bytes long.
> >a CWinThread object at $00C17BF0, 112 bytes long
> >c:\work\MyProject\MyUIthread.cpp(96) : {550} normal block at 0x00C17FC0,
12
> >bytes long.
> > Data: < > CD CD CD CD CD CD CD CD CD CD CD CD
> >c:\work\MyProject\MyUIthread.cpp(94) : {549} normal block at 0x00C17398,
12
> >bytes long.
> > Data: < 0 > C2 30 00 00 F2 C9 00 02 D1 01 00 00
> >c:\work\MyProject\mainfrm.cpp(746) : {535} client block at 0x00C17E40,
> >subtype 0, 128 bytes long.
> >a CMyUIThread object at $00C17E40, 128 bytes long
> >Object dump complete.
> >The thread 0x304 has exited with code 0 (0x0).
> >The program c:\work\MyProject\Debug\MyProject.exe' has exited with code 0
> >(0x0).
> >
> >In my program, ui thread is created when certain selection made from
combo
> >box and shutdown, deleted when combo box selection. Ui thread creates one
> >worker thread for communication with embeded system via COM port. So in a
> >normal situation(combo box changed), shutdown prccedure is like this:
First,
> >main frame PostThreadMessage(QUIT) to ui thread. Ui thread set 'running'
> >flag to FALSE to let worker thread exit its while(running) loop. Just
before
> >exit, worker thread sends another QUIT packet to embeded system to power
off
> >then PostMessage(THREAD_QUIT) to main frame. Message handler in main
frame
> >wait for m_hThread and delete pThread. Debugger doesn't complain about
this
> >normal shutdown and the program looks just fine when I try without
debugger.
> >Can I neglect this situation?
> >Where can I insert this shutdown procedure when program is forced to quit
> >while threads running?
> >Any suggestion appreciated. Cheers
> >
>
> Joseph M. Newcomer [MVP]
> email: EMail@HideDomain.com
> Web: http://www.flounder.com
> MVP Tips: http://www.flounder.com/mvp_tips.htm



 
 
Joseph





PostPosted: Sun Jun 26 22:18:29 CDT 2005 Top

MFC >> When user trying to quit program while thread is running See below...
On Mon, 27 Jun 2005 09:56:13 +1200, "bbg" <EMail@HideDomain.com> wrote:

>Joe, I'm greatly depending on knowledges obtained from your essays when
>writing threads codes, many appreciates for sharing your know-hows.
>
>> It is your responsibility to make sure that all threads cleanly terminate.
>How do you mean
>> that a thread is "deleted"?
>
>When combo selection changed to other one, main frame sends following
>message to ui thread to shutdown threads:
>
> pMyUIThread->PostThreadMessage(UWM_BUTTON_PRESSED,
>(WPARAM)(BYTE)QUIT,0);
****
Note that the thread must be blocked on the message pump GetMessage to see this. If the
thread is off doing some long computation, this will not be seen until the computation
finishes.

If it does as you say and sets a volatile flag, then the worker thread will, if it
properly polls this flag, terminate.
****
>
>Then ui thread set some volatile flag so that worker thread detects it and
>set running flag to FALSE to exit while loop.
>Worker thread also send back following message to main frame:
>
> AfxGetMainWnd()->PostMessage(UWM_THREAD_1,
>(WPARAM)(BYTE)THREAD_1_QUIT,0);
****
Be careful about AfxGetMainWnd() in worker threads; it doesn't always give you the main
window. I tend to do
::PostMessage(AfxGetApp()->m_hWnd, ...)
or better still, pass the CWnd * object in so I can just call its methods directly
****
>
>Then main frame's thread message handler may think that worker thread has
>shutdown and does following jobs to terminate ui thread:
>
>LRESULT CMainFrame::OnThreadMessage(WPARAM wParam, LPARAM lParam)
>{
> BYTE WhatHappened = (BYTE)wParam;
> //...........
> else if (WhatHappened == THREAD_DISPLAY_STATUS_INFO)
> {
> CString * s = (CString *)lParam;
> m_wndStatusBar.SetPaneText (1, *s, TRUE);
> delete s;
> }
> else if (WhatHappened == THREAD_QUIT)
> {
> pMyUIThread->PostThreadMessage(WM_QUIT, 0, 0); // as you recomended...
>it works well in not 'X' button case
> VERIFY(WaitForSingleObject(pMyUIThread->m_hThread, INFINITE) ==
>WAIT_OBJECT_0);
> delete pMyUIThread;
****
Only if you have set m_bAutoDelete to FALSE. This requires creating the thread suspended,
setting the m_bAutoDelete = FALSE, then doing a ResumeThread. Otherwise the delete will
likely result in a serious error as you try to delete a piece of storage the second time.
***
> }
> return 0;
>}
>
>Now, I'm trying to write CMainFrame::OnClose() to handle 'X' button case and
>trouble is that....
>In my shutodwn method, main frame may know when it can send WM_QUIT to
>terminate ui thread by waiting message from worker thread.
>But in 'X' button case, message handler doesn't have a chance to handle that
>message, so codes below are not working properly.
****
The [x] button should be generated a WM_CLOSE message, so you should be hitting the
OnClose handler. Can you verify this with the debugger?
****
>
>void CMainFrame::OnClose()
>{
> if (COMBO_SELECTION == CHOICE_1) // if ui/worker threads were working,
>try to shutdown them
****
Be very cautious of this sort of code; you shouldn't be checking the combo box, you should
be checking to see if there is a thread-running state. Note that in multiple languages,
the choices may be ordered differently. And what happens if the user changes the combo box
setting, then hits the close box while the thread is shutting down?
***
> {
> // send QUIT to MyUIThread to shutdown worker thread and ui thread itself
> pMyUIThread->PostThreadMessage(UWM_BUTTON_PRESSED, (WPARAM)(BYTE)QUIT,0);
> // MyUIThread will send back UWM_THREAD_MSG(QUIT).
> // But no chance to be handled in 'X' button case
> pMyUIThread->PostThreadMessage(WM_QUIT, 0, 0);
> VERIFY(WaitForSingleObject(pMyUIThread->m_hThread, INFINITE) ==
>WAIT_OBJECT_0);
> delete pMyUIThread;
****
Same problem with m_bAutoDelete. Note that even doing the WaitForSingleObject may fail
horribly because the thread may have finished, and deleted the object pMyUIThread
references, and they you try to use it to point to something else. Not a good idea unless
you have made sure that m_bAutoDelete is FALSE (if it isn't, this code could crash in a
rather nasty number of ways)

My own preference these days would be to simply set a flag saying "shutdown in progress"
and return, instead of doing the WaitFor. Any attempt to use any menu item would make sure
the menu item was disabled. Then when the thread message was received by the mainframe
that ALL threads were finished, then you call CFrameWnd::OnClose.
****
> }
> else
> CFrameWnd::OnClose();
>}
>
>Thanks
>bbg
>
>> On Fri, 24 Jun 2005 10:17:55 +1200, "bbg" <EMail@HideDomain.com>
>wrote:
>>
>> >Hi guys, I have a memory leak problem. When I tried to quit program by
>click
>> >'x' at top right corner while my ui thread and its child worker thread
>are
>> >running, debugger display following messages:
>> >
>> >The thread 0x570 has exited with code 0 (0x0).
>> >The thread 0x574 has exited with code 0 (0x0).
>> >Detected memory leaks!
>> >Dumping objects ->
>> >c:\work\MyProject\MyUIthread.cpp(396) : {717} normal block at 0x00C17CA8,
>4
>> >bytes long.
>> >a CWinThread object at $00C17BF0, 112 bytes long
>> >c:\work\MyProject\MyUIthread.cpp(96) : {550} normal block at 0x00C17FC0,
>12
>> >bytes long.
>> > Data: < > CD CD CD CD CD CD CD CD CD CD CD CD
>> >c:\work\MyProject\MyUIthread.cpp(94) : {549} normal block at 0x00C17398,
>12
>> >bytes long.
>> > Data: < 0 > C2 30 00 00 F2 C9 00 02 D1 01 00 00
>> >c:\work\MyProject\mainfrm.cpp(746) : {535} client block at 0x00C17E40,
>> >subtype 0, 128 bytes long.
>> >a CMyUIThread object at $00C17E40, 128 bytes long
>> >Object dump complete.
>> >The thread 0x304 has exited with code 0 (0x0).
>> >The program c:\work\MyProject\Debug\MyProject.exe' has exited with code 0
>> >(0x0).
>> >
>> >In my program, ui thread is created when certain selection made from
>combo
>> >box and shutdown, deleted when combo box selection. Ui thread creates one
>> >worker thread for communication with embeded system via COM port. So in a
>> >normal situation(combo box changed), shutdown prccedure is like this:
>First,
>> >main frame PostThreadMessage(QUIT) to ui thread. Ui thread set 'running'
>> >flag to FALSE to let worker thread exit its while(running) loop. Just
>before
>> >exit, worker thread sends another QUIT packet to embeded system to power
>off
>> >then PostMessage(THREAD_QUIT) to main frame. Message handler in main
>frame
>> >wait for m_hThread and delete pThread. Debugger doesn't complain about
>this
>> >normal shutdown and the program looks just fine when I try without
>debugger.
>> >Can I neglect this situation?
>> >Where can I insert this shutdown procedure when program is forced to quit
>> >while threads running?
>> >Any suggestion appreciated. Cheers
>> >
>>
>> Joseph M. Newcomer [MVP]
>> email: EMail@HideDomain.com
>> Web: http://www.flounder.com
>> MVP Tips: http://www.flounder.com/mvp_tips.htm
>
>

Joseph M. Newcomer [MVP]
email: EMail@HideDomain.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm