/**
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
This is a public function that returns the wxThread object
associated with the thread.
*/
- wxThread* GetThread();
+ wxThread* GetThread() const;
/**
wxThread * m_thread
*/
};
+/**
+ 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}
{
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.
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
+};
/**
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,
@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
information.
See also Sleep().
*/
- void Yield();
+ static void Yield();
};
/**
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);
};
+/**
+ 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
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}
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();
};