]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/carbon/thread.cpp
Replaced SOCKLEN_T by WX_SOCKLEN_T to resolve conflict with AIX system headers.
[wxWidgets.git] / src / mac / carbon / thread.cpp
index 8aebe3bde2d4302c3ce614ca734d75398d07e660..bbfafd4b38cc8f0dca4637d941f081988ec2fdd1 100644 (file)
@@ -10,7 +10,7 @@
 // Licence:    wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
-#ifdef __GNUG__
+#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
 #pragma implementation "thread.h"
 #endif
 
 #include "wx/thread.h"
 
 #ifdef __WXMAC__
-#if TARGET_API_MAC_OSX
+#ifdef __DARWIN__
 #include <CoreServices/CoreServices.h>
 #else
 #include <DriverServices.h>
 #include <Multiprocessing.h>
-#include <math.h>
+#include "wx/math.h"
 #endif
 #include "wx/mac/uma.h"
 #endif
@@ -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.
     
-    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
-    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 
 */
 
+// ----------------------------------------------------------------------------
+// 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
 // ----------------------------------------------------------------------------
@@ -962,7 +986,7 @@ private:
        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;
@@ -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.
-               // 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);
                
@@ -1147,7 +1171,7 @@ void wxThreadInternal::Wait()
                                 kDurationForever);
             if ( err)
             {
-                wxLogSysError( _( "Cannot wait on thread to exit."));
+                wxLogSysError( _( "Cannot wait for thread termination."));
                 rc = (void*) -1;
             }
 
@@ -1614,7 +1638,7 @@ bool wxThreadModule::OnInit()
        
        verify_noerr( MPAllocateTaskStorageIndex( &gs_tlsForWXThread ) ) ;
        // main thread's This() is NULL
-       verify_noerr( MPSetTaskStorageValue( gs_tlsForWXThread , NULL ) ) ;
+       verify_noerr( MPSetTaskStorageValue( gs_tlsForWXThread , 0 ) ) ;
 
        gs_idMainThread = wxThread::GetCurrentId() ;
        
@@ -1630,6 +1654,11 @@ void wxThreadModule::OnExit()
 {
     if ( gs_critsectGui )
     {
+        if ( !wxGuiOwnedByMainThread() )
+        {
+            gs_critsectGui->Enter();
+            gs_bGuiOwnedByMainThread = true;
+        }
         gs_critsectGui->Leave();
         delete gs_critsectGui;
         gs_critsectGui = NULL;
@@ -1692,6 +1721,9 @@ void WXDLLIMPEXP_BASE wxMutexGuiLeaveOrEnter()
     wxASSERT_MSG( wxThread::IsMain(),
                   wxT("only main thread may call wxMutexGuiLeaveOrEnter()!") );
 
+    if( !gs_critsectWaitingForGui )
+        return;
+        
     wxCriticalSectionLocker enter(*gs_critsectWaitingForGui);
 
     if ( gs_nWaitingForGui == 0 )