]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/carbon/thread.cpp
Include missing.h to find O_* flags.
[wxWidgets.git] / src / mac / carbon / thread.cpp
index fed5af4d817872ad219722ba3449d47c2f3ca521..6c477b3685b804d0cbf4714b14c731c60d22fa06 100644 (file)
@@ -114,16 +114,40 @@ MPCriticalRegionID gs_guiCritical = kInvalidID;
     to use two indices one for each 32 bit part as the MP implementation is limited
     to longs.
     
     to use two indices one for each 32 bit part as the MP implementation is limited
     to longs.
     
-    I have two implementations for mutexes :
+    I have three implementations for mutexes :
     version A based on a binary semaphore, problem - not reentrant, version B based 
     on a critical region, allows for reentrancy, performance implications not
     version A based on a binary semaphore, problem - not reentrant, version B based 
     on a critical region, allows for reentrancy, performance implications not
-    yet tested
+    yet tested, and third a plain pthreads implementation
 
     The same for condition internal, one implementation by Aj Lavin and the other one
     copied from the thrimpl.cpp which I assume has been more broadly tested, I've just
     replaced the interlock increment with the appropriate PPC calls 
 */
 
 
     The same for condition internal, one implementation by Aj Lavin and the other one
     copied from the thrimpl.cpp which I assume has been more broadly tested, I've just
     replaced the interlock increment with the appropriate PPC calls 
 */
 
+// ----------------------------------------------------------------------------
+// wxCriticalSection
+// ----------------------------------------------------------------------------
+
+wxCriticalSection::wxCriticalSection()
+{
+    MPCreateCriticalRegion( (MPCriticalRegionID*) &m_critRegion ) ;
+}
+
+wxCriticalSection::~wxCriticalSection()
+{
+    MPDeleteCriticalRegion( (MPCriticalRegionID) m_critRegion ) ;
+}
+
+void wxCriticalSection::Enter()
+{
+    MPEnterCriticalRegion( (MPCriticalRegionID) m_critRegion , kDurationForever ) ;
+}    
+
+void wxCriticalSection::Leave()
+{
+    MPExitCriticalRegion((MPCriticalRegionID) m_critRegion ) ;
+}
+
 // ----------------------------------------------------------------------------
 // wxMutex implementation
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 // wxMutex implementation
 // ----------------------------------------------------------------------------
@@ -962,7 +986,7 @@ private:
        MPQueueID           m_notifyQueueId;    // its notification queue
 
     wxThreadState m_state;              // see wxThreadState enum
        MPQueueID           m_notifyQueueId;    // its notification queue
 
     wxThreadState m_state;              // see wxThreadState enum
-    int           m_prio;               // in wxWindows units: from 0 to 100
+    int           m_prio;               // in wxWidgets units: from 0 to 100
 
     // this flag is set when the thread should terminate
     bool m_cancelled;
 
     // this flag is set when the thread should terminate
     bool m_cancelled;
@@ -1092,8 +1116,8 @@ void wxThreadInternal::SetPriority( int priority)
        if ( m_tid)
     {
                // Mac priorities range from 1 to 10,000, with a default of 100.
        if ( m_tid)
     {
                // Mac priorities range from 1 to 10,000, with a default of 100.
-               // wxWindows priorities range from 0 to 100 with a default of 50.
-               // We can map wxWindows to Mac priorities easily by assuming
+               // wxWidgets priorities range from 0 to 100 with a default of 50.
+               // We can map wxWidgets to Mac priorities easily by assuming
                // the former uses a logarithmic scale.
                const unsigned int macPriority = ( int)( exp( priority / 25.0 * log( 10.0)) + 0.5);
                
                // the former uses a logarithmic scale.
                const unsigned int macPriority = ( int)( exp( priority / 25.0 * log( 10.0)) + 0.5);
                
@@ -1121,7 +1145,15 @@ void wxThreadInternal::Wait()
     // if the thread we're waiting for is waiting for the GUI mutex, we will
     // deadlock so make sure we release it temporarily
     if ( wxThread::IsMain() )
     // if the thread we're waiting for is waiting for the GUI mutex, we will
     // deadlock so make sure we release it temporarily
     if ( wxThread::IsMain() )
-        wxMutexGuiLeave();
+    {
+        // give the thread we're waiting for chance to do the GUI call
+        // it might be in, we don't do this conditionally as the to be waited on 
+        // thread might have to acquire the mutex later but before terminating
+        if ( wxGuiOwnedByMainThread() )
+        {
+            wxMutexGuiLeave();
+        }
+    }
 
     {
         wxCriticalSectionLocker lock(m_csJoinFlag);
 
     {
         wxCriticalSectionLocker lock(m_csJoinFlag);
@@ -1150,10 +1182,6 @@ void wxThreadInternal::Wait()
             m_shouldBeJoined = FALSE;
         }
     }
             m_shouldBeJoined = FALSE;
         }
     }
-
-    // reacquire GUI mutex
-    if ( wxThread::IsMain() )
-        wxMutexGuiEnter();
 }
 
 void wxThreadInternal::Pause()
 }
 
 void wxThreadInternal::Pause()
@@ -1197,7 +1225,7 @@ wxThread *wxThread::This()
 
 bool wxThread::IsMain()
 {
 
 bool wxThread::IsMain()
 {
-       return GetCurrentId() == gs_idMainThread || gs_idMainThread == kNoThreadID;
+       return GetCurrentId() == gs_idMainThread || gs_idMainThread == kInvalidID ;
 }
 
 #ifdef Yield
 }
 
 #ifdef Yield
@@ -1408,7 +1436,6 @@ wxThreadError wxThread::Delete(ExitCode *rc)
                     *rc = m_internal->GetExitCode();
                 }
             }
                     *rc = m_internal->GetExitCode();
                 }
             }
-            //else: can't wait for detached threads
     }
 
     return wxTHREAD_NO_ERROR;
     }
 
     return wxTHREAD_NO_ERROR;
@@ -1627,6 +1654,11 @@ void wxThreadModule::OnExit()
 {
     if ( gs_critsectGui )
     {
 {
     if ( gs_critsectGui )
     {
+        if ( !wxGuiOwnedByMainThread() )
+        {
+            gs_critsectGui->Enter();
+            gs_bGuiOwnedByMainThread = true;
+        }
         gs_critsectGui->Leave();
         delete gs_critsectGui;
         gs_critsectGui = NULL;
         gs_critsectGui->Leave();
         delete gs_critsectGui;
         gs_critsectGui = NULL;