+MyFrame::~MyFrame()
+{
+ // NB: although the OS will terminate all the threads anyhow when the main
+ // one exits, it's good practice to do it ourselves -- even if it's not
+ // completely trivial in this example
+
+ // tell all the threads to terminate: note that they can't terminate while
+ // 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
+ const wxArrayThread& threads = wxGetApp().m_threads;
+ size_t count = threads.GetCount();
+
+ if ( count )
+ {
+ // 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
+ wxGetApp().m_semAllDone.Wait();
+ }
+ //else: no threads to terminate, no condition to wait for
+}
+