1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        wx/thread.h
3 // Purpose:     Thread API
4 // Author:      Guilhem Lavaux
5 // Modified by: Vadim Zeitlin (modifications partly inspired by omnithreads
6 //              package from Olivetti & Oracle Research Laboratory)
7 // Created:     04/13/98
8 // RCS-ID:      $Id: thread.h 66924 2011-02-16 22:58:53Z JS $
9 // Copyright:   (c) Guilhem Lavaux
10 // Licence:     wxWindows licence
11 /////////////////////////////////////////////////////////////////////////////
12 
13 #ifndef _WX_THREAD_H_
14 #define _WX_THREAD_H_
15 
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19 
20 // get the value of wxUSE_THREADS configuration flag
21 #include "wx/defs.h"
22 
23 #if wxUSE_THREADS
24 
25 // Windows headers define it
26 #ifdef Yield
27     #undef Yield
28 #endif
29 
30 // ----------------------------------------------------------------------------
31 // constants
32 // ----------------------------------------------------------------------------
33 
34 enum wxMutexError
35 {
36     wxMUTEX_NO_ERROR = 0,   // operation completed successfully
37     wxMUTEX_INVALID,        // mutex hasn't been initialized
38     wxMUTEX_DEAD_LOCK,      // mutex is already locked by the calling thread
39     wxMUTEX_BUSY,           // mutex is already locked by another thread
40     wxMUTEX_UNLOCKED,       // attempt to unlock a mutex which is not locked
41     wxMUTEX_MISC_ERROR      // any other error
42 };
43 
44 enum wxCondError
45 {
46     wxCOND_NO_ERROR = 0,
47     wxCOND_INVALID,
48     wxCOND_TIMEOUT,         // WaitTimeout() has timed out
49     wxCOND_MISC_ERROR
50 };
51 
52 enum wxSemaError
53 {
54     wxSEMA_NO_ERROR = 0,
55     wxSEMA_INVALID,         // semaphore hasn't been initialized successfully
56     wxSEMA_BUSY,            // returned by TryWait() if Wait() would block
57     wxSEMA_TIMEOUT,         // returned by WaitTimeout()
58     wxSEMA_OVERFLOW,        // Post() would increase counter past the max
59     wxSEMA_MISC_ERROR
60 };
61 
62 enum wxThreadError
63 {
64     wxTHREAD_NO_ERROR = 0,      // No error
65     wxTHREAD_NO_RESOURCE,       // No resource left to create a new thread
66     wxTHREAD_RUNNING,           // The thread is already running
67     wxTHREAD_NOT_RUNNING,       // The thread isn't running
68     wxTHREAD_KILLED,            // Thread we waited for had to be killed
69     wxTHREAD_MISC_ERROR         // Some other error
70 };
71 
72 enum wxThreadKind
73 {
74     wxTHREAD_DETACHED,
75     wxTHREAD_JOINABLE
76 };
77 
78 // defines the interval of priority
79 enum
80 {
81     WXTHREAD_MIN_PRIORITY      = 0u,
82     WXTHREAD_DEFAULT_PRIORITY  = 50u,
83     WXTHREAD_MAX_PRIORITY      = 100u
84 };
85 
86 // There are 2 types of mutexes: normal mutexes and recursive ones. The attempt
87 // to lock a normal mutex by a thread which already owns it results in
88 // undefined behaviour (it always works under Windows, it will almost always
89 // result in a deadlock under Unix). Locking a recursive mutex in such
90 // situation always succeeds and it must be unlocked as many times as it has
91 // been locked.
92 //
93 // However recursive mutexes have several important drawbacks: first, in the
94 // POSIX implementation, they're less efficient. Second, and more importantly,
95 // they CAN NOT BE USED WITH CONDITION VARIABLES under Unix! Using them with
96 // wxCondition will work under Windows and some Unices (notably Linux) but will
97 // deadlock under other Unix versions (e.g. Solaris). As it might be difficult
98 // to ensure that a recursive mutex is not used with wxCondition, it is a good
99 // idea to avoid using recursive mutexes at all. Also, the last problem with
100 // them is that some (older) Unix versions don't support this at all -- which
101 // results in a configure warning when building and a deadlock when using them.
102 enum wxMutexType
103 {
104     // normal mutex: try to always use this one
105     wxMUTEX_DEFAULT,
106 
107     // recursive mutex: don't use these ones with wxCondition
108     wxMUTEX_RECURSIVE
109 };
110 
111 // forward declarations
112 class WXDLLIMPEXP_FWD_BASE wxThreadHelper;
113 class WXDLLIMPEXP_FWD_BASE wxConditionInternal;
114 class WXDLLIMPEXP_FWD_BASE wxMutexInternal;
115 class WXDLLIMPEXP_FWD_BASE wxSemaphoreInternal;
116 class WXDLLIMPEXP_FWD_BASE wxThreadInternal;
117 
118 // ----------------------------------------------------------------------------
119 // A mutex object is a synchronization object whose state is set to signaled
120 // when it is not owned by any thread, and nonsignaled when it is owned. Its
121 // name comes from its usefulness in coordinating mutually-exclusive access to
122 // a shared resource. Only one thread at a time can own a mutex object.
123 // ----------------------------------------------------------------------------
124 
125 // you should consider wxMutexLocker whenever possible instead of directly
126 // working with wxMutex class - it is safer
127 class WXDLLIMPEXP_BASE wxMutex
128 {
129 public:
130     // constructor & destructor
131     // ------------------------
132 
133     // create either default (always safe) or recursive mutex
134     wxMutex(wxMutexType mutexType = wxMUTEX_DEFAULT);
135 
136     // destroys the mutex kernel object
137     ~wxMutex();
138 
139     // test if the mutex has been created successfully
140     bool IsOk() const;
141 
142     // mutex operations
143     // ----------------
144 
145     // Lock the mutex, blocking on it until it is unlocked by the other thread.
146     // The result of locking a mutex already locked by the current thread
147     // depend on the mutex type.
148     //
149     // The caller must call Unlock() later if Lock() returned wxMUTEX_NO_ERROR.
150     wxMutexError Lock();
151 
152     // Try to lock the mutex: if it is currently locked, return immediately
153     // with an error. Otherwise the caller must call Unlock().
154     wxMutexError TryLock();
155 
156     // Unlock the mutex. It is an error to unlock an already unlocked mutex
157     wxMutexError Unlock();
158 
159 protected:
160     wxMutexInternal *m_internal;
161 
162     friend class wxConditionInternal;
163 
164     DECLARE_NO_COPY_CLASS(wxMutex)
165 };
166 
167 // a helper class which locks the mutex in the ctor and unlocks it in the dtor:
168 // this ensures that mutex is always unlocked, even if the function returns or
169 // throws an exception before it reaches the end
170 class WXDLLIMPEXP_BASE wxMutexLocker
171 {
172 public:
173     // lock the mutex in the ctor
wxMutexLocker(wxMutex & mutex)174     wxMutexLocker(wxMutex& mutex)
175         : m_isOk(false), m_mutex(mutex)
176         { m_isOk = ( m_mutex.Lock() == wxMUTEX_NO_ERROR ); }
177 
178     // returns true if mutex was successfully locked in ctor
IsOk()179     bool IsOk() const
180         { return m_isOk; }
181 
182     // unlock the mutex in dtor
~wxMutexLocker()183     ~wxMutexLocker()
184         { if ( IsOk() ) m_mutex.Unlock(); }
185 
186 private:
187     // no assignment operator nor copy ctor
188     wxMutexLocker(const wxMutexLocker&);
189     wxMutexLocker& operator=(const wxMutexLocker&);
190 
191     bool     m_isOk;
192     wxMutex& m_mutex;
193 };
194 
195 // ----------------------------------------------------------------------------
196 // Critical section: this is the same as mutex but is only visible to the
197 // threads of the same process. For the platforms which don't have native
198 // support for critical sections, they're implemented entirely in terms of
199 // mutexes.
200 //
201 // NB: wxCriticalSection object does not allocate any memory in its ctor
202 //     which makes it possible to have static globals of this class
203 // ----------------------------------------------------------------------------
204 
205 // in order to avoid any overhead under platforms where critical sections are
206 // just mutexes make all wxCriticalSection class functions inline
207 #if !defined(__WXMSW__) && !defined(__WXMAC__)
208     #define wxCRITSECT_IS_MUTEX 1
209 
210     #define wxCRITSECT_INLINE inline
211 #else // MSW
212     #define wxCRITSECT_IS_MUTEX 0
213 
214     #define wxCRITSECT_INLINE
215 #endif // MSW/!MSW
216 
217 // you should consider wxCriticalSectionLocker whenever possible instead of
218 // directly working with wxCriticalSection class - it is safer
219 class WXDLLIMPEXP_BASE wxCriticalSection
220 {
221 public:
222     // ctor & dtor
223     wxCRITSECT_INLINE wxCriticalSection();
224     wxCRITSECT_INLINE ~wxCriticalSection();
225 
226     // enter the section (the same as locking a mutex)
227     wxCRITSECT_INLINE void Enter();
228 
229     // leave the critical section (same as unlocking a mutex)
230     wxCRITSECT_INLINE void Leave();
231 
232 private:
233 #if wxCRITSECT_IS_MUTEX
234     wxMutex m_mutex;
235 #elif defined(__WXMSW__)
236     // we can't allocate any memory in the ctor, so use placement new -
237     // unfortunately, we have to hardcode the sizeof() here because we can't
238     // include windows.h from this public header and we also have to use the
239     // union to force the correct (i.e. maximal) alignment
240     //
241     // if CRITICAL_SECTION size changes in Windows, you'll get an assert from
242     // thread.cpp and will need to increase the buffer size
243     //
244     // finally, we need this typedef instead of declaring m_buffer directly
245     // because otherwise the assert mentioned above wouldn't compile with some
246     // compilers (notably CodeWarrior 8)
247 #ifdef __WIN64__
248     typedef char wxCritSectBuffer[40];
249 #else // __WIN32__
250     typedef char wxCritSectBuffer[24];
251 #endif
252     union
253     {
254         unsigned long m_dummy1;
255         void *m_dummy2;
256 
257         wxCritSectBuffer m_buffer;
258     };
259 #elif defined(__WXMAC__)
260     void *m_critRegion ;
261 #endif // Unix&OS2/Win32
262 
263     DECLARE_NO_COPY_CLASS(wxCriticalSection)
264 };
265 
266 #if wxCRITSECT_IS_MUTEX
267     // implement wxCriticalSection using mutexes
wxCriticalSection()268     inline wxCriticalSection::wxCriticalSection() { }
~wxCriticalSection()269     inline wxCriticalSection::~wxCriticalSection() { }
270 
Enter()271     inline void wxCriticalSection::Enter() { (void)m_mutex.Lock(); }
Leave()272     inline void wxCriticalSection::Leave() { (void)m_mutex.Unlock(); }
273 #endif // wxCRITSECT_IS_MUTEX
274 
275 #undef wxCRITSECT_INLINE
276 #undef wxCRITSECT_IS_MUTEX
277 
278 // wxCriticalSectionLocker is the same to critical sections as wxMutexLocker is
279 // to mutexes
280 class WXDLLIMPEXP_BASE wxCriticalSectionLocker
281 {
282 public:
wxCriticalSectionLocker(wxCriticalSection & cs)283     wxCriticalSectionLocker(wxCriticalSection& cs)
284         : m_critsect(cs)
285     {
286         m_critsect.Enter();
287     }
288 
~wxCriticalSectionLocker()289     ~wxCriticalSectionLocker()
290     {
291         m_critsect.Leave();
292     }
293 
294 private:
295     wxCriticalSection& m_critsect;
296 
297     DECLARE_NO_COPY_CLASS(wxCriticalSectionLocker)
298 };
299 
300 // ----------------------------------------------------------------------------
301 // wxCondition models a POSIX condition variable which allows one (or more)
302 // thread(s) to wait until some condition is fulfilled
303 // ----------------------------------------------------------------------------
304 
305 class WXDLLIMPEXP_BASE wxCondition
306 {
307 public:
308     // Each wxCondition object is associated with a (single) wxMutex object.
309     // The mutex object MUST be locked before calling Wait()
310     wxCondition(wxMutex& mutex);
311 
312     // dtor is not virtual, don't use this class polymorphically
313     ~wxCondition();
314 
315     // return true if the condition has been created successfully
316     bool IsOk() const;
317 
318     // NB: the associated mutex MUST be locked beforehand by the calling thread
319     //
320     // it atomically releases the lock on the associated mutex
321     // and starts waiting to be woken up by a Signal()/Broadcast()
322     // once its signaled, then it will wait until it can reacquire
323     // the lock on the associated mutex object, before returning.
324     wxCondError Wait();
325 
326     // exactly as Wait() except that it may also return if the specified
327     // timeout elapses even if the condition hasn't been signalled: in this
328     // case, the return value is false, otherwise (i.e. in case of a normal
329     // return) it is true
330     //
331     // the timeout parameter specifies an interval that needs to be waited for
332     // in milliseconds
333     wxCondError WaitTimeout(unsigned long milliseconds);
334 
335     // NB: the associated mutex may or may not be locked by the calling thread
336     //
337     // this method unblocks one thread if any are blocking on the condition.
338     // if no thread is blocking in Wait(), then the signal is NOT remembered
339     // The thread which was blocking on Wait() will then reacquire the lock
340     // on the associated mutex object before returning
341     wxCondError Signal();
342 
343     // NB: the associated mutex may or may not be locked by the calling thread
344     //
345     // this method unblocks all threads if any are blocking on the condition.
346     // if no thread is blocking in Wait(), then the signal is NOT remembered
347     // The threads which were blocking on Wait() will then reacquire the lock
348     // on the associated mutex object before returning.
349     wxCondError Broadcast();
350 
351 
352 #if WXWIN_COMPATIBILITY_2_6
353     // deprecated version, don't use
354     wxDEPRECATED( bool Wait(unsigned long milliseconds) );
355 #endif // WXWIN_COMPATIBILITY_2_6
356 
357 private:
358     wxConditionInternal *m_internal;
359 
360     DECLARE_NO_COPY_CLASS(wxCondition)
361 };
362 
363 #if WXWIN_COMPATIBILITY_2_6
Wait(unsigned long milliseconds)364     inline bool wxCondition::Wait(unsigned long milliseconds)
365         { return WaitTimeout(milliseconds) == wxCOND_NO_ERROR; }
366 #endif // WXWIN_COMPATIBILITY_2_6
367 
368 // ----------------------------------------------------------------------------
369 // wxSemaphore: a counter limiting the number of threads concurrently accessing
370 //              a shared resource
371 // ----------------------------------------------------------------------------
372 
373 class WXDLLIMPEXP_BASE wxSemaphore
374 {
375 public:
376     // specifying a maxcount of 0 actually makes wxSemaphore behave as if there
377     // is no upper limit, if maxcount is 1 the semaphore behaves as a mutex
378     wxSemaphore( int initialcount = 0, int maxcount = 0 );
379 
380     // dtor is not virtual, don't use this class polymorphically
381     ~wxSemaphore();
382 
383     // return true if the semaphore has been created successfully
384     bool IsOk() const;
385 
386     // wait indefinitely, until the semaphore count goes beyond 0
387     // and then decrement it and return (this method might have been called
388     // Acquire())
389     wxSemaError Wait();
390 
391     // same as Wait(), but does not block, returns wxSEMA_NO_ERROR if
392     // successful and wxSEMA_BUSY if the count is currently zero
393     wxSemaError TryWait();
394 
395     // same as Wait(), but as a timeout limit, returns wxSEMA_NO_ERROR if the
396     // semaphore was acquired and wxSEMA_TIMEOUT if the timeout has elapsed
397     wxSemaError WaitTimeout(unsigned long milliseconds);
398 
399     // increments the semaphore count and signals one of the waiting threads
400     wxSemaError Post();
401 
402 private:
403     wxSemaphoreInternal *m_internal;
404 
405     DECLARE_NO_COPY_CLASS(wxSemaphore)
406 };
407 
408 // ----------------------------------------------------------------------------
409 // wxThread: class encapsulating a thread of execution
410 // ----------------------------------------------------------------------------
411 
412 // there are two different kinds of threads: joinable and detached (default)
413 // ones. Only joinable threads can return a return code and only detached
414 // threads auto-delete themselves - the user should delete the joinable
415 // threads manually.
416 
417 // NB: in the function descriptions the words "this thread" mean the thread
418 //     created by the wxThread object while "main thread" is the thread created
419 //     during the process initialization (a.k.a. the GUI thread)
420 
421 // On VMS thread pointers are 64 bits (also needed for other systems???
422 #ifdef __VMS
423    typedef unsigned long long wxThreadIdType;
424 #else
425    typedef unsigned long wxThreadIdType;
426 #endif
427 
428 class WXDLLIMPEXP_BASE wxThread
429 {
430 public:
431     // the return type for the thread function
432     typedef void *ExitCode;
433 
434     // static functions
435         // Returns the wxThread object for the calling thread. NULL is returned
436         // if the caller is the main thread (but it's recommended to use
437         // IsMain() and only call This() for threads other than the main one
438         // because NULL is also returned on error). If the thread wasn't
439         // created with wxThread class, the returned value is undefined.
440     static wxThread *This();
441 
442         // Returns true if current thread is the main thread.
443     static bool IsMain();
444 
445         // Release the rest of our time slice letting the other threads run
446     static void Yield();
447 
448         // Sleep during the specified period of time in milliseconds
449         //
450         // NB: at least under MSW worker threads can not call ::wxSleep()!
451     static void Sleep(unsigned long milliseconds);
452 
453         // get the number of system CPUs - useful with SetConcurrency()
454         // (the "best" value for it is usually number of CPUs + 1)
455         //
456         // Returns -1 if unknown, number of CPUs otherwise
457     static int GetCPUCount();
458 
459         // Get the platform specific thread ID and return as a long.  This
460         // can be used to uniquely identify threads, even if they are not
461         // wxThreads.  This is used by wxPython.
462    static wxThreadIdType GetCurrentId();
463 
464         // sets the concurrency level: this is, roughly, the number of threads
465         // the system tries to schedule to run in parallel. 0 means the
466         // default value (usually acceptable, but may not yield the best
467         // performance for this process)
468         //
469         // Returns true on success, false otherwise (if not implemented, for
470         // example)
471     static bool SetConcurrency(size_t level);
472 
473     // constructor only creates the C++ thread object and doesn't create (or
474     // start) the real thread
475     wxThread(wxThreadKind kind = wxTHREAD_DETACHED);
476 
477     // functions that change the thread state: all these can only be called
478     // from _another_ thread (typically the thread that created this one, e.g.
479     // the main thread), not from the thread itself
480 
481         // create a new thread and optionally set the stack size on
482         // platforms that support that - call Run() to start it
483         // (special cased for watcom which won't accept 0 default)
484 
485     wxThreadError Create(unsigned int stackSize = 0);
486 
487         // starts execution of the thread - from the moment Run() is called
488         // the execution of wxThread::Entry() may start at any moment, caller
489         // shouldn't suppose that it starts after (or before) Run() returns.
490     wxThreadError Run();
491 
492         // stops the thread if it's running and deletes the wxThread object if
493         // this is a detached thread freeing its memory - otherwise (for
494         // joinable threads) you still need to delete wxThread object
495         // yourself.
496         //
497         // this function only works if the thread calls TestDestroy()
498         // periodically - the thread will only be deleted the next time it
499         // does it!
500         //
501         // will fill the rc pointer with the thread exit code if it's !NULL
502     wxThreadError Delete(ExitCode *rc = (ExitCode *)NULL);
503 
504         // waits for a joinable thread to finish and returns its exit code
505         //
506         // Returns (ExitCode)-1 on error (for example, if the thread is not
507         // joinable)
508     ExitCode Wait();
509 
510         // kills the thread without giving it any chance to clean up - should
511         // not be used under normal circumstances, use Delete() instead.
512         // It is a dangerous function that should only be used in the most
513         // extreme cases!
514         //
515         // The wxThread object is deleted by Kill() if the thread is
516         // detachable, but you still have to delete it manually for joinable
517         // threads.
518     wxThreadError Kill();
519 
520         // pause a running thread: as Delete(), this only works if the thread
521         // calls TestDestroy() regularly
522     wxThreadError Pause();
523 
524         // resume a paused thread
525     wxThreadError Resume();
526 
527     // priority
528         // Sets the priority to "prio": see WXTHREAD_XXX_PRIORITY constants
529         //
530         // NB: the priority can only be set before the thread is created
531     void SetPriority(unsigned int prio);
532 
533         // Get the current priority.
534     unsigned int GetPriority() const;
535 
536     // thread status inquiries
537         // Returns true if the thread is alive: i.e. running or suspended
538     bool IsAlive() const;
539         // Returns true if the thread is running (not paused, not killed).
540     bool IsRunning() const;
541         // Returns true if the thread is suspended
542     bool IsPaused() const;
543 
544         // is the thread of detached kind?
IsDetached()545     bool IsDetached() const { return m_isDetached; }
546 
547     // Get the thread ID - a platform dependent number which uniquely
548     // identifies a thread inside a process
549     wxThreadIdType GetId() const;
550 
551     // called when the thread exits - in the context of this thread
552     //
553     // NB: this function will not be called if the thread is Kill()ed
OnExit()554     virtual void OnExit() { }
555 
556     // Returns true if the thread was asked to terminate: this function should
557     // be called by the thread from time to time, otherwise the main thread
558     // will be left forever in Delete()!
559     virtual bool TestDestroy();
560 
561     // dtor is public, but the detached threads should never be deleted - use
562     // Delete() instead (or leave the thread terminate by itself)
563     virtual ~wxThread();
564 
565 protected:
566     // exits from the current thread - can be called only from this thread
567     void Exit(ExitCode exitcode = 0);
568 
569     // entry point for the thread - called by Run() and executes in the context
570     // of this thread.
571     virtual void *Entry() = 0;
572 
573 private:
574     // no copy ctor/assignment operator
575     wxThread(const wxThread&);
576     wxThread& operator=(const wxThread&);
577 
578     friend class wxThreadInternal;
579 
580     // the (platform-dependent) thread class implementation
581     wxThreadInternal *m_internal;
582 
583     // protects access to any methods of wxThreadInternal object
584     wxCriticalSection m_critsect;
585 
586     // true if the thread is detached, false if it is joinable
587     bool m_isDetached;
588 };
589 
590 // wxThreadHelperThread class
591 // --------------------------
592 
593 class WXDLLIMPEXP_BASE wxThreadHelperThread : public wxThread
594 {
595 public:
596     // constructor only creates the C++ thread object and doesn't create (or
597     // start) the real thread
wxThreadHelperThread(wxThreadHelper & owner)598     wxThreadHelperThread(wxThreadHelper& owner)
599         : wxThread(wxTHREAD_JOINABLE), m_owner(owner)
600         { }
601 
602 protected:
603     // entry point for the thread -- calls Entry() in owner.
604     virtual void *Entry();
605 
606 private:
607     // the owner of the thread
608     wxThreadHelper& m_owner;
609 
610     // no copy ctor/assignment operator
611     wxThreadHelperThread(const wxThreadHelperThread&);
612     wxThreadHelperThread& operator=(const wxThreadHelperThread&);
613 };
614 
615 // ----------------------------------------------------------------------------
616 // wxThreadHelper: this class implements the threading logic to run a
617 // background task in another object (such as a window).  It is a mix-in: just
618 // derive from it to implement a threading background task in your class.
619 // ----------------------------------------------------------------------------
620 
621 class WXDLLIMPEXP_BASE wxThreadHelper
622 {
623 private:
KillThread()624     void KillThread()
625     {
626         if ( m_thread )
627         {
628             m_thread->Kill();
629             delete m_thread;
630         }
631     }
632 
633 public:
634     // constructor only initializes m_thread to NULL
wxThreadHelper()635     wxThreadHelper() : m_thread(NULL) { }
636 
637     // destructor deletes m_thread
~wxThreadHelper()638     virtual ~wxThreadHelper() { KillThread(); }
639 
640     // create a new thread (and optionally set the stack size on platforms that
641     // support/need that), call Run() to start it
642     wxThreadError Create(unsigned int stackSize = 0)
643     {
644         KillThread();
645 
646         m_thread = new wxThreadHelperThread(*this);
647 
648         return m_thread->Create(stackSize);
649     }
650 
651     // entry point for the thread - called by Run() and executes in the context
652     // of this thread.
653     virtual void *Entry() = 0;
654 
655     // returns a pointer to the thread which can be used to call Run()
GetThread()656     wxThread *GetThread() const { return m_thread; }
657 
658 protected:
659     wxThread *m_thread;
660 };
661 
662 // call Entry() in owner, put it down here to avoid circular declarations
Entry()663 inline void *wxThreadHelperThread::Entry()
664 {
665     return m_owner.Entry();
666 }
667 
668 // ----------------------------------------------------------------------------
669 // Automatic initialization
670 // ----------------------------------------------------------------------------
671 
672 // GUI mutex handling.
673 void WXDLLIMPEXP_BASE wxMutexGuiEnter();
674 void WXDLLIMPEXP_BASE wxMutexGuiLeave();
675 
676 // macros for entering/leaving critical sections which may be used without
677 // having to take them inside "#if wxUSE_THREADS"
678 #define wxENTER_CRIT_SECT(cs)   (cs).Enter()
679 #define wxLEAVE_CRIT_SECT(cs)   (cs).Leave()
680 #define wxCRIT_SECT_DECLARE(cs) static wxCriticalSection cs
681 #define wxCRIT_SECT_DECLARE_MEMBER(cs) wxCriticalSection cs
682 #define wxCRIT_SECT_LOCKER(name, cs)  wxCriticalSectionLocker name(cs)
683 
684 // function for checking if we're in the main thread which may be used whether
685 // wxUSE_THREADS is 0 or 1
wxIsMainThread()686 inline bool wxIsMainThread() { return wxThread::IsMain(); }
687 
688 #else // !wxUSE_THREADS
689 
690 // no thread support
wxMutexGuiEnter()691 inline void WXDLLIMPEXP_BASE wxMutexGuiEnter() { }
wxMutexGuiLeave()692 inline void WXDLLIMPEXP_BASE wxMutexGuiLeave() { }
693 
694 // macros for entering/leaving critical sections which may be used without
695 // having to take them inside "#if wxUSE_THREADS"
696 // (the implementation uses dummy structs to force semicolon after the macro;
697 // also notice that Watcom doesn't like declaring a struct as a member so we
698 // need to actually define it in wxCRIT_SECT_DECLARE_MEMBER)
699 #define wxENTER_CRIT_SECT(cs)            do {} while (0)
700 #define wxLEAVE_CRIT_SECT(cs)            do {} while (0)
701 #define wxCRIT_SECT_DECLARE(cs)          struct wxDummyCS##cs
702 #define wxCRIT_SECT_DECLARE_MEMBER(cs)   struct wxDummyCSMember##cs { }
703 #define wxCRIT_SECT_LOCKER(name, cs)     struct wxDummyCSLocker##name
704 
705 // if there is only one thread, it is always the main one
wxIsMainThread()706 inline bool wxIsMainThread() { return true; }
707 
708 #endif // wxUSE_THREADS/!wxUSE_THREADS
709 
710 // mark part of code as being a critical section: this macro declares a
711 // critical section with the given name and enters it immediately and leaves
712 // it at the end of the current scope
713 //
714 // example:
715 //
716 //      int Count()
717 //      {
718 //          static int s_counter = 0;
719 //
720 //          wxCRITICAL_SECTION(counter);
721 //
722 //          return ++s_counter;
723 //      }
724 //
725 // this function is MT-safe in presence of the threads but there is no
726 // overhead when the library is compiled without threads
727 #define wxCRITICAL_SECTION(name) \
728     wxCRIT_SECT_DECLARE(s_cs##name);  \
729     wxCRIT_SECT_LOCKER(cs##name##Locker, s_cs##name)
730 
731 // automatically lock GUI mutex in ctor and unlock it in dtor
732 class WXDLLIMPEXP_BASE wxMutexGuiLocker
733 {
734 public:
wxMutexGuiLocker()735     wxMutexGuiLocker() { wxMutexGuiEnter(); }
~wxMutexGuiLocker()736    ~wxMutexGuiLocker() { wxMutexGuiLeave(); }
737 };
738 
739 // -----------------------------------------------------------------------------
740 // implementation only until the end of file
741 // -----------------------------------------------------------------------------
742 
743 #if wxUSE_THREADS
744 
745 #if defined(__WXMSW__) || defined(__WXMAC__) || defined(__OS2__) || defined(__EMX__)
746     // unlock GUI if there are threads waiting for and lock it back when
747     // there are no more of them - should be called periodically by the main
748     // thread
749     extern void WXDLLIMPEXP_BASE wxMutexGuiLeaveOrEnter();
750 
751     // returns true if the main thread has GUI lock
752     extern bool WXDLLIMPEXP_BASE wxGuiOwnedByMainThread();
753 
754     // wakes up the main thread if it's sleeping inside ::GetMessage()
755     extern void WXDLLIMPEXP_BASE wxWakeUpMainThread();
756 
757     // return true if the main thread is waiting for some other to terminate:
758     // wxApp then should block all "dangerous" messages
759     extern bool WXDLLIMPEXP_BASE wxIsWaitingForThread();
760 #endif // MSW, Mac, OS/2
761 
762 #endif // wxUSE_THREADS
763 
764 #endif // _WX_THREAD_H_
765