Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1034
  • Last Modified:

Using CEvent / CWinthread during thread termination

I'm writing a multithreaded MFC application (famous last words, I know).  I have a main dialog based application that uses AfxBeginThread to launch a CWinthread-derived UI thread of my design.  My question relates to how to properly terminate the thread when someone presses the cancel button in the main application dialog.

What I've tried so far is the following:  I created a CEvent member variable within the CWinthread-derived class which I initially set to unsignalled.  I have overridden OnCancel in the main dialog as follows:

CSomethingorother::OnCancel {
   m_pMyThread->PostThreadMessage(WM_BAILOUT, 0, 0);
   WaitForSingleObject(m_pMyThread->m_eEndEvent, INFINITE);
   CDialog::OnCancel();
}

When I catch the WM_BAILOUT message in my thread, I call PostQuitMessage.  Then, in ExitInstance for the thread, I have:

   m_eEndEvent.SetEvent();

This all seems to work just as I expect, but my question is this:  Is there a possibility that after the event is signalled, my thread will finish terminating and get deleted before the calling thread (my dialog app) has a chance to properly "see" the event when it's still valid.  In other words, am I running the risk of some later timing issues having it hang indefinitely?  Is this the correct and thread-safe way to do things?  The documentation for MFC's synchronization classes seems spotty to me and I'm not sure if they have some internal mechanisms for making sure things like this function correctly (in fact, I don't see how it could).

Any help would be greatly appreciated.
0
pHaze426
Asked:
pHaze426
  • 2
1 Solution
 
jkrCommented:
I'd suggest to use

CSomethingorother::OnCancel {
  m_pMyThread->PostThreadMessage(WM_BAILOUT, 0, 0);
  WaitForSingleObject(m_pMyThread->m_hThread, INFINITE);
  CDialog::OnCancel();
}

isntead, so you don't have to use an event in the 1st pace.
0
 
AxterCommented:
jkr makes a great suggestion.

I think you should modify the code, so it's not doing an infinite wait on the thread, and try to do a force kill on the thread if it takes too long.
CSomethingorother::OnCancel {
  const int QtyOfRetries = 9;
  DWORD  result ;
  for(int i = 0;i < QtyOfRetries;++i)
  {
    m_pMyThread->PostThreadMessage(WM_BAILOUT, 0, 0);
    DWORD  result = WaitForSingleObject(m_pMyThread->m_hThread, 60000);
    if (WAIT_TIMEOUT != result) break;
  }
  if (WAIT_TIMEOUT == result)
  {//Force kill the thread
  }
  CDialog::OnCancel();
}

That way your application doesn't hang if one thread hangs.
0
 
pHaze426Author Commented:
Guys,

  This seems like a good methodology as opposed to using CEvent, but assuming I wanted to stick with that.  I'm just unsure how a CEvent could be used in this manner, although it seems to be what they were designed for.  The documentation for WaitForSingleObject suggests that it consumes no CPU time while waiting for the event to occurr.  Does this register some sort of interrupt handler with the system for the event?  If so, that might mean I don't have to worry about it.
0
 
AxterCommented:
The problem with using event is that your thread might be dead already, or maybe it never got kicked off in the first place.
In which case, your application will hang forever if your waiting on an event signal
0

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now