X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/12f5e1e78fe906050ff2fee9529476db332633f0..704ceca8d2cd8da51a5cc22f8c51fd61c762dbf5:/interface/wx/thread.h diff --git a/interface/wx/thread.h b/interface/wx/thread.h index 3dd874afa0..46296f70d5 100644 --- a/interface/wx/thread.h +++ b/interface/wx/thread.h @@ -214,7 +214,7 @@ public: /** The destructor frees the resources associated with the thread. */ - ~wxThreadHelper(); + virtual ~wxThreadHelper(); /** Creates a new thread. The thread object is created in the suspended state, and @@ -242,7 +242,7 @@ public: This is a public function that returns the wxThread object associated with the thread. */ - wxThread* GetThread(); + wxThread* GetThread() const; /** wxThread * m_thread @@ -250,24 +250,33 @@ public: */ }; +/** + Possible critical section types +*/ +enum wxCriticalSectionType +{ + wxCRITSEC_DEFAULT, + /** Recursive critical section under both Windows and Unix */ + + wxCRITSEC_NON_RECURSIVE + /** Non-recursive critical section under Unix, recursive under Windows */ +}; /** @class wxCriticalSection A critical section object is used for exactly the same purpose as - mutexes(). The only difference is that under Windows platform + a wxMutex. The only difference is that under Windows platform critical sections are only visible inside one process, while mutexes may be shared among processes, so using critical sections is slightly more - efficient. The terminology is also slightly different: mutex may be locked (or - acquired) and unlocked (or released) while critical section is entered and left - by the program. + efficient. The terminology is also slightly different: mutex may be locked + (or acquired) and unlocked (or released) while critical section is entered + and left by the program. - Finally, you should try to use - wxCriticalSectionLocker class whenever + Finally, you should try to use wxCriticalSectionLocker class whenever possible instead of directly using wxCriticalSection for the same reasons - wxMutexLocker is preferrable to - wxMutex - please see wxMutex for an example. + wxMutexLocker is preferrable to wxMutex - please see wxMutex for an example. @library{wxbase} @category{threading} @@ -278,9 +287,10 @@ class wxCriticalSection { public: /** - Default constructor initializes critical section object. + Default constructor initializes critical section object. By default + critical sections are recursive under Unix and Windows. */ - wxCriticalSection(); + wxCriticalSection( wxCriticalSectionType critSecType = wxCRITSEC_DEFAULT ); /** Destructor frees the resources. @@ -301,6 +311,51 @@ public: void Leave(); }; +/** + The possible thread kinds. +*/ +enum wxThreadKind +{ + /** Detached thread */ + wxTHREAD_DETACHED, + + /** Joinable thread */ + wxTHREAD_JOINABLE +}; + +/** + The possible thread errors. +*/ +enum wxThreadError +{ + /** No error */ + wxTHREAD_NO_ERROR = 0, + + /** No resource left to create a new thread. */ + wxTHREAD_NO_RESOURCE, + + /** The thread is already running. */ + wxTHREAD_RUNNING, + + /** The thread isn't running. */ + wxTHREAD_NOT_RUNNING, + + /** Thread we waited for had to be killed. */ + wxTHREAD_KILLED, + + /** Some other error */ + wxTHREAD_MISC_ERROR +}; + +/** + Defines the interval of priority +*/ +enum +{ + WXTHREAD_MIN_PRIORITY = 0u, + WXTHREAD_DEFAULT_PRIORITY = 50u, + WXTHREAD_MAX_PRIORITY = 100u +}; /** @@ -432,7 +487,7 @@ public: will not delete the C++ thread object. It is also safe to allocate them on stack. */ - ~wxThread(); + virtual ~wxThread(); /** Creates a new thread. The thread object is created in the suspended state, @@ -584,7 +639,7 @@ public: @ref Kill() killed. This function should never be called directly. */ - void OnExit(); + virtual void OnExit(); /** Suspends the thread. Under some implementations (Win32), the thread is @@ -693,7 +748,7 @@ public: information. See also Sleep(). */ - void Yield(); + static void Yield(); }; /** @@ -784,8 +839,7 @@ class wxMutexLocker public: /** Constructs a wxMutexLocker object associated with mutex and locks it. - Call @ref IsOk() IsLocked to check if the mutex was - successfully locked. + Call IsOk() to check if the mutex was successfully locked. */ wxMutexLocker(wxMutex& mutex); @@ -801,6 +855,47 @@ public: }; +/** + The possible wxMutex kinds. +*/ +enum wxMutexType +{ + /** Normal non-recursive mutex: try to always use this one. */ + wxMUTEX_DEFAULT, + + /** Recursive mutex: don't use these ones with wxCondition. */ + wxMUTEX_RECURSIVE +}; + + +/** + The possible wxMutex errors. +*/ +enum wxMutexError +{ + /** The operation completed successfully. */ + wxMUTEX_NO_ERROR = 0, + + /** The mutex hasn't been initialized. */ + wxMUTEX_INVALID, + + /** The mutex is already locked by the calling thread. */ + wxMUTEX_DEAD_LOCK, + + /** The mutex is already locked by another thread. */ + wxMUTEX_BUSY, + + /** An attempt to unlock a mutex which is not locked. */ + wxMUTEX_UNLOCKED, + + /** wxMutex::LockTimeout() has timed out. */ + wxMUTEX_TIMEOUT, + + /** Any other error */ + wxMUTEX_MISC_ERROR +}; + + /** @class wxMutex @@ -814,16 +909,58 @@ public: had already locked before (instead of dead locking the entire process in this situation by starting to wait on a mutex which will never be released while the thread is waiting) but using them is not recommended under Unix and they are - @b not recursive there by default. The reason for this is that recursive + @b not recursive by default. The reason for this is that recursive mutexes are not supported by all Unix flavours and, worse, they cannot be used - with wxCondition. On the other hand, Win32 mutexes are - always recursive. + with wxCondition. For example, when several threads use the data stored in the linked list, modifications to the list should only be allowed to one thread at a time because during a new node addition the list integrity is temporarily broken (this is also called @e program invariant). + @code + // this variable has an "s_" prefix because it is static: seeing an "s_" in + // a multithreaded program is in general a good sign that you should use a + // mutex (or a critical section) + static wxMutex *s_mutexProtectingTheGlobalData; + + // we store some numbers in this global array which is presumably used by + // several threads simultaneously + wxArrayInt s_data; + + void MyThread::AddNewNode(int num) + { + // ensure that no other thread accesses the list + s_mutexProtectingTheGlobalList->Lock(); + + s_data.Add(num); + + s_mutexProtectingTheGlobalList->Unlock(); + } + + // return true if the given number is greater than all array elements + bool MyThread::IsGreater(int num) + { + // before using the list we must acquire the mutex + wxMutexLocker lock(s_mutexProtectingTheGlobalData); + + size_t count = s_data.Count(); + for ( size_t n = 0; n < count; n++ ) + { + if ( s_data[n] > num ) + return false; + } + + return true; + } + @endcode + + Notice how wxMutexLocker was used in the second function to ensure that the + mutex is unlocked in any case: whether the function returns true or false + (because the destructor of the local object lock is always called). Using + this class instead of directly using wxMutex is, in general safer and is + even more so if your program uses C++ exceptions. + @library{wxbase} @category{threading} @@ -846,28 +983,28 @@ public: Locks the mutex object. This is equivalent to LockTimeout() with infinite timeout. - @return One of: + @return One of: @c wxMUTEX_NO_ERROR, @c wxMUTEX_DEAD_LOCK. */ wxMutexError Lock(); /** Try to lock the mutex object during the specified time interval. - @return One of: + @return One of: @c wxMUTEX_NO_ERROR, @c wxMUTEX_DEAD_LOCK, @c wxMUTEX_TIMEOUT. */ wxMutexError LockTimeout(unsigned long msec); /** Tries to lock the mutex object. If it can't, returns immediately with an error. - @return One of: + @return One of: @c wxMUTEX_NO_ERROR, @c wxMUTEX_BUSY. */ wxMutexError TryLock(); /** Unlocks the mutex object. - @return One of: + @return One of: @c wxMUTEX_NO_ERROR, @c wxMUTEX_UNLOCKED. */ wxMutexError Unlock(); };