]> git.saurik.com Git - wxWidgets.git/blobdiff - include/wx/thread.h
fixedb ug with normalization of UNC paths (patch 558701)
[wxWidgets.git] / include / wx / thread.h
index 016e2ff2b5ab9a7433109c31cd86b23e1bdae0f3..319829ba71f509e6b1ba8f0e805bdd26111370f7 100644 (file)
@@ -80,6 +80,7 @@ enum
 
 // you should consider wxMutexLocker whenever possible instead of directly
 // working with wxMutex class - it is safer
+class WXDLLEXPORT wxConditionInternal;
 class WXDLLEXPORT wxMutexInternal;
 class WXDLLEXPORT wxMutex
 {
@@ -99,14 +100,14 @@ public:
     bool IsLocked() const { return (m_locked > 0); }
 
 protected:
-    friend class wxCondition;
-
     // no assignment operator nor copy ctor
     wxMutex(const wxMutex&);
     wxMutex& operator=(const wxMutex&);
 
     int m_locked;
     wxMutexInternal *m_internal;
+
+    friend class wxConditionInternal;
 };
 
 // a helper class which locks the mutex in the ctor and unlocks it in the dtor:
@@ -116,8 +117,9 @@ class WXDLLEXPORT wxMutexLocker
 {
 public:
     // lock the mutex in the ctor
-    wxMutexLocker(wxMutex& mutex) : m_mutex(mutex)
-        { m_isOk = m_mutex.Lock() == wxMUTEX_NO_ERROR; }
+    wxMutexLocker(wxMutex& mutex)
+        : m_isOk(FALSE), m_mutex(mutex)
+        { m_isOk = ( m_mutex.Lock() == wxMUTEX_NO_ERROR ); }
 
     // returns TRUE if mutex was successfully locked in ctor
     bool IsOk() const
@@ -150,11 +152,11 @@ class WXDLLEXPORT wxCriticalSectionInternal;
 
 // in order to avoid any overhead under platforms where critical sections are
 // just mutexes make all wxCriticalSection class functions inline
-#if !defined(__WXMSW__) && !defined(__WXPM__) && !defined(__WXMAC__)
+#if !defined(__WXMSW__) && !defined(__WXPM__)
     #define WXCRITICAL_INLINE   inline
 
     #define wxCRITSECT_IS_MUTEX 1
-#else // MSW || Mac || OS2
+#else // MSW || OS2
     #define WXCRITICAL_INLINE
 
     #define wxCRITSECT_IS_MUTEX 0
@@ -213,28 +215,55 @@ private:
 };
 
 // ----------------------------------------------------------------------------
-// Condition variable: allows to block the thread execution until something
-// happens (== condition is signaled)
+// wxCondition models a POSIX condition variable which allows one (or more)
+// thread(s) to wait until some condition is fulfilled
 // ----------------------------------------------------------------------------
 
-class wxConditionInternal;
 class WXDLLEXPORT wxCondition
 {
+    DECLARE_NO_COPY_CLASS(wxCondition)
+        
 public:
-    // constructor & destructor
-    wxCondition();
+    // constructor and destructor
+
+    // Each wxCondition object is associated with with a wxMutex object The
+    // mutex object MUST be locked before calling Wait()
+    wxCondition(wxMutex& mutex);
+
+    // dtor is not virtual, don't use this class polymorphically
     ~wxCondition();
 
-    // wait until the condition is signaled
-        // waits indefinitely.
+    // NB: the associated mutex MUST be locked beforehand by the calling thread
+    // 
+    // it atomically releases the lock on the associated mutex
+    // and starts waiting to be woken up by a Signal()/Broadcast()
+    // once its signaled, then it will wait until it can reacquire
+    // the lock on the associated mutex object, before returning.
     void Wait();
-        // waits until a signal is raised or the timeout elapses
-    bool Wait(unsigned long sec, unsigned long nsec);
 
-    // signal the condition
-        // wakes up one (and only one) of the waiting threads
+    // exactly as Wait() except that it may also return if the specified
+    // timeout ellapses even if the condition hasn't been signalled: in this
+    // case, the return value is FALSE, otherwise (i.e. in case of a normal
+    // return) it is TRUE
+    // 
+    // the timeeout parameter specifies a interval that needs to be waited in
+    // milliseconds
+    bool Wait( unsigned long timeout_millis );
+
+    // NB: the associated mutex may or may not be locked by the calling thread
+    //
+    // this method unblocks one thread if any are blocking on the condition.
+    // if no thread is blocking in Wait(), then the signal is NOT remembered
+    // The thread which was blocking on Wait(), will then reacquire the lock
+    // on the associated mutex object before returning
     void Signal();
-        // wakes up all threads waiting onthis condition
+
+    // NB: the associated mutex may or may not be locked by the calling thread
+    //
+    // this method unblocks all threads if any are blocking on the condition.
+    // if no thread is blocking in Wait(), then the signal is NOT remembered
+    // The threads which were blocking on Wait(), will then reacquire the lock
+    // on the associated mutex object before returning.
     void Broadcast();
 
 private:
@@ -242,7 +271,45 @@ private:
 };
 
 // ----------------------------------------------------------------------------
-// Thread class
+// wxSemaphore: a counter limiting the number of threads concurrently accessing
+//              a shared resource
+// ----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxSemaphoreInternal;
+class WXDLLEXPORT wxSemaphore
+{
+    DECLARE_NO_COPY_CLASS(wxSemaphore)
+        
+public:
+    // specifying a maxcount of 0 actually makes wxSemaphore behave as if there
+    // is no upper limit, if maxcount is 1 the semaphore behaves as a mutex
+    wxSemaphore( int initialcount = 0, int maxcount = 0 );
+
+    // dtor is not virtual, don't use this class polymorphically
+    ~wxSemaphore();
+
+    // wait indefinitely, until the semaphore count goes beyond 0
+    // and then decrement it and return (this method might have been called
+    // Acquire())
+    void Wait();
+
+    // same as Wait(), but does not block, returns TRUE if successful and
+    // FALSE if the count is zero
+    bool TryWait();
+
+    // same as Wait(), but as a timeout limit, returns TRUE if the semaphore
+    // was acquired and FALSE if the timeout has ellapsed
+    bool Wait( unsigned long timeout_millis );
+
+    // increments the semaphore count and signals one of the waiting threads
+    void Post();
+
+private:
+    wxSemaphoreInternal *m_internal;
+};
+
+// ----------------------------------------------------------------------------
+// wxThread: class encpasulating a thread of execution
 // ----------------------------------------------------------------------------
 
 // there are two different kinds of threads: joinable and detached (default)
@@ -254,6 +321,13 @@ private:
 //     created by the wxThread object while "main thread" is the thread created
 //     during the process initialization (a.k.a. the GUI thread)
 
+// On VMS thread pointers are 64 bits (also needed for other systems???
+#ifdef __VMS
+   typedef unsigned long long wxThreadIdType;
+#else
+   typedef unsigned long wxThreadIdType;
+#endif
+
 class wxThreadInternal;
 class WXDLLEXPORT wxThread
 {
@@ -280,6 +354,26 @@ public:
         // NB: at least under MSW worker threads can not call ::wxSleep()!
     static void Sleep(unsigned long milliseconds);
 
+        // get the number of system CPUs - useful with SetConcurrency()
+        // (the "best" value for it is usually number of CPUs + 1)
+        //
+        // Returns -1 if unknown, number of CPUs otherwise
+    static int GetCPUCount();
+
+        // Get the platform specific thread ID and return as a long.  This
+        // can be used to uniquely identify threads, even if they are not
+        // wxThreads.  This is used by wxPython.
+   static wxThreadIdType GetCurrentId();
+
+        // sets the concurrency level: this is, roughly, the number of threads
+        // the system tries to schedule to run in parallel. 0 means the
+        // default value (usually acceptable, but may not yield the best
+        // performance for this process)
+        //
+        // Returns TRUE on success, FALSE otherwise (if not implemented, for
+        // example)
+    static bool SetConcurrency(size_t level);
+
     // constructor only creates the C++ thread object and doesn't create (or
     // start) the real thread
     wxThread(wxThreadKind kind = wxTHREAD_DETACHED);
@@ -288,8 +382,11 @@ public:
     // from _another_ thread (typically the thread that created this one, e.g.
     // the main thread), not from the thread itself
 
-        // create a new thread - call Run() to start it
-    wxThreadError Create();
+        // create a new thread and optionally set the stack size on
+        // platforms that support that - call Run() to start it
+        // (special cased for watcom which won't accept 0 default)
+
+    wxThreadError Create(unsigned int stackSize = 0);
 
         // starts execution of the thread - from the moment Run() is called
         // the execution of wxThread::Entry() may start at any moment, caller
@@ -353,7 +450,7 @@ public:
 
     // Get the thread ID - a platform dependent number which uniquely
     // identifies a thread inside a process
-    unsigned long GetId() const;
+    wxThreadIdType GetId() const;
 
     // called when the thread exits - in the context of this thread
     //
@@ -406,6 +503,7 @@ void WXDLLEXPORT wxMutexGuiLeave();
 // having to take them inside "#if wxUSE_THREADS"
 #define wxENTER_CRIT_SECT(cs)   (cs).Enter()
 #define wxLEAVE_CRIT_SECT(cs)   (cs).Leave()
+#define wxCRIT_SECT_DECLARE(cs) static wxCriticalSection cs
 #define wxCRIT_SECT_LOCKER(name, cs)  wxCriticalSectionLocker name(cs)
 
 #else // !wxUSE_THREADS
@@ -420,6 +518,7 @@ inline void WXDLLEXPORT wxMutexGuiLeave() { }
 // having to take them inside "#if wxUSE_THREADS"
 #define wxENTER_CRIT_SECT(cs)
 #define wxLEAVE_CRIT_SECT(cs)
+#define wxCRIT_SECT_DECLARE(cs)
 #define wxCRIT_SECT_LOCKER(name, cs)
 
 #endif // wxUSE_THREADS
@@ -465,6 +564,13 @@ public:
     // return TRUE if the main thread is waiting for some other to terminate:
     // wxApp then should block all "dangerous" messages
     extern bool WXDLLEXPORT wxIsWaitingForThread();
+
+    // implement wxCriticalSection using mutexes
+    inline wxCriticalSection::wxCriticalSection() : m_mutex() { }
+    inline wxCriticalSection::~wxCriticalSection() { }
+
+    inline void wxCriticalSection::Enter() { (void)m_mutex.Lock(); }
+    inline void wxCriticalSection::Leave() { (void)m_mutex.Unlock(); }
 #elif defined(__WXPM__)
     // unlock GUI if there are threads waiting for and lock it back when
     // there are no more of them - should be called periodically by the main
@@ -497,3 +603,4 @@ public:
 #endif // wxUSE_THREADS
 
 #endif // __THREADH__
+