]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/carbon/thread.cpp
added MacOpenURL() (patch 1235957)
[wxWidgets.git] / src / mac / carbon / thread.cpp
index fed5af4d817872ad219722ba3449d47c2f3ca521..cacf2e5e35a0d7fe168da6e4f49c278319ed1cbd 100644 (file)
@@ -1,77 +1,64 @@
 /////////////////////////////////////////////////////////////////////////////
-// Name:       thread.cpp
-// Purpose:    wxThread Implementation
-// Author:     Original from Wolfram Gloger/Guilhem Lavaux/Vadim Zeitlin
+// Name:        src/mac/carbon/thread.cpp
+// Purpose:     wxThread Implementation
+// Author:      Original from Wolfram Gloger/Guilhem Lavaux/Vadim Zeitlin
 // Modified by: Aj Lavin, Stefan Csomor
-// Created:    04/22/98
-// RCS-ID:     $Id$
-// Copyright:  (c) Wolfram Gloger (1996, 1997); Guilhem Lavaux (1998),
-//                 Vadim Zeitlin (1999) , Stefan Csomor (2000)
-// Licence:    wxWindows licence
+// Created:     04/22/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Wolfram Gloger (1996, 1997); Guilhem Lavaux (1998),
+//                  Vadim Zeitlin (1999), Stefan Csomor (2000)
+// Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
-#ifdef __GNUG__
-#pragma implementation "thread.h"
-#endif
-
-// ----------------------------------------------------------------------------
-// headers
-// ----------------------------------------------------------------------------
-
-// For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
 #if defined(__BORLANDC__)
-#pragma hdrstop
+    #pragma hdrstop
 #endif
 
 #ifndef WX_PRECOMP
-#include "wx/wx.h"
+    #include "wx/wx.h"
+    #include "wx/module.h"
 #endif
 
 #if wxUSE_THREADS
 
-#include "wx/module.h"
 #include "wx/thread.h"
 
 #ifdef __WXMAC__
-#if TARGET_API_MAC_OSX
-#include <CoreServices/CoreServices.h>
+#ifdef __DARWIN__
+    #include <CoreServices/CoreServices.h>
 #else
-#include <DriverServices.h>
-#include <Multiprocessing.h>
-#include <math.h>
+    #include <DriverServices.h>
+    #include <Multiprocessing.h>
 #endif
+
 #include "wx/mac/uma.h"
 #endif
 
 #include "wx/mac/macnotfy.h"
 
-// ----------------------------------------------------------------------------
-// constants
-// ----------------------------------------------------------------------------
 
-// the possible states of the thread ("=>" shows all possible transitions from
-// this state)
+// the possible states of the thread:
+// ("=>" shows all possible transitions from this state)
 enum wxThreadState
 {
-       STATE_NEW,              // didn't start execution yet (=> RUNNING)
-       STATE_RUNNING,  // thread is running (=> PAUSED, CANCELED)
-       STATE_PAUSED,   // thread is temporarily suspended (=> RUNNING)
-       STATE_CANCELED, // thread should terminate a.s.a.p. (=> EXITED)
-       STATE_EXITED    // thread is terminating
+    STATE_NEW, // didn't start execution yet (=> RUNNING)
+    STATE_RUNNING, // thread is running (=> PAUSED, CANCELED)
+    STATE_PAUSED, // thread is temporarily suspended (=> RUNNING)
+    STATE_CANCELED, // thread should terminate a.s.a.p. (=> EXITED)
+    STATE_EXITED // thread is terminating
 };
 
 // ----------------------------------------------------------------------------
-// this module globals
+// globals
 // ----------------------------------------------------------------------------
 
-
 // the task ID of the main thread
 static wxThreadIdType gs_idMainThread = kInvalidID;
 
 // this is the Per-Task Storage for the pointer to the appropriate wxThread
-TaskStorageIndex gs_tlsForWXThread = 0 ;
+TaskStorageIndex gs_tlsForWXThread = 0;
 
 // if it's false, some secondary thread is holding the GUI lock
 static bool gs_bGuiOwnedByMainThread = true;
@@ -87,16 +74,13 @@ static wxCriticalSection *gs_critsectWaitingForGui = NULL;
 // number of threads waiting for GUI in wxMutexGuiEnter()
 static size_t gs_nWaitingForGui = 0;
 
-// overall number of threads, needed for determining the sleep value of the main 
-// event loop
+// overall number of threads, needed for determining
+// the sleep value of the main event loop
 size_t g_numberOfThreads = 0;
 
 
-
 #if wxUSE_GUI
-
 MPCriticalRegionID gs_guiCritical = kInvalidID;
-
 #endif
 
 // ============================================================================
@@ -105,25 +89,49 @@ MPCriticalRegionID gs_guiCritical = kInvalidID;
 
 /*
     Notes :
-    
+
     The implementation is very close to the phtreads implementation, the reason for
     using MPServices is the fact that these are also available under OS 9. Thus allowing
     for one common API for all current builds.
-    
+
     As soon as wxThreads are on a 64 bit address space, the TLS must be extended
     to use two indices one for each 32 bit part as the MP implementation is limited
     to longs.
-    
-    I have two implementations for mutexes :
-    version A based on a binary semaphore, problem - not reentrant, version B based 
+
+    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 
+    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
 // ----------------------------------------------------------------------------
@@ -138,21 +146,23 @@ MPCriticalRegionID gs_guiCritical = kInvalidID;
 #define wxUSE_MAC_PTHREADS_MUTEX 0
 #endif
 
-#if wxUSE_MAC_PTHREADS_MUTEX 
+#if wxUSE_MAC_PTHREADS_MUTEX
 
 #include <pthread.h>
 
+
 class wxMutexInternal
 {
 public:
-    wxMutexInternal(wxMutexType mutexType);
+    wxMutexInternal( wxMutexType mutexType );
     ~wxMutexInternal();
 
     wxMutexError Lock();
     wxMutexError TryLock();
     wxMutexError Unlock();
 
-    bool IsOk() const { return m_isOk; }
+    bool IsOk() const
+    { return m_isOk; }
 
 private:
     pthread_mutex_t m_mutex;
@@ -165,10 +175,10 @@ private:
 #ifdef HAVE_PTHREAD_MUTEXATTR_T
 // on some systems pthread_mutexattr_settype() is not in the headers (but it is
 // in the library, otherwise we wouldn't compile this code at all)
-extern "C" int pthread_mutexattr_settype(pthread_mutexattr_t *, int);
+extern "C" int pthread_mutexattr_settype( pthread_mutexattr_t *, int );
 #endif
 
-wxMutexInternal::wxMutexInternal(wxMutexType mutexType)
+wxMutexInternal::wxMutexInternal( wxMutexType mutexType )
 {
     int err;
     switch ( mutexType )
@@ -182,10 +192,10 @@ wxMutexInternal::wxMutexInternal(wxMutexType mutexType)
 #ifdef HAVE_PTHREAD_MUTEXATTR_T
             {
                 pthread_mutexattr_t attr;
-                pthread_mutexattr_init(&attr);
-                pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+                pthread_mutexattr_init( &attr );
+                pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_RECURSIVE );
 
-                err = pthread_mutex_init(&m_mutex, &attr);
+                err = pthread_mutex_init( &m_mutex, &attr );
             }
 #elif defined(HAVE_PTHREAD_RECURSIVE_MUTEX_INITIALIZER)
             // we can use this only as initializer so we have to assign it
@@ -201,18 +211,18 @@ wxMutexInternal::wxMutexInternal(wxMutexType mutexType)
             break;
 
         default:
-            wxFAIL_MSG( _T("unknown mutex type") );
+            wxFAIL_MSG( wxT("unknown mutex type") );
             // fall through
 
         case wxMUTEX_DEFAULT:
-            err = pthread_mutex_init(&m_mutex, NULL);
+            err = pthread_mutex_init( &m_mutex, NULL );
             break;
     }
 
     m_isOk = err == 0;
     if ( !m_isOk )
     {
-        wxLogApiError( wxT("pthread_mutex_init()"), err);
+        wxLogApiError( wxT("pthread_mutex_init()"), err );
     }
 }
 
@@ -220,34 +230,34 @@ wxMutexInternal::~wxMutexInternal()
 {
     if ( m_isOk )
     {
-        int err = pthread_mutex_destroy(&m_mutex);
+        int err = pthread_mutex_destroy( &m_mutex );
         if ( err != 0 )
         {
-            wxLogApiError( wxT("pthread_mutex_destroy()"), err);
+            wxLogApiError( wxT("pthread_mutex_destroy()"), err );
         }
     }
 }
 
 wxMutexError wxMutexInternal::Lock()
 {
-    int err = pthread_mutex_lock(&m_mutex);
+    int err = pthread_mutex_lock( &m_mutex );
     switch ( err )
     {
         case EDEADLK:
             // only error checking mutexes return this value and so it's an
             // unexpected situation -- hence use assert, not wxLogDebug
-            wxFAIL_MSG( _T("mutex deadlock prevented") );
+            wxFAIL_MSG( wxT("mutex deadlock prevented") );
             return wxMUTEX_DEAD_LOCK;
 
         case EINVAL:
-            wxLogDebug(_T("pthread_mutex_lock(): mutex not initialized."));
+            wxLogDebug( wxT("pthread_mutex_lock(): mutex not initialized.") );
             break;
 
         case 0:
             return wxMUTEX_NO_ERROR;
 
         default:
-            wxLogApiError(_T("pthread_mutex_lock()"), err);
+            wxLogApiError( wxT("pthread_mutex_lock()"), err );
     }
 
     return wxMUTEX_MISC_ERROR;
@@ -255,23 +265,22 @@ wxMutexError wxMutexInternal::Lock()
 
 wxMutexError wxMutexInternal::TryLock()
 {
-    int err = pthread_mutex_trylock(&m_mutex);
+    int err = pthread_mutex_trylock( &m_mutex );
     switch ( err )
     {
         case EBUSY:
-            // not an error: mutex is already locked, but we're prepared for
-            // this
+            // not an error: mutex is already locked, but we're prepared for this case
             return wxMUTEX_BUSY;
 
         case EINVAL:
-            wxLogDebug(_T("pthread_mutex_trylock(): mutex not initialized."));
+            wxLogDebug( wxT("pthread_mutex_trylock(): mutex not initialized.") );
             break;
 
         case 0:
             return wxMUTEX_NO_ERROR;
 
         default:
-            wxLogApiError(_T("pthread_mutex_trylock()"), err);
+            wxLogApiError( wxT("pthread_mutex_trylock()"), err );
     }
 
     return wxMUTEX_MISC_ERROR;
@@ -279,7 +288,7 @@ wxMutexError wxMutexInternal::TryLock()
 
 wxMutexError wxMutexInternal::Unlock()
 {
-    int err = pthread_mutex_unlock(&m_mutex);
+    int err = pthread_mutex_unlock( &m_mutex );
     switch ( err )
     {
         case EPERM:
@@ -287,110 +296,116 @@ wxMutexError wxMutexInternal::Unlock()
             return wxMUTEX_UNLOCKED;
 
         case EINVAL:
-            wxLogDebug(_T("pthread_mutex_unlock(): mutex not initialized."));
+            wxLogDebug( wxT("pthread_mutex_unlock(): mutex not initialized.") );
             break;
 
         case 0:
             return wxMUTEX_NO_ERROR;
 
         default:
-            wxLogApiError(_T("pthread_mutex_unlock()"), err);
+            wxLogApiError( wxT("pthread_mutex_unlock()"), err );
     }
 
     return wxMUTEX_MISC_ERROR;
 }
 
-
 #endif
 
-#if wxUSE_MAC_SEMAPHORE_MUTEX 
+#if wxUSE_MAC_SEMAPHORE_MUTEX
 
 class wxMutexInternal
 {
 public:
-       wxMutexInternal(wxMutexType mutexType) ;
-       ~wxMutexInternal() ;
-       bool IsOk() const { return m_isOk; }
-       
-       wxMutexError Lock() ;
-       wxMutexError TryLock() ;
-       wxMutexError Unlock();
-private:               
+    wxMutexInternal( wxMutexType mutexType );
+    virtual ~wxMutexInternal();
+
+    bool IsOk() const
+    { return m_isOk; }
+
+    wxMutexError Lock();
+    wxMutexError TryLock();
+    wxMutexError Unlock();
+
+private:
     MPSemaphoreID m_semaphore;
-    bool m_isOk ;
+    bool m_isOk;
 };
 
 wxMutexInternal::wxMutexInternal(wxMutexType mutexType )
 {
-    m_isOk = false ;
-    m_semaphore = kInvalidID ;
-    
-    OSStatus err = noErr ;
-    switch( mutexType )
+    m_isOk = false;
+    m_semaphore = kInvalidID;
+    OSStatus err = noErr;
+
+    switch ( mutexType )
     {
         case wxMUTEX_DEFAULT :
-            {
-               verify_noerr( MPCreateBinarySemaphore( & m_semaphore) );
-                m_isOk = ( m_semaphore != kInvalidID ) ;
-            }
-            break ;
+            verify_noerr( MPCreateBinarySemaphore( &m_semaphore ) );
+            m_isOk = ( m_semaphore != kInvalidID );
+            break;
+
         case wxMUTEX_RECURSIVE :
-            wxFAIL_MSG(wxT("Recursive Mutex not supported yet") ) ;
-            break ;
+            wxFAIL_MSG( wxT("Recursive Mutex not supported yet") );
+            break;
+
         default :
-            wxFAIL_MSG(wxT("Unknown mutex type") ) ;
-            break ;
+            wxFAIL_MSG( wxT("Unknown mutex type") );
+            break;
     }
 }
 
 wxMutexInternal::~wxMutexInternal()
 {
     if ( m_semaphore != kInvalidID )
-           MPDeleteSemaphore( m_semaphore);
-       MPYield() ;
+        MPDeleteSemaphore( m_semaphore );
+
+    MPYield();
 }
 
 wxMutexError wxMutexInternal::Lock()
 {
-    wxCHECK_MSG( m_isOk , wxMUTEX_MISC_ERROR , wxT("Invalid Mutex") ) ;
-       OSStatus err = MPWaitOnSemaphore( m_semaphore, kDurationForever);
-       if ( err)
+    wxCHECK_MSG( m_isOk, wxMUTEX_MISC_ERROR, wxT("Invalid Mutex") );
+    OSStatus err = MPWaitOnSemaphore( m_semaphore, kDurationForever );
+    if (err != noErr)
     {
-               wxLogSysError(wxT("Could not lock mutex"));
-               return wxMUTEX_MISC_ERROR;
+        wxLogSysError( wxT("Could not lock mutex") );
+
+        return wxMUTEX_MISC_ERROR;
     }
-    
-       return wxMUTEX_NO_ERROR;
+
+    return wxMUTEX_NO_ERROR;
 }
 
 wxMutexError wxMutexInternal::TryLock()
 {
-    wxCHECK_MSG( m_isOk , wxMUTEX_MISC_ERROR , wxT("Invalid Mutex") ) ;
-       OSStatus err = MPWaitOnSemaphore( m_semaphore, kDurationImmediate);
-       if ( err)
+    wxCHECK_MSG( m_isOk, wxMUTEX_MISC_ERROR, wxT("Invalid Mutex") );
+    OSStatus err = MPWaitOnSemaphore( m_semaphore, kDurationImmediate );
+    if (err != noErr)
     {
-               if ( err == kMPTimeoutErr)
-               {
-                       return wxMUTEX_BUSY;
-               }
-               wxLogSysError(wxT("Could not try lock mutex"));
-               return wxMUTEX_MISC_ERROR;    
+        if (err == kMPTimeoutErr)
+            return wxMUTEX_BUSY;
+
+        wxLogSysError( wxT("Could not try lock mutex") );
+
+        return wxMUTEX_MISC_ERROR;
     }
-    
-       return wxMUTEX_NO_ERROR;
+
+    return wxMUTEX_NO_ERROR;
 }
 
 wxMutexError wxMutexInternal::Unlock()
 {
-    wxCHECK_MSG( m_isOk , wxMUTEX_MISC_ERROR , wxT("Invalid Mutex") ) ;
-       OSStatus err = MPSignalSemaphore( m_semaphore);
-       MPYield() ;
-       if ( err)
+    wxCHECK_MSG( m_isOk, wxMUTEX_MISC_ERROR, wxT("Invalid Mutex") );
+    OSStatus err = MPSignalSemaphore( m_semaphore );
+
+    MPYield();
+    if (err != noErr)
     {
-               wxLogSysError(_("Could not unlock mutex"));
-               return wxMUTEX_MISC_ERROR;        
+        wxLogSysError( wxT("Could not unlock mutex") );
+        return wxMUTEX_MISC_ERROR;
     }
-       return wxMUTEX_NO_ERROR;
+
+    return wxMUTEX_NO_ERROR;
 }
 
 #endif
@@ -400,79 +415,96 @@ wxMutexError wxMutexInternal::Unlock()
 class wxMutexInternal
 {
 public:
-       wxMutexInternal(wxMutexType mutexType) ;
-       ~wxMutexInternal() ;
-       bool IsOk() const { return m_isOk; }
-       
-       wxMutexError Lock() ;
-       wxMutexError TryLock() ;
-       wxMutexError Unlock();
-private:               
-    MPCriticalRegionID m_critRegion ;
+    wxMutexInternal( wxMutexType mutexType );
+    virtual ~wxMutexInternal();
+
+    bool IsOk() const { return m_isOk; }
+
+    wxMutexError Lock() { return Lock(kDurationForever); }
+    wxMutexError Lock(unsigned long ms);
+    wxMutexError TryLock();
+    wxMutexError Unlock();
+
+private:
+    MPCriticalRegionID m_critRegion;
     bool m_isOk ;
 };
 
-wxMutexInternal::wxMutexInternal(wxMutexType mutexType )
+wxMutexInternal::wxMutexInternal( wxMutexType mutexType )
 {
-    m_isOk = false ;
-    m_critRegion = kInvalidID ;
-    
-    verify_noerr( MPCreateCriticalRegion( & m_critRegion) );
-    m_isOk = ( m_critRegion != kInvalidID ) ;
-    
+    m_isOk = false;
+    m_critRegion = kInvalidID;
+
+    verify_noerr( MPCreateCriticalRegion( &m_critRegion ) );
+    m_isOk = ( m_critRegion != kInvalidID );
     if ( !IsOk() )
-        wxFAIL_MSG(wxT("Error when creating mutex") ) ;
+    {
+        wxFAIL_MSG( wxT("Error when creating mutex") );
+    }
 }
 
 wxMutexInternal::~wxMutexInternal()
 {
     if ( m_critRegion != kInvalidID )
-           MPDeleteCriticalRegion( m_critRegion);
-       MPYield() ;
+        MPDeleteCriticalRegion( m_critRegion );
+
+    MPYield();
 }
 
-wxMutexError wxMutexInternal::Lock()
+wxMutexError wxMutexInternal::Lock(unsigned long ms)
 {
-    wxCHECK_MSG( m_isOk , wxMUTEX_MISC_ERROR , wxT("Invalid Mutex") ) ;
-       OSStatus err = MPEnterCriticalRegion( m_critRegion, kDurationForever);
-       if ( err)
+    wxCHECK_MSG( m_isOk , wxMUTEX_MISC_ERROR , wxT("Invalid Mutex") );
+
+    OSStatus err = MPEnterCriticalRegion( m_critRegion, ms );
+    switch ( err )
     {
-               wxLogSysError(wxT("Could not lock mutex"));
-               return wxMUTEX_MISC_ERROR;
+        case noErr:
+            break;
+
+        case kMPTimeoutErr:
+            wxASSERT_MSG( ms != kDurationForever, wxT("unexpected timeout") );
+            return wxMUTEX_TIMEOUT;
+
+        default:
+            wxLogSysError(wxT("Could not lock mutex"));
+            return wxMUTEX_MISC_ERROR;
     }
-    
-       return wxMUTEX_NO_ERROR;
+
+    return wxMUTEX_NO_ERROR;
 }
 
 wxMutexError wxMutexInternal::TryLock()
 {
     wxCHECK_MSG( m_isOk , wxMUTEX_MISC_ERROR , wxT("Invalid Mutex") ) ;
-       OSStatus err = MPEnterCriticalRegion( m_critRegion, kDurationImmediate);
-       if ( err)
+
+    OSStatus err = MPEnterCriticalRegion( m_critRegion, kDurationImmediate);
+    if (err != noErr)
     {
-               if ( err == kMPTimeoutErr)
-               {
-                       return wxMUTEX_BUSY;
-               }
-               wxLogSysError(wxT("Could not try lock mutex"));
-               return wxMUTEX_MISC_ERROR;    
+        if ( err == kMPTimeoutErr)
+            return wxMUTEX_BUSY;
+
+        wxLogSysError( wxT("Could not try lock mutex") );
+        return wxMUTEX_MISC_ERROR;
     }
-    
-       return wxMUTEX_NO_ERROR;
+
+    return wxMUTEX_NO_ERROR;
 }
 
 wxMutexError wxMutexInternal::Unlock()
 {
     wxCHECK_MSG( m_isOk , wxMUTEX_MISC_ERROR , wxT("Invalid Mutex") ) ;
-       OSStatus err = MPExitCriticalRegion( m_critRegion);
-       MPYield() ;
-       if ( err)
+
+    OSStatus err = MPExitCriticalRegion( m_critRegion );
+    MPYield() ;
+
+    if (err != noErr)
     {
-               wxLogSysError(_("Could not unlock mutex"));
-               return wxMUTEX_MISC_ERROR;        
+        wxLogSysError( wxT("Could not unlock mutex") );
+
+        return wxMUTEX_MISC_ERROR;
     }
-    
-       return wxMUTEX_NO_ERROR;
+
+    return wxMUTEX_NO_ERROR;
 }
 
 #endif
@@ -484,75 +516,79 @@ wxMutexError wxMutexInternal::Unlock()
 class wxSemaphoreInternal
 {
 public:
-       wxSemaphoreInternal(int initialcount, int maxcount);
-       ~wxSemaphoreInternal();
-       
-       bool IsOk() const { return m_isOk; }
-       
-       wxSemaError WaitTimeout(unsigned long milliseconds);
-       
-       wxSemaError Wait() { return WaitTimeout( kDurationForever); }
-       
-       wxSemaError TryWait() 
-       { 
-           wxSemaError err = WaitTimeout(kDurationImmediate); 
-           if ( err == wxSEMA_TIMEOUT )
-               err = wxSEMA_BUSY ;
-           return err ;
-       }
-       wxSemaError Post();
-       
+    wxSemaphoreInternal( int initialcount, int maxcount );
+    virtual ~wxSemaphoreInternal();
+
+    bool IsOk() const
+    { return m_isOk; }
+
+    wxSemaError Post();
+    wxSemaError WaitTimeout( unsigned long milliseconds );
+
+    wxSemaError Wait()
+    { return WaitTimeout( kDurationForever); }
+
+    wxSemaError TryWait()
+    {
+        wxSemaError err = WaitTimeout( kDurationImmediate );
+        if (err == wxSEMA_TIMEOUT)
+            err = wxSEMA_BUSY;
+
+        return err;
+    }
+
 private:
     MPSemaphoreID m_semaphore;
-    bool m_isOk ;
+    bool m_isOk;
 };
 
-wxSemaphoreInternal::wxSemaphoreInternal(int initialcount, int maxcount)
+wxSemaphoreInternal::wxSemaphoreInternal( int initialcount, int maxcount)
 {
-    m_isOk = false ;
-    m_semaphore = kInvalidID ;
-       if ( maxcount == 0 )
+    m_isOk = false;
+    m_semaphore = kInvalidID;
+    if ( maxcount == 0 )
+        // make it practically infinite
+        maxcount = INT_MAX;
+
+    verify_noerr( MPCreateSemaphore( maxcount, initialcount, &m_semaphore ) );
+    m_isOk = ( m_semaphore != kInvalidID );
+
+    if ( !IsOk() )
     {
-               // make it practically infinite
-               maxcount = INT_MAX;
+        wxFAIL_MSG( wxT("Error when creating semaphore") );
     }
-       verify_noerr( MPCreateSemaphore( maxcount, initialcount, & m_semaphore) );
-    m_isOk = ( m_semaphore != kInvalidID ) ;
-    
-    if ( !IsOk() )
-        wxFAIL_MSG(wxT("Error when creating semaphore") ) ;
 }
 
 wxSemaphoreInternal::~wxSemaphoreInternal()
 {
-    if( m_semaphore != kInvalidID )
-           MPDeleteSemaphore( m_semaphore);
-       MPYield() ;
+    if (m_semaphore != kInvalidID)
+        MPDeleteSemaphore( m_semaphore );
+
+    MPYield();
 }
 
-wxSemaError wxSemaphoreInternal::WaitTimeout(unsigned long milliseconds)
+wxSemaError wxSemaphoreInternal::WaitTimeout( unsigned long milliseconds )
 {
-       OSStatus err = MPWaitOnSemaphore( m_semaphore, milliseconds);
-       if ( err)
+    OSStatus err = MPWaitOnSemaphore( m_semaphore, milliseconds );
+    if (err != noErr)
     {
-               if ( err == kMPTimeoutErr)
-               {
-                       return wxSEMA_TIMEOUT;
-               }
-               return wxSEMA_MISC_ERROR;
+        if (err == kMPTimeoutErr)
+            return wxSEMA_TIMEOUT;
+
+        return wxSEMA_MISC_ERROR;
     }
-       return wxSEMA_NO_ERROR;
+
+    return wxSEMA_NO_ERROR;
 }
 
 wxSemaError wxSemaphoreInternal::Post()
 {
-       OSStatus err = MPSignalSemaphore( m_semaphore);
-       MPYield() ;
-       if ( err)
-    {
-               return wxSEMA_MISC_ERROR;
-    }
-       return wxSEMA_NO_ERROR;
+    OSStatus err = MPSignalSemaphore( m_semaphore );
+    MPYield();
+    if (err != noErr)
+        return wxSEMA_MISC_ERROR;
+
+    return wxSEMA_NO_ERROR;
 }
 
 // ----------------------------------------------------------------------------
@@ -564,185 +600,182 @@ wxSemaError wxSemaphoreInternal::Post()
 class wxConditionInternal
 {
 public:
-       
-       wxConditionInternal(wxMutex& mutex) 
-    : m_mutex( mutex),
-       m_semaphore( 0, 1),
-       m_gate( 1, 1)
-       {
-               m_waiters = 0;
-               m_signals = 0;
-               m_canceled = 0;
-       }
-       
-       ~wxConditionInternal()
-       {
-       }
-       
-       bool IsOk() const { return m_mutex.IsOk() ; }
-    
-       wxCondError Wait()
-       {
-               return WaitTimeout( kDurationForever);
-       }
-       
-       wxCondError WaitTimeout(unsigned long msectimeout);
-       
-       wxCondError Signal()
-       {
-               return DoSignal( false);
-       }
-       
-       wxCondError Broadcast()
-       {
-               return DoSignal( true);
-       }
-    
+    wxConditionInternal( wxMutex& mutex )
+    :
+    m_mutex( mutex ),
+    m_semaphore( 0, 1 ),
+    m_gate( 1, 1 )
+    {
+        m_waiters = 0;
+        m_signals = 0;
+        m_canceled = 0;
+    }
+
+    virtual ~wxConditionInternal() {}
+
+    bool IsOk() const
+    { return m_mutex.IsOk(); }
+
+    wxCondError Wait()
+    { return WaitTimeout( kDurationForever ); }
+
+    wxCondError WaitTimeout( unsigned long msectimeout );
+
+    wxCondError Signal()
+    { return DoSignal( false); }
+
+    wxCondError Broadcast()
+    { return DoSignal( true ); }
+
 private:
-               
-               wxCondError DoSignal( bool signalAll);
-       
-       wxMutex&          m_mutex;
-       wxSemaphoreInternal     m_semaphore;  // Signals the waiting threads.
-       wxSemaphoreInternal       m_gate;
-       wxCriticalSection m_varSection;
-       size_t    m_waiters;    // Number of threads waiting for a signal.
-       size_t          m_signals;      // Number of signals to send.
-       size_t    m_canceled;   // Number of canceled waiters in m_waiters.
+    wxCondError DoSignal( bool signalAll );
+
+    wxMutex& m_mutex;
+    wxSemaphoreInternal m_semaphore;  // Signals the waiting threads.
+    wxSemaphoreInternal m_gate;
+    wxCriticalSection m_varSection;
+    size_t m_waiters; // Number of threads waiting for a signal.
+    size_t m_signals; // Number of signals to send.
+    size_t m_canceled; // Number of canceled waiters in m_waiters.
 };
 
+wxCondError wxConditionInternal::WaitTimeout( unsigned long msectimeout )
+{
+    m_gate.Wait();
 
-wxCondError wxConditionInternal::WaitTimeout(unsigned long msectimeout)
-{      
-       m_gate.Wait();
-       if ( ++ m_waiters == INT_MAX)
-    {
-               m_varSection.Enter();
-               m_waiters -= m_canceled;
-               m_signals -= m_canceled;
-               m_canceled = 0;
-               m_varSection.Leave();
-    }
-       m_gate.Post();
-       
-       m_mutex.Unlock();
-       
-       wxSemaError err = m_semaphore.WaitTimeout( msectimeout);
-       wxASSERT( err == wxSEMA_NO_ERROR || err == wxSEMA_TIMEOUT);
-       
-       m_varSection.Enter();
-       if ( err != wxSEMA_NO_ERROR)
+    if ( ++ m_waiters == INT_MAX )
     {
-               if ( m_signals > m_canceled)
-               {
-                       // A signal is being sent after we timed out.
-                       
-                       if ( m_waiters == m_signals)
-                       {
-                               // There are no excess waiters to catch the signal, so
-                               // we must throw it away.
-                               
-                               wxSemaError err2 = m_semaphore.Wait();
-                               if ( err2 != wxSEMA_NO_ERROR)
-                               {
-                                       wxLogSysError(_("Error while waiting on semaphore"));
-                               }
-                               wxASSERT( err2 == wxSEMA_NO_ERROR);
-                               -- m_waiters;
-                               if ( -- m_signals == m_canceled)
-                               {
-                                       // This was the last signal. open the gate.
-                                       wxASSERT( m_waiters == m_canceled);
-                                       m_gate.Post();
-                               }
-                       }
-                       else
-                       {
-                               // There are excess waiters to catch the signal, leave
-                               // it be.
-                               -- m_waiters;
-                       }
-               }
-               else
-               {
-                       // No signals is being sent.
-                       // The gate may be open or closed, so we can't touch m_waiters.
-                       ++ m_canceled;
-                       ++ m_signals;
-               }
+        m_varSection.Enter();
+
+        m_waiters -= m_canceled;
+        m_signals -= m_canceled;
+        m_canceled = 0;
+
+        m_varSection.Leave();
     }
-       else
+
+    m_gate.Post();
+    m_mutex.Unlock();
+
+    wxSemaError err = m_semaphore.WaitTimeout( msectimeout);
+    wxASSERT( err == wxSEMA_NO_ERROR || err == wxSEMA_TIMEOUT);
+
+    m_varSection.Enter();
+
+    if ( err != wxSEMA_NO_ERROR )
     {
-               // We caught a signal.
-               wxASSERT( m_signals > m_canceled);
-               -- m_waiters;
-               if ( -- m_signals == m_canceled)
-               {
-                       // This was the last signal. open the gate.
-                       wxASSERT( m_waiters == m_canceled);
-                       m_gate.Post();
-               }
+        if ( m_signals > m_canceled )
+        {
+            // A signal is being sent after we timed out.
+            if ( m_waiters == m_signals )
+            {
+                // There are no excess waiters to catch the signal, so
+                // we must throw it away.
+                wxSemaError err2 = m_semaphore.Wait();
+                if ( err2 != wxSEMA_NO_ERROR )
+                {
+                    wxLogSysError( wx("Error while waiting on semaphore") );
+                }
+
+                wxASSERT( err2 == wxSEMA_NO_ERROR);
+
+                --m_waiters;
+                if ( --m_signals == m_canceled )
+                {
+                    // This was the last signal. open the gate.
+                    wxASSERT( m_waiters == m_canceled );
+                    m_gate.Post();
+                }
+            }
+            else
+            {
+                // There are excess waiters to catch the signal, leave it be.
+                --m_waiters;
+            }
+        }
+        else
+        {
+            // No signals is being sent:
+            // the gate may be open or closed, so we can't touch m_waiters.
+            ++m_canceled;
+            ++m_signals;
+        }
     }
-       m_varSection.Leave();
-       
-       m_mutex.Lock();
-       
-       if ( err)
+    else
     {
-               return err == wxSEMA_TIMEOUT ? wxCOND_TIMEOUT : wxCOND_MISC_ERROR;
+        // We caught a signal.
+        wxASSERT( m_signals > m_canceled );
+
+        --m_waiters;
+
+        if ( --m_signals == m_canceled)
+        {
+            // This was the last signal. open the gate.
+            wxASSERT( m_waiters == m_canceled );
+
+            m_gate.Post();
+        }
     }
-    
-       return wxCOND_NO_ERROR;
+
+    m_varSection.Leave();
+    m_mutex.Lock();
+
+    if (err != noErr)
+        return err == wxSEMA_TIMEOUT ? wxCOND_TIMEOUT : wxCOND_MISC_ERROR;
+
+    return wxCOND_NO_ERROR;
 }
 
 
 wxCondError wxConditionInternal::DoSignal( bool signalAll)
 {
-       m_gate.Wait();
-       m_varSection.Enter();
-       
-       wxASSERT( m_signals == m_canceled);
-       
-       if ( m_waiters == m_canceled)
+    m_gate.Wait();
+    m_varSection.Enter();
+
+    wxASSERT( m_signals == m_canceled );
+
+    if ( m_waiters == m_canceled)
     {
-               m_varSection.Leave();
-               m_gate.Post();
-               return wxCOND_NO_ERROR;
+        m_varSection.Leave();
+        m_gate.Post();
+        return wxCOND_NO_ERROR;
     }
-       
-       if ( m_canceled > 0)
+
+    if ( m_canceled > 0)
     {
-               m_waiters -= m_canceled;
-               m_signals = 0;
-               m_canceled = 0;
+        m_waiters -= m_canceled;
+        m_signals = 0;
+        m_canceled = 0;
     }
-       
-       m_signals = signalAll ? m_waiters : 1;
-       size_t n = m_signals;
-       
-       m_varSection.Leave();
-       
-       // Let the waiters inherit the gate lock.
-       
-       do
+
+    m_signals = signalAll ? m_waiters : 1;
+    size_t n = m_signals;
+
+    m_varSection.Leave();
+
+    // Let the waiters inherit the gate lock.
+
+    do
     {
-               wxSemaError err = m_semaphore.Post();
-               wxASSERT( err == wxSEMA_NO_ERROR);
-    } while ( -- n);
-       
-       return wxCOND_NO_ERROR;
+        wxSemaError err = m_semaphore.Post();
+        wxASSERT( err == wxSEMA_NO_ERROR );
+    }
+    while ( --n );
+
+    return wxCOND_NO_ERROR;
 }
 
 #else
 class wxConditionInternal
 {
 public:
-    wxConditionInternal(wxMutex& mutex);
+    wxConditionInternal( wxMutex& mutex );
 
-    bool IsOk() const { return m_mutex.IsOk() && m_semaphore.IsOk(); }
+    bool IsOk() const
+    { return m_mutex.IsOk() && m_semaphore.IsOk(); }
 
     wxCondError Wait();
-    wxCondError WaitTimeout(unsigned long milliseconds);
+    wxCondError WaitTimeout( unsigned long milliseconds );
 
     wxCondError Signal();
     wxCondError Broadcast();
@@ -760,8 +793,8 @@ private:
     DECLARE_NO_COPY_CLASS(wxConditionInternal)
 };
 
-wxConditionInternal::wxConditionInternal(wxMutex& mutex)
-                   : m_mutex(mutex)
+wxConditionInternal::wxConditionInternal( wxMutex& mutex )
+    : m_mutex(mutex)
 {
     // another thread can't access it until we return from ctor, so no need to
     // protect access to m_numWaiters here
@@ -771,7 +804,7 @@ wxConditionInternal::wxConditionInternal(wxMutex& mutex)
 wxCondError wxConditionInternal::Wait()
 {
     // increment the number of waiters
-    IncrementAtomic(&m_numWaiters);
+    IncrementAtomic( &m_numWaiters );
 
     m_mutex.Unlock();
 
@@ -792,9 +825,9 @@ wxCondError wxConditionInternal::Wait()
     return err == wxSEMA_NO_ERROR ? wxCOND_NO_ERROR : wxCOND_MISC_ERROR;
 }
 
-wxCondError wxConditionInternal::WaitTimeout(unsigned long milliseconds)
+wxCondError wxConditionInternal::WaitTimeout( unsigned long milliseconds )
 {
-    IncrementAtomic(&m_numWaiters);
+    IncrementAtomic( &m_numWaiters );
 
     m_mutex.Unlock();
 
@@ -804,7 +837,7 @@ wxCondError wxConditionInternal::WaitTimeout(unsigned long milliseconds)
 
     wxSemaError err = m_semaphore.WaitTimeout(milliseconds);
 
-    if ( err == wxSEMA_BUSY )
+    if ( err == wxSEMA_TIMEOUT )
     {
         // another potential race condition exists here it is caused when a
         // 'waiting' thread timesout, and returns from WaitForSingleObject, but
@@ -883,86 +916,105 @@ class wxThreadInternal
 public:
     wxThreadInternal()
     {
-               m_tid = kInvalidID;
-               m_state = STATE_NEW;
-               m_prio = WXTHREAD_DEFAULT_PRIORITY;
-               m_notifyQueueId = kInvalidID;
+        m_tid = kInvalidID;
+        m_state = STATE_NEW;
+        m_prio = WXTHREAD_DEFAULT_PRIORITY;
+        m_notifyQueueId = kInvalidID;
         m_exitcode = 0;
-        m_cancelled = FALSE ;
+        m_cancelled = false ;
 
-        // set to TRUE only when the thread starts waiting on m_semSuspend
-        m_isPaused = FALSE;
+        // set to true only when the thread starts waiting on m_semSuspend
+        m_isPaused = false;
 
         // defaults for joinable threads
-        m_shouldBeJoined = TRUE;
-        m_isDetached = FALSE;
+        m_shouldBeJoined = true;
+        m_isDetached = false;
     }
-    ~wxThreadInternal()
+
+    virtual ~wxThreadInternal()
     {
-               if ( m_notifyQueueId)
-               {
-                       MPDeleteQueue( m_notifyQueueId);
-                       m_notifyQueueId = kInvalidID ;
-           }
+        if ( m_notifyQueueId)
+        {
+            MPDeleteQueue( m_notifyQueueId );
+            m_notifyQueueId = kInvalidID ;
+        }
     }
 
-       // thread function
-       static OSStatus    MacThreadStart(void* arg);
+    // thread function
+    static OSStatus MacThreadStart(void* arg);
 
     // create a new (suspended) thread (for the given thread object)
     bool Create(wxThread *thread, unsigned int stackSize);
 
     // thread actions
+
     // start the thread
     wxThreadError Run();
+
     // unblock the thread allowing it to run
     void SignalRun() { m_semRun.Post(); }
+
     // ask the thread to terminate
     void Wait();
+
     // go to sleep until Resume() is called
     void Pause();
+
     // resume the thread
     void Resume();
 
     // accessors
     // priority
-    int GetPriority() const { return m_prio; }
-    void SetPriority(int prio) ;
+    int GetPriority() const
+    { return m_prio; }
+    void SetPriority(int prio);
+
     // state
-    wxThreadState GetState() const { return m_state; }
-    void SetState(wxThreadState state) { m_state = state; }
+    wxThreadState GetState() const
+    { return m_state; }
+    void SetState(wxThreadState state)
+    { m_state = state; }
+
+    // Get the ID of this thread's underlying MP Services task.
+    MPTaskID  GetId() const
+    { return m_tid; }
 
-       // Get the ID of this thread's underlying MP Services task.
-       MPTaskID  GetId() const { return m_tid; }
+    void SetCancelFlag()
+    { m_cancelled = true; }
+
+    bool WasCancelled() const
+    { return m_cancelled; }
 
-    void SetCancelFlag() { m_cancelled = TRUE; }
-    bool WasCancelled() const { return m_cancelled; }
     // exit code
-    void SetExitCode(wxThread::ExitCode exitcode) { m_exitcode = exitcode; }
-    wxThread::ExitCode GetExitCode() const { return m_exitcode; }
+    void SetExitCode(wxThread::ExitCode exitcode)
+    { m_exitcode = exitcode; }
+    wxThread::ExitCode GetExitCode() const
+    { return m_exitcode; }
 
     // the pause flag
-    void SetReallyPaused(bool paused) { m_isPaused = paused; }
-    bool IsReallyPaused() const { return m_isPaused; }
+    void SetReallyPaused(bool paused)
+    { m_isPaused = paused; }
+    bool IsReallyPaused() const
+    { return m_isPaused; }
 
     // tell the thread that it is a detached one
     void Detach()
     {
         wxCriticalSectionLocker lock(m_csJoinFlag);
 
-        m_shouldBeJoined = FALSE;
-        m_isDetached = TRUE;
+        m_shouldBeJoined = false;
+        m_isDetached = true;
     }
 
 private:
     // the thread we're associated with
     wxThread *      m_thread;
 
-       MPTaskID        m_tid;              // thread id
-       MPQueueID           m_notifyQueueId;    // its notification queue
+    MPTaskID        m_tid;                // thread id
+    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;
@@ -991,11 +1043,11 @@ private:
 
 OSStatus wxThreadInternal::MacThreadStart(void *parameter)
 {
-       wxThread* thread = (wxThread*) parameter ;
+    wxThread* thread = (wxThread*) parameter ;
     wxThreadInternal *pthread = thread->m_internal;
 
     // add to TLS so that This() will work
-       verify_noerr( MPSetTaskStorageValue( gs_tlsForWXThread , (long) thread ) ) ;
+    verify_noerr( MPSetTaskStorageValue( gs_tlsForWXThread , (TaskStorageValue) thread ) ) ;
 
     // have to declare this before pthread_cleanup_push() which defines a
     // block!
@@ -1019,85 +1071,80 @@ OSStatus wxThreadInternal::MacThreadStart(void *parameter)
 
         {
             wxCriticalSectionLocker lock(thread->m_critsect);
-            pthread->SetState(STATE_EXITED);
+            pthread->SetState( STATE_EXITED );
         }
     }
-    
+
     if ( dontRunAtAll )
     {
         if ( pthread->m_isDetached )
             delete thread;
 
-        return -1 ;
+        return -1;
     }
     else
     {
-        // on mac for the running code the correct thread termination is to
-        // return
+        // on Mac for the running code,
+        // the correct thread termination is to return
 
         // terminate the thread
-        thread->Exit(pthread->m_exitcode);
+        thread->Exit( pthread->m_exitcode );
 
-        return (OSStatus) NULL ; // pthread->m_exitcode;
+        return (OSStatus) NULL; // pthread->m_exitcode;
     }
 }
 
-bool wxThreadInternal::Create(wxThread *thread, unsigned int stackSize)
+bool wxThreadInternal::Create( wxThread *thread, unsigned int stackSize )
 {
     wxASSERT_MSG( m_state == STATE_NEW && !m_tid,
-                    _T("Create()ing thread twice?") );
+                    wxT("Create()ing thread twice?") );
 
-       OSStatus err = noErr ;
-       m_thread = thread;
-       
-       if ( m_notifyQueueId == kInvalidID )
-    {
-               OSStatus err = MPCreateQueue( & m_notifyQueueId);
-               if( err)
-               {
-                       wxLogSysError(_("Cant create the thread event queue"));
-                       return false;
-               }
-    }
-       
-       m_state = STATE_NEW;
-       
-       err = MPCreateTask( MacThreadStart,
-                                               (void*) m_thread,
-                                               stackSize,
-                                               m_notifyQueueId,
-                                               &m_exitcode,
-                                               0,
-                                               0,
-                                               &m_tid);
-       
-       if ( err)
+    OSStatus err = noErr;
+    m_thread = thread;
+
+    if ( m_notifyQueueId == kInvalidID )
     {
-               wxLogSysError(_("Can't create thread"));                
-               return false;
+        OSStatus err = MPCreateQueue( &m_notifyQueueId );
+        if (err != noErr)
+        {
+            wxLogSysError( wxT("Cant create the thread event queue") );
+
+            return false;
+        }
     }
-       
-       if ( m_prio != WXTHREAD_DEFAULT_PRIORITY )
+
+    m_state = STATE_NEW;
+
+    err = MPCreateTask(
+        MacThreadStart, (void*)m_thread, stackSize,
+        m_notifyQueueId, &m_exitcode, 0, 0, &m_tid );
+
+    if (err != noErr)
     {
-               SetPriority(m_prio);
+        wxLogSysError( wxT("Can't create thread") );
+
+        return false;
     }
-       
-       return true;
+
+    if ( m_prio != WXTHREAD_DEFAULT_PRIORITY )
+        SetPriority( m_prio );
+
+    return true;
 }
 
-void wxThreadInternal::SetPriority( int priority)
+void wxThreadInternal::SetPriority( int priority )
 {
-       m_prio = priority;
-       
-       if ( m_tid)
+    m_prio = 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
-               // the former uses a logarithmic scale.
-               const unsigned int macPriority = ( int)( exp( priority / 25.0 * log( 10.0)) + 0.5);
-               
-               MPSetTaskWeight( m_tid, macPriority);
+        // Mac priorities range from 1 to 10,000, with a default of 100.
+        // 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);
+
+        MPSetTaskWeight( m_tid, macPriority );
     }
 }
 
@@ -1106,7 +1153,7 @@ wxThreadError wxThreadInternal::Run()
     wxCHECK_MSG( GetState() == STATE_NEW, wxTHREAD_RUNNING,
                  wxT("thread may only be started once after Create()") );
 
-    SetState(STATE_RUNNING);
+    SetState( STATE_RUNNING );
 
     // wake up threads waiting for our start
     SignalRun();
@@ -1116,30 +1163,35 @@ wxThreadError wxThreadInternal::Run()
 
 void wxThreadInternal::Wait()
 {
-   wxCHECK_RET( !m_isDetached, _T("can't wait for a detached thread") );
+   wxCHECK_RET( !m_isDetached, wxT("can't wait for a detached thread") );
 
     // 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);
 
         if ( m_shouldBeJoined )
         {
-            void * param1;
-            void * param2;
-            void * rc;
-
-            OSStatus err = MPWaitOnQueue ( m_notifyQueueId, 
-                                & param1, 
-                                & param2, 
-                                & rc, 
-                                kDurationForever);
-            if ( err)
+            void *param1, *param2, *rc;
+
+            OSStatus err = MPWaitOnQueue(
+                m_notifyQueueId,
+                &param1,
+                &param2,
+                &rc,
+                kDurationForever );
+            if (err != noErr)
             {
-                wxLogSysError( _( "Cannot wait on thread to exit."));
+                wxLogSysError( wxT( "Cannot wait for thread termination."));
                 rc = (void*) -1;
             }
 
@@ -1147,13 +1199,9 @@ void wxThreadInternal::Wait()
             // but we don't need this here
             m_exitcode = rc;
 
-            m_shouldBeJoined = FALSE;
+            m_shouldBeJoined = false;
         }
     }
-
-    // reacquire GUI mutex
-    if ( wxThread::IsMain() )
-        wxMutexGuiEnter();
 }
 
 void wxThreadInternal::Pause()
@@ -1180,10 +1228,10 @@ void wxThreadInternal::Resume()
         m_semSuspend.Post();
 
         // reset the flag
-        SetReallyPaused(FALSE);
+        SetReallyPaused( false );
     }
 
-    SetState(STATE_RUNNING);
+    SetState( STATE_RUNNING );
 }
 
 // static functions
@@ -1192,12 +1240,13 @@ void wxThreadInternal::Resume()
 wxThread *wxThread::This()
 {
     wxThread* thr = (wxThread*) MPGetTaskStorageValue( gs_tlsForWXThread ) ;
-       return thr;
+
+    return thr;
 }
 
 bool wxThread::IsMain()
 {
-       return GetCurrentId() == gs_idMainThread || gs_idMainThread == kNoThreadID;
+    return GetCurrentId() == gs_idMainThread || gs_idMainThread == kInvalidID ;
 }
 
 #ifdef Yield
@@ -1207,48 +1256,46 @@ bool wxThread::IsMain()
 void wxThread::Yield()
 {
 #if TARGET_API_MAC_OSX
-       CFRunLoopRunInMode( kCFRunLoopDefaultMode , 0 , true ) ;
+    CFRunLoopRunInMode( kCFRunLoopDefaultMode , 0 , true ) ;
 #endif
-       MPYield();
-}
 
+    MPYield();
+}
 
-void wxThread::Sleep(unsigned long milliseconds)
+void wxThread::Sleep( unsigned long milliseconds )
 {
-       AbsoluteTime wakeup = AddDurationToAbsolute( milliseconds, UpTime());
-       MPDelayUntil( & wakeup);
+    AbsoluteTime wakeup = AddDurationToAbsolute( milliseconds, UpTime() );
+    MPDelayUntil( &wakeup );
 }
 
-
 int wxThread::GetCPUCount()
 {
-       return MPProcessors();
+    return MPProcessors();
 }
 
 unsigned long wxThread::GetCurrentId()
 {
-       return (unsigned long)MPCurrentTaskID();
+    return (unsigned long)MPCurrentTaskID();
 }
 
-
-bool wxThread::SetConcurrency(size_t level)
+bool wxThread::SetConcurrency( size_t level )
 {
     // Cannot be set in MacOS.
-       return false;
+    return false;
 }
 
-
-wxThread::wxThread(wxThreadKind kind)
+wxThread::wxThread( wxThreadKind kind )
 {
-       g_numberOfThreads++;
-       m_internal = new wxThreadInternal();
-       
-       m_isDetached = (kind == wxTHREAD_DETACHED);
+    g_numberOfThreads++;
+    m_internal = new wxThreadInternal();
+
+    m_isDetached = (kind == wxTHREAD_DETACHED);
 }
 
 wxThread::~wxThread()
 {
     wxASSERT_MSG( g_numberOfThreads>0 , wxT("More threads deleted than created.") ) ;
+
     g_numberOfThreads--;
 
 #ifdef __WXDEBUG__
@@ -1258,31 +1305,32 @@ wxThread::~wxThread()
     if ( m_internal->GetState() != STATE_EXITED &&
          m_internal->GetState() != STATE_NEW )
     {
-        wxLogDebug(_T("The thread %ld is being destroyed although it is still running! The application may crash."), GetId());
+        wxLogDebug(
+            wxT("The thread %ld is being destroyed although it is still running! The application may crash."),
+            GetId() );
     }
 
     m_critsect.Leave();
-#endif // __WXDEBUG__
+#endif
 
     wxDELETE( m_internal ) ;
 }
 
-
-wxThreadError wxThread::Create(unsigned int stackSize)
+wxThreadError wxThread::Create( unsigned int stackSize )
 {
-       wxCriticalSectionLocker lock(m_critsect);
-       
+    wxCriticalSectionLocker lock(m_critsect);
+
     if ( m_isDetached )
-    {
         m_internal->Detach() ;
-    }
-       if ( m_internal->Create(this, stackSize) == false )
+
+    if ( !m_internal->Create(this, stackSize) )
     {
-        m_internal->SetState(STATE_EXITED);
+        m_internal->SetState( STATE_EXITED );
+
         return wxTHREAD_NO_RESOURCE;
     }
-       
-       return wxTHREAD_NO_ERROR;
+
+    return wxTHREAD_NO_ERROR;
 }
 
 wxThreadError wxThread::Run()
@@ -1308,14 +1356,14 @@ wxThreadError wxThread::Pause()
 
     if ( m_internal->GetState() != STATE_RUNNING )
     {
-        wxLogDebug(wxT("Can't pause thread which is not running."));
+        wxLogDebug( wxT("Can't pause thread which is not running.") );
 
         return wxTHREAD_NOT_RUNNING;
     }
 
     // just set a flag, the thread will be really paused only during the next
     // call to TestDestroy()
-    m_internal->SetState(STATE_PAUSED);
+    m_internal->SetState( STATE_PAUSED );
 
     return wxTHREAD_NO_ERROR;
 }
@@ -1323,7 +1371,7 @@ wxThreadError wxThread::Pause()
 wxThreadError wxThread::Resume()
 {
     wxCHECK_MSG( This() != this, wxTHREAD_MISC_ERROR,
-                 _T("a thread can't resume itself") );
+                 wxT("a thread can't resume itself") );
 
     wxCriticalSectionLocker lock(m_critsect);
 
@@ -1334,11 +1382,12 @@ wxThreadError wxThread::Resume()
         case STATE_PAUSED:
             m_internal->Resume();
             return wxTHREAD_NO_ERROR;
+
         case STATE_EXITED:
             return wxTHREAD_NO_ERROR;
 
         default:
-            wxLogDebug(_T("Attempt to resume a thread which is not paused."));
+            wxLogDebug( wxT("Attempt to resume a thread which is not paused.") );
 
             return wxTHREAD_MISC_ERROR;
     }
@@ -1351,10 +1400,10 @@ wxThreadError wxThread::Resume()
 wxThread::ExitCode wxThread::Wait()
 {
     wxCHECK_MSG( This() != this, (ExitCode)-1,
-                 _T("a thread can't wait for itself") );
+                 wxT("a thread can't wait for itself") );
 
     wxCHECK_MSG( !m_isDetached, (ExitCode)-1,
-                 _T("can't wait for detached thread") );
+                 wxT("can't wait for detached thread") );
 
     m_internal->Wait();
 
@@ -1364,7 +1413,7 @@ wxThread::ExitCode wxThread::Wait()
 wxThreadError wxThread::Delete(ExitCode *rc)
 {
     wxCHECK_MSG( This() != this, wxTHREAD_MISC_ERROR,
-                 _T("a thread can't delete itself") );
+                 wxT("a thread can't delete itself") );
 
     bool isDetached = m_isDetached;
 
@@ -1408,7 +1457,6 @@ wxThreadError wxThread::Delete(ExitCode *rc)
                     *rc = m_internal->GetExitCode();
                 }
             }
-            //else: can't wait for detached threads
     }
 
     return wxTHREAD_NO_ERROR;
@@ -1417,7 +1465,7 @@ wxThreadError wxThread::Delete(ExitCode *rc)
 wxThreadError wxThread::Kill()
 {
     wxCHECK_MSG( This() != this, wxTHREAD_MISC_ERROR,
-                 _T("a thread can't kill itself") );
+                 wxT("a thread can't kill itself") );
 
     switch ( m_internal->GetState() )
     {
@@ -1433,9 +1481,9 @@ wxThreadError wxThread::Kill()
 
         default:
             OSStatus err = MPTerminateTask( m_internal->GetId() , -1 ) ;
-            if ( err )
+            if (err != noErr)
             {
-                wxLogError(_("Failed to terminate a thread."));
+                wxLogError( wxT("Failed to terminate a thread.") );
 
                 return wxTHREAD_MISC_ERROR;
             }
@@ -1447,17 +1495,17 @@ wxThreadError wxThread::Kill()
             else
             {
                 // this should be retrieved by Wait actually
-                m_internal->SetExitCode((void*)-1);
+                m_internal->SetExitCode( (void*)-1 );
             }
 
             return wxTHREAD_NO_ERROR;
     }
 }
 
-void wxThread::Exit(ExitCode status)
+void wxThread::Exit( ExitCode status )
 {
     wxASSERT_MSG( This() == this,
-                  _T("wxThread::Exit() can only be called in the context of the same thread") );
+                  wxT("wxThread::Exit() can only be called in the context of the same thread") );
 
     // don't enter m_critsect before calling OnExit() because the user code
     // might deadlock if, for example, it signals a condition in OnExit() (a
@@ -1465,8 +1513,8 @@ void wxThread::Exit(ExitCode status)
     // m_critsect on us (almost all of them do)
     OnExit();
 
-    MPTaskID threadid = m_internal->GetId() ;
-    
+    MPTaskID threadid = m_internal->GetId();
+
     if ( IsDetached() )
     {
         delete this;
@@ -1474,27 +1522,27 @@ void wxThread::Exit(ExitCode status)
     else // joinable
     {
         // update the status of the joinable thread
-        wxCriticalSectionLocker lock(m_critsect);
-        m_internal->SetState(STATE_EXITED);
+        wxCriticalSectionLocker lock( m_critsect );
+        m_internal->SetState( STATE_EXITED );
     }
-    MPTerminateTask( threadid , (long) status) ;    
+
+    MPTerminateTask( threadid, (long)status );
 }
 
 // also test whether we were paused
 bool wxThread::TestDestroy()
 {
     wxASSERT_MSG( This() == this,
-                  _T("wxThread::TestDestroy() can only be called in the context of the same thread") );
+                  wxT("wxThread::TestDestroy() can only be called in the context of the same thread") );
 
     m_critsect.Enter();
 
     if ( m_internal->GetState() == STATE_PAUSED )
     {
-        m_internal->SetReallyPaused(TRUE);
+        m_internal->SetReallyPaused( true );
 
-        // leave the crit section or the other threads will stop too if they
-        // try to call any of (seemingly harmless) IsXXX() functions while we
-        // sleep
+        // leave the crit section or the other threads will stop too if they attempt
+        // to call any of (seemingly harmless) IsXXX() functions while we sleep
         m_critsect.Leave();
 
         m_internal->Pause();
@@ -1526,12 +1574,12 @@ void wxThread::SetPriority(unsigned int prio)
         case STATE_PAUSED:
         case STATE_NEW:
             // thread not yet started, priority will be set when it is
-            m_internal->SetPriority(prio);
+            m_internal->SetPriority( prio );
             break;
 
         case STATE_EXITED:
         default:
-            wxFAIL_MSG(wxT("impossible to set thread priority in this state"));
+            wxFAIL_MSG( wxT("impossible to set thread priority in this state") );
     }
 }
 
@@ -1568,10 +1616,10 @@ bool wxThread::IsAlive() const
     {
         case STATE_RUNNING:
         case STATE_PAUSED:
-            return TRUE;
+            return true;
 
         default:
-            return FALSE;
+            return false;
     }
 }
 
@@ -1589,44 +1637,54 @@ bool wxThread::IsPaused() const
 class wxThreadModule : public wxModule
 {
 public:
-       virtual bool OnInit();
-       virtual void OnExit();
-       
+    virtual bool OnInit();
+    virtual void OnExit();
+
 private:
-               DECLARE_DYNAMIC_CLASS(wxThreadModule)
+    DECLARE_DYNAMIC_CLASS(wxThreadModule)
 };
 
 IMPLEMENT_DYNAMIC_CLASS(wxThreadModule, wxModule)
 
 bool wxThreadModule::OnInit()
 {
-       bool hasThreadManager = false ;
-       hasThreadManager = MPLibraryIsLoaded();
-    
-       if ( !hasThreadManager )
+    bool hasThreadManager = 
+#ifdef __LP64__ 
+        true ; // TODO VERIFY IN NEXT BUILD
+#else
+        MPLibraryIsLoaded();
+#endif
+
+    if ( !hasThreadManager )
     {
-               wxLogError( _("MP Thread Support is not available on this System" ) ) ;
-               return FALSE ;
+        wxLogError( wxT("MP thread support is not available on this system" ) ) ;
+
+        return false;
     }
-       
-       verify_noerr( MPAllocateTaskStorageIndex( &gs_tlsForWXThread ) ) ;
-       // main thread's This() is NULL
-       verify_noerr( MPSetTaskStorageValue( gs_tlsForWXThread , NULL ) ) ;
 
-       gs_idMainThread = wxThread::GetCurrentId() ;
-       
+    // main thread's This() is NULL
+    verify_noerr( MPAllocateTaskStorageIndex( &gs_tlsForWXThread ) ) ;
+    verify_noerr( MPSetTaskStorageValue( gs_tlsForWXThread, 0 ) ) ;
+
+    gs_idMainThread = wxThread::GetCurrentId();
     gs_critsectWaitingForGui = new wxCriticalSection();
 
     gs_critsectGui = new wxCriticalSection();
     gs_critsectGui->Enter();
-       
-       return TRUE;
+
+    return true;
 }
 
 void wxThreadModule::OnExit()
 {
     if ( gs_critsectGui )
     {
+        if ( !wxGuiOwnedByMainThread() )
+        {
+            gs_critsectGui->Enter();
+            gs_bGuiOwnedByMainThread = true;
+        }
+
         gs_critsectGui->Leave();
         delete gs_critsectGui;
         gs_critsectGui = NULL;
@@ -1689,6 +1747,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 )
@@ -1707,9 +1768,7 @@ void WXDLLIMPEXP_BASE wxMutexGuiLeaveOrEnter()
     {
         // some threads are waiting, release the GUI lock if we have it
         if ( wxGuiOwnedByMainThread() )
-        {
             wxMutexGuiLeave();
-        }
         //else: some other worker thread is doing GUI
     }
 }
@@ -1722,7 +1781,7 @@ bool WXDLLIMPEXP_BASE wxGuiOwnedByMainThread()
 // wake up the main thread
 void WXDLLEXPORT wxWakeUpMainThread()
 {
-       wxMacWakeUp() ;
+    wxMacWakeUp();
 }
 
 // ----------------------------------------------------------------------------