From: Vadim Zeitlin Date: Sun, 21 Sep 2003 20:36:07 +0000 (+0000) Subject: fix problems with terminating while threads are running and more (patch 781922) X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/963ac8fbf59fbc3817d573ecd704663e84e0ebf8 fix problems with terminating while threads are running and more (patch 781922) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@23782 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/samples/thread/thread.cpp b/samples/thread/thread.cpp index 1040e283d0..3e65bde45d 100644 --- a/samples/thread/thread.cpp +++ b/samples/thread/thread.cpp @@ -58,12 +58,10 @@ public: // crit section protects access to all of the arrays below wxCriticalSection m_critsect; - // the (mutex, condition) pair used to wait for the threads to exit, see - // MyFrame::OnQuit() - wxMutex m_mutexAllDone; - wxCondition m_condAllDone; + // semaphore used to wait for the threads to exit, see MyFrame::OnQuit() + wxSemaphore m_semAllDone; - // the last exiting thread should signal m_condAllDone if this is true + // the last exiting thread should post to m_semAllDone if this is true // (protected by the same m_critsect) bool m_waitingUntilAllDone; }; @@ -212,8 +210,7 @@ void MyThread::OnExit() { wxGetApp().m_waitingUntilAllDone = FALSE; - wxMutexLocker lock(wxGetApp().m_mutexAllDone); - wxGetApp().m_condAllDone.Signal(); + wxGetApp().m_semAllDone.Post(); } } } @@ -354,19 +351,13 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame) END_EVENT_TABLE() MyApp::MyApp() - : m_condAllDone(m_mutexAllDone) + : m_semAllDone() { - // the mutex associated with a condition must be initially locked, it will - // only be unlocked when we call Wait() - m_mutexAllDone.Lock(); - m_waitingUntilAllDone = FALSE; } MyApp::~MyApp() { - // the mutex must be unlocked before being destroyed - m_mutexAllDone.Unlock(); } // `Main program' equivalent, creating windows and returning main app frame @@ -614,6 +605,8 @@ void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event) ) // we're deleting them because they will block in their OnExit() -- this is // important as otherwise we might access invalid array elements { + wxThread *thread; + wxGetApp().m_critsect.Enter(); // check if we have any threads running first @@ -622,27 +615,28 @@ void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event) ) if ( count ) { - // we do, ask them to stop - for ( size_t n = 0; n < count; n++ ) - { - threads[n]->Delete(); - } - // set the flag for MyThread::OnExit() wxGetApp().m_waitingUntilAllDone = TRUE; + + // stop all threads + while ( ! threads.IsEmpty() ) + { + thread = threads.Last(); + + wxGetApp().m_critsect.Leave(); + + thread->Delete(); + + wxGetApp().m_critsect.Enter(); + } } wxGetApp().m_critsect.Leave(); if ( count ) { - // now wait for them to really terminate but leave the GUI mutex - // before doing it as otherwise we might dead lock - wxMutexGuiLeave(); - - wxGetApp().m_condAllDone.Wait(); - - wxMutexGuiEnter(); + // now wait for them to really terminate + wxGetApp().m_semAllDone.Wait(); } //else: no threads to terminate, no condition to wait for }