X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/81f1bb400ab97cdd1d776e1129db2b0fa567819c..1d61ebaca18624cadf455a8859c1d089db5e6a23:/samples/thread/test.cpp?ds=sidebyside diff --git a/samples/thread/test.cpp b/samples/thread/test.cpp index 7d2c088b4f..053b052712 100644 --- a/samples/thread/test.cpp +++ b/samples/thread/test.cpp @@ -41,15 +41,25 @@ #include "wx/dynarray.h" #include "wx/time.h" +class MyThread; +WX_DEFINE_ARRAY(wxThread *, wxArrayThread); + // Define a new application type class MyApp : public wxApp { -public: - bool OnInit(); + public: + // all the threads currently alive - as soon as the thread terminates, it's + // removed from the array + wxArrayThread m_threads; + + // crit section protects access to all of the arrays below + wxCriticalSection m_critsect; + public: + bool OnInit(); }; -class MyThread; -WX_DEFINE_ARRAY(wxThread *, wxArrayThread); +// Create a new application object +IMPLEMENT_APP (MyApp) // Define a new frame type class MyFrame: public wxFrame @@ -74,32 +84,11 @@ public: void OnIdle(wxIdleEvent &event); - // called by dying thread _in_that_thread_context_ - void OnThreadExit(wxThread *thread); - private: // helper function - creates a new thread (but doesn't run it) MyThread *CreateThread(); - - // crit section protects access to all of the arrays below - wxCriticalSection m_critsect; - - // all the threads currently alive - as soon as the thread terminates, it's - // removed from the array - wxArrayThread m_threads; - - // both of these arrays are only valid between 2 iterations of OnIdle(), - // they're cleared each time it is excuted. - - // the array of threads which finished (either because they did their work - // or because they were explicitly stopped) - wxArrayThread m_terminated; - - // the array of threads which were stopped by the user and not terminated - // by themselves - these threads shouldn't be Delete()d second time from - // OnIdle() - wxArrayThread m_stopped; - + + // just some place to put our messages in wxTextCtrl *m_txtctrl; @@ -142,15 +131,21 @@ void MyThread::WriteText(const wxString& text) // before doing any GUI calls we must ensure that this thread is the only // one doing it! - wxMutexGuiLocker guiLocker; + + wxMutexGuiEnter(); + msg << wxTime().FormatTime() << ": " << text; m_frame->WriteText(msg); + + wxMutexGuiLeave(); } void MyThread::OnExit() { - m_frame->OnThreadExit(this); + wxCriticalSectionLocker locker(wxGetApp().m_critsect); + + wxGetApp().m_threads.Remove(this); } void *MyThread::Entry() @@ -206,9 +201,6 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_IDLE(MyFrame::OnIdle) END_EVENT_TABLE() -// Create a new application object -IMPLEMENT_APP (MyApp) - // `Main program' equivalent, creating windows and returning main app frame bool MyApp::OnInit() { @@ -268,8 +260,8 @@ MyThread *MyFrame::CreateThread() wxLogError("Can't create thread!"); } - wxCriticalSectionLocker enter(m_critsect); - m_threads.Add(thread); + wxCriticalSectionLocker enter(wxGetApp().m_critsect); + wxGetApp().m_threads.Add(thread); return thread; } @@ -322,21 +314,20 @@ void MyFrame::OnStartThread(wxCommandEvent& WXUNUSED(event) ) void MyFrame::OnStopThread(wxCommandEvent& WXUNUSED(event) ) { // stop the last thread - if ( m_threads.IsEmpty() ) + if ( wxGetApp().m_threads.IsEmpty() ) { wxLogError("No thread to stop!"); } else { - m_critsect.Enter(); + wxGetApp().m_critsect.Enter(); - wxThread *thread = m_threads.Last(); - m_stopped.Add(thread); + wxThread *thread = wxGetApp().m_threads.Last(); // it's important to leave critical section before calling Delete() - // because delete will (implicitly) call OnThreadExit() which also tries + // because delete will (implicitly) call OnExit() which also tries // to enter the same crit section - would dead lock. - m_critsect.Leave(); + wxGetApp().m_critsect.Leave(); thread->Delete(); @@ -346,11 +337,11 @@ void MyFrame::OnStopThread(wxCommandEvent& WXUNUSED(event) ) void MyFrame::OnResumeThread(wxCommandEvent& WXUNUSED(event) ) { - wxCriticalSectionLocker enter(m_critsect); + wxCriticalSectionLocker enter(wxGetApp().m_critsect); // resume first suspended thread - size_t n = 0, count = m_threads.Count(); - while ( n < count && !m_threads[n]->IsPaused() ) + size_t n = 0, count = wxGetApp().m_threads.Count(); + while ( n < count && !wxGetApp().m_threads[n]->IsPaused() ) n++; if ( n == count ) @@ -359,7 +350,7 @@ void MyFrame::OnResumeThread(wxCommandEvent& WXUNUSED(event) ) } else { - m_threads[n]->Resume(); + wxGetApp().m_threads[n]->Resume(); SetStatusText("Thread resumed.", 1); } @@ -367,11 +358,11 @@ void MyFrame::OnResumeThread(wxCommandEvent& WXUNUSED(event) ) void MyFrame::OnPauseThread(wxCommandEvent& WXUNUSED(event) ) { - wxCriticalSectionLocker enter(m_critsect); + wxCriticalSectionLocker enter(wxGetApp().m_critsect); // pause last running thread - int n = m_threads.Count() - 1; - while ( n >= 0 && !m_threads[n]->IsRunning() ) + int n = wxGetApp().m_threads.Count() - 1; + while ( n >= 0 && !wxGetApp().m_threads[n]->IsRunning() ) n--; if ( n < 0 ) @@ -380,8 +371,8 @@ void MyFrame::OnPauseThread(wxCommandEvent& WXUNUSED(event) ) } else { - m_threads[n]->Pause(); - + wxGetApp().m_threads[n]->Pause(); + SetStatusText("Thread paused.", 1); } } @@ -389,29 +380,12 @@ void MyFrame::OnPauseThread(wxCommandEvent& WXUNUSED(event) ) // set the frame title indicating the current number of threads void MyFrame::OnIdle(wxIdleEvent &event) { - // first wait for all the threads which dies since the last call - { - wxCriticalSectionLocker enter(m_critsect); - - size_t nCount = m_terminated.GetCount(); - for ( size_t n = 0; n < nCount; n++ ) - { - // don't delete the threads which were stopped - they were already - // deleted in OnStopThread() - wxThread *thread = m_terminated[n]; - if ( m_stopped.Index(thread) == wxNOT_FOUND ) - thread->Delete(); - } - - m_stopped.Empty(); - m_terminated.Empty(); - } - + // update the counts of running/total threads size_t nRunning = 0, - nCount = m_threads.Count(); + nCount = wxGetApp().m_threads.Count(); for ( size_t n = 0; n < nCount; n++ ) { - if ( m_threads[n]->IsRunning() ) + if ( wxGetApp().m_threads[n]->IsRunning() ) nRunning++; } @@ -427,10 +401,10 @@ void MyFrame::OnIdle(wxIdleEvent &event) void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event) ) { - size_t count = m_threads.Count(); + size_t count = wxGetApp().m_threads.Count(); for ( size_t i = 0; i < count; i++ ) { - m_threads[i]->Delete(); + wxGetApp().m_threads[0]->Delete(); } Close(TRUE); @@ -451,11 +425,3 @@ void MyFrame::OnClear(wxCommandEvent& WXUNUSED(event)) { m_txtctrl->Clear(); } - -void MyFrame::OnThreadExit(wxThread *thread) -{ - wxCriticalSectionLocker enter(m_critsect); - - m_threads.Remove(thread); - m_terminated.Add(thread); -}