X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/5159e01481609101d7bf20b3e32457346e631df6..59b7da02ff62a33862accc13158870f2a9a23630:/interface/wx/thread.h diff --git a/interface/wx/thread.h b/interface/wx/thread.h index c454f8e925..34d98462fd 100644 --- a/interface/wx/thread.h +++ b/interface/wx/thread.h @@ -3,7 +3,7 @@ // Purpose: interface of all thread-related wxWidgets classes // Author: wxWidgets team // RCS-ID: $Id$ -// Licence: wxWindows license +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// @@ -279,7 +279,7 @@ public: Example: @code - extern const wxEventType wxEVT_COMMAND_MYTHREAD_UPDATE; + wxDECLARE_EVENT(wxEVT_COMMAND_MYTHREAD_UPDATE, wxThreadEvent); class MyFrame : public wxFrame, public wxThreadHelper { @@ -298,7 +298,7 @@ public: ... void DoStartALongTask(); - void OnThreadUpdate(wxCommandEvent& evt); + void OnThreadUpdate(wxThreadEvent& evt); void OnClose(wxCloseEvent& evt); ... @@ -309,14 +309,14 @@ public: char m_data[1024]; wxCriticalSection m_dataCS; // protects field above - DECLARE_EVENT_TABLE() + wxDECLARE_EVENT_TABLE(); }; - DEFINE_EVENT_TYPE(wxEVT_COMMAND_MYTHREAD_UPDATE) - BEGIN_EVENT_TABLE(MyFrame, wxFrame) + wxDEFINE_EVENT(wxEVT_COMMAND_MYTHREAD_UPDATE, wxThreadEvent) + wxBEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_MYTHREAD_UPDATE, MyFrame::OnThreadUpdate) EVT_CLOSE(MyFrame::OnClose) - END_EVENT_TABLE() + wxEND_EVENT_TABLE() void MyFrame::DoStartALongTask() { @@ -364,7 +364,7 @@ public: // VERY IMPORTANT: do not call any GUI function inside this // function; rather use wxQueueEvent(): - wxQueueEvent(this, new wxCommandEvent(wxEVT_COMMAND_MYTHREAD_UPDATE)); + wxQueueEvent(this, new wxThreadEvent(wxEVT_COMMAND_MYTHREAD_UPDATE)); // we used pointer 'this' assuming it's safe; see OnClose() } @@ -386,7 +386,7 @@ public: Destroy(); } - void MyFrame::OnThreadUpdate(wxCommandEvent&evt) + void MyFrame::OnThreadUpdate(wxThreadEvent& evt) { // ...do something... e.g. m_pGauge->Pulse(); @@ -399,7 +399,7 @@ public: @library{wxbase} @category{threading} - @see wxThread + @see wxThread, wxThreadEvent */ class wxThreadHelper { @@ -454,6 +454,12 @@ public: */ virtual ExitCode Entry() = 0; + /** + @deprecated + Use CreateThread() instead. + */ + wxThreadError Create(unsigned int stackSize = 0); + /** Creates a new thread of the given @a kind. @@ -512,6 +518,10 @@ enum wxCriticalSectionType @library{wxbase} @category{threading} + @note Critical sections can be used before the wxWidgets library is fully + initialized. In particular, it's safe to create global + wxCriticalSection instances. + @see wxThread, wxCondition, wxCriticalSectionLocker */ class wxCriticalSection @@ -529,11 +539,17 @@ public: ~wxCriticalSection(); /** - Enter the critical section (same as locking a mutex). - + Enter the critical section (same as locking a mutex): if another thread + has already entered it, this call will block until the other thread + calls Leave(). There is no error return for this function. - After entering the critical section protecting some global - data the thread running in critical section may safely use/modify it. + + After entering the critical section protecting a data variable, + the thread running inside the critical section may safely use/modify it. + + Note that entering the same critical section twice or more from the same + thread doesn't result in a deadlock; in this case in fact this function will + immediately return. */ void Enter(); @@ -625,8 +641,8 @@ enum @code // declare a new type of event, to be used by our MyThread class: - extern const wxEventType wxEVT_COMMAND_MYTHREAD_COMPLETED; - extern const wxEventType wxEVT_COMMAND_MYTHREAD_UPDATE; + wxDECLARE_EVENT(wxEVT_COMMAND_MYTHREAD_COMPLETED, wxThreadEvent); + wxDECLARE_EVENT(wxEVT_COMMAND_MYTHREAD_UPDATE, wxThreadEvent); class MyFrame; class MyThread : public wxThread @@ -663,25 +679,26 @@ enum // a resume routine would be nearly identic to DoPauseThread() void DoResumeThread() { ... } - void OnThreadCompletion(wxCommandEvent&); + void OnThreadUpdate(wxThreadEvent&); + void OnThreadCompletion(wxThreadEvent&); void OnClose(wxCloseEvent&); protected: MyThread *m_pThread; wxCriticalSection m_pThreadCS; // protects the m_pThread pointer - DECLARE_EVENT_TABLE() + wxDECLARE_EVENT_TABLE(); }; - BEGIN_EVENT_TABLE(MyFrame, wxFrame) + wxBEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_CLOSE(MyFrame::OnClose) EVT_MENU(Minimal_Start, MyFrame::DoStartThread) EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_MYTHREAD_UPDATE, MyFrame::OnThreadUpdate) EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_MYTHREAD_COMPLETED, MyFrame::OnThreadCompletion) - END_EVENT_TABLE() + wxEND_EVENT_TABLE() - DEFINE_EVENT_TYPE(wxEVT_COMMAND_MYTHREAD_COMPLETED) - DEFINE_EVENT_TYPE(wxEVT_COMMAND_MYTHREAD_UPDATE) + wxDEFINE_EVENT(wxEVT_COMMAND_MYTHREAD_COMPLETED, wxThreadEvent) + wxDEFINE_EVENT(wxEVT_COMMAND_MYTHREAD_UPDATE, wxThreadEvent) void MyFrame::DoStartThread() { @@ -715,13 +732,13 @@ enum { // ... do a bit of work... - wxQueueEvent(m_pHandler, new wxCommandEvent(wxEVT_COMMAND_MYTHREAD_UPDATE)); + wxQueueEvent(m_pHandler, new wxThreadEvent(wxEVT_COMMAND_MYTHREAD_UPDATE)); } // signal the event handler that this thread is going to be destroyed // NOTE: here we assume that using the m_pHandler pointer is safe, // (in this case this is assured by the MyFrame destructor) - wxQueueEvent(m_pHandler, new wxCommandEvent(wxEVT_COMMAND_MYTHREAD_COMPLETED)); + wxQueueEvent(m_pHandler, new wxThreadEvent(wxEVT_COMMAND_MYTHREAD_COMPLETED)); return (wxThread::ExitCode)0; // success } @@ -734,12 +751,12 @@ enum m_pHandler->m_pThread = NULL; } - void MyFrame::OnThreadCompletion(wxCommandEvent&) + void MyFrame::OnThreadCompletion(wxThreadEvent&) { wxMessageOutputDebug().Printf("MYFRAME: MyThread exited!\n"); } - void MyFrame::OnThreadUpdate(wxCommandEvent&) + void MyFrame::OnThreadUpdate(wxThreadEvent&) { wxMessageOutputDebug().Printf("MYFRAME: MyThread update...\n"); } @@ -771,7 +788,7 @@ enum if (m_pThread) // does the thread still exist? { - m_out.Printf("MYFRAME: deleting thread"); + wxMessageOutputDebug().Printf("MYFRAME: deleting thread"); if (m_pThread->Delete() != wxTHREAD_NO_ERROR ) wxLogError("Can't delete the thread!"); @@ -857,9 +874,9 @@ enum as MFC. A workaround for some wxWidgets ports is calling wxMutexGUIEnter() - before any GUI calls and then calling wxMutexGUILeave() afterwords. However, - the recommended way is to simply process the GUI calls in the main thread - through an event that is posted by wxQueueEvent(). + before any GUI calls and then calling wxMutexGUILeave() afterwords. + However, the recommended way is to simply process the GUI calls in the main + thread through an event that is posted by wxQueueEvent(). This does not imply that calls to these classes are thread-safe, however, as most wxWidgets classes are not thread-safe, including wxString. @@ -966,15 +983,22 @@ public: /** Returns the number of system CPUs or -1 if the value is unknown. + For multi-core systems the returned value is typically the total number + of @e cores, since the OS usually abstract a single N-core CPU + as N different cores. + @see SetConcurrency() */ static int GetCPUCount(); /** Returns the platform specific thread ID of the current thread as a long. + This can be used to uniquely identify threads, even if they are not wxThreads. + + @see GetMainId() */ - static unsigned long GetCurrentId(); + static wxThreadIdType GetCurrentId(); /** Gets the thread identifier: this is a platform dependent number that uniquely @@ -990,6 +1014,15 @@ public: */ wxThreadKind GetKind() const; + /** + Returns the thread ID of the main thread. + + @see IsMain() + + @since 2.9.1 + */ + static wxThreadIdType GetMainId(); + /** Gets the priority of the thread, between zero and 100. @@ -1018,6 +1051,11 @@ public: /** Returns @true if the calling thread is the main application thread. + + Main thread in the context of wxWidgets is the one which initialized + the library. + + @see GetMainId(), GetCurrentId() */ static bool IsMain(); @@ -1058,17 +1096,6 @@ public: */ wxThreadError Kill(); - /** - Called when the thread exits. - - This function is called in the context of the thread associated with the - wxThread object, not in the context of the main thread. - This function will not be called if the thread was @ref Kill() killed. - - This function should never be called directly. - */ - virtual void OnExit(); - /** Suspends the thread. @@ -1098,6 +1125,10 @@ public: of detached threads. This function can only be called from another thread context. + + Finally, note that once a thread has completed and its Entry() function + returns, you cannot call Run() on it again (an assert will fail in debug + builds or @c wxTHREAD_RUNNING will be returned in release builds). */ wxThreadError Run(); @@ -1227,6 +1258,19 @@ protected: OnExit() will be called just before exiting. */ void Exit(ExitCode exitcode = 0); + +private: + + /** + Called when the thread exits. + + This function is called in the context of the thread associated with the + wxThread object, not in the context of the main thread. + This function will not be called if the thread was @ref Kill() killed. + + This function should never be called directly. + */ + virtual void OnExit(); }; @@ -1493,6 +1537,9 @@ public: Locks the mutex object. This is equivalent to LockTimeout() with infinite timeout. + Note that if this mutex is already locked by the caller thread, + this function doesn't block but rather immediately returns. + @return One of: @c wxMUTEX_NO_ERROR, @c wxMUTEX_DEAD_LOCK. */ wxMutexError Lock(); @@ -1525,7 +1572,7 @@ public: // Global functions/macros // ============================================================================ -/** @ingroup group_funcmacro_thread */ +/** @addtogroup group_funcmacro_thread */ //@{ /** @@ -1608,6 +1655,8 @@ public: */ bool wxIsMainThread(); + + /** This function must be called when any thread other than the main GUI thread wants to get access to the GUI library. This function will block the @@ -1626,14 +1675,14 @@ bool wxIsMainThread(); wxMutexGuiEnter(); // Call GUI here: - my_window-DrawSomething(); + my_window->DrawSomething(); wxMutexGuiLeave(); } @endcode This function is only defined on platforms which support preemptive - threads. + threads and only works under some ports (wxMSW currently). @note Under GTK, no creation of top-level windows is allowed in any thread but the main one.