]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/carbon/mpthread.cpp
further encapsulation of graphics context, wxdc becoming 'generic'
[wxWidgets.git] / src / mac / carbon / mpthread.cpp
index 52976e92a53341f96497f20f8a1f53e8d8d6355a..30bb2a008789aa84eb8244e3deadf80f0b6a1985 100755 (executable)
@@ -1,19 +1,15 @@
 /////////////////////////////////////////////////////////////////////////////
-// Name:       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
+// Name:      src/mac/carbon/mpthread.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
 /////////////////////////////////////////////////////////////////////////////
 
-#ifdef __GNUG__
-#pragma implementation "thread.h"
-#endif
-
 // ----------------------------------------------------------------------------
 // headers
 // ----------------------------------------------------------------------------
 #include "wx/wxprec.h"
 
 #if defined(__BORLANDC__)
-#pragma hdrstop
+    #pragma hdrstop
 #endif
 
+#if wxUSE_THREADS
+
 #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>
+#else
+#include <DriverServices.h>
+#include <Multiprocessing.h>
+#endif
 #include "wx/mac/uma.h"
 #endif
 
-// trace mask for wxThread operations
-#define TRACE_THREADS   _T("thread")
-
-// you can get additional debugging messages for the semaphore operations
-#define TRACE_SEMA      _T("semaphore")
-
-
 // ----------------------------------------------------------------------------
 // constants
 // ----------------------------------------------------------------------------
 // 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
 };
 
 // ----------------------------------------------------------------------------
@@ -86,7 +80,7 @@ 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 
+// overall number of threads, needed for determining the sleep value of the main
 // event loop
 size_t g_numberOfThreads = 0;
 
@@ -104,57 +98,73 @@ 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 
+    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
 
     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
 */
 
 // ----------------------------------------------------------------------------
 // wxMutex implementation
 // ----------------------------------------------------------------------------
 
-#if 0 
+static bool wxMacMPThreadsInitVerify()
+{
+    static bool hasThreadManager = false ;
+    if ( !hasThreadManager )
+        hasThreadManager = MPLibraryIsLoaded();
+
+    if ( !hasThreadManager )
+    {
+        wxMessageBox( wxT("Error") , wxT("MP Thread Support is not available on this System" ), wxOK ) ;
+        return false ;
+    }
+    return true ;
+}
+
+#if 0
 
 class wxMutexInternal
 {
 public:
-       wxMutexInternal(wxMutexType mutexType) ;
-       ~wxMutexInternal() ;
-       bool IsOk() const { return m_isOk; }
-       
-       wxMutexError Lock() ;
-       wxMutexError TryLock() ;
-       wxMutexError Unlock();
-private:               
+    wxMutexInternal(wxMutexType mutexType) ;
+    ~wxMutexInternal() ;
+    bool IsOk() const { return m_isOk; }
+
+    wxMutexError Lock() ;
+    wxMutexError TryLock() ;
+    wxMutexError Unlock();
+private:
     MPSemaphoreID m_semaphore;
     bool m_isOk ;
 };
 
 wxMutexInternal::wxMutexInternal(wxMutexType mutexType )
 {
+    wxMacMPThreadsInitVerify() ;
+
     m_isOk = false ;
     m_semaphore = kInvalidID ;
-    
+
     OSStatus err = noErr ;
     switch( mutexType )
     {
         case wxMUTEX_DEFAULT :
             {
-               verify_noerr( MPCreateBinarySemaphore( & m_semaphore) );
+                verify_noerr( MPCreateBinarySemaphore( & m_semaphore) );
                 m_isOk = ( m_semaphore != kInvalidID ) ;
             }
             break ;
@@ -170,50 +180,50 @@ wxMutexInternal::wxMutexInternal(wxMutexType mutexType )
 wxMutexInternal::~wxMutexInternal()
 {
     if ( m_semaphore != kInvalidID )
-           MPDeleteSemaphore( m_semaphore);
+        MPDeleteSemaphore( m_semaphore);
 }
 
 wxMutexError wxMutexInternal::Lock()
 {
     wxCHECK_MSG( m_isOk , wxMUTEX_MISC_ERROR , wxT("Invalid Mutex") ) ;
-       OSStatus err = MPWaitOnSemaphore( m_semaphore, kDurationForever);
-       if ( err)
+    OSStatus err = MPWaitOnSemaphore( m_semaphore, kDurationForever);
+    if ( err)
     {
-               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)
+    OSStatus err = MPWaitOnSemaphore( m_semaphore, kDurationImmediate);
+    if ( err)
     {
-               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);
-       if ( err)
+    OSStatus err = MPSignalSemaphore( m_semaphore);
+    if ( err)
     {
-               wxLogSysError(_("Could not unlock mutex"));
-               return wxMUTEX_MISC_ERROR;        
+        wxLogSysError(_("Could not unlock mutex"));
+        return wxMUTEX_MISC_ERROR;
     }
-    
-       return wxMUTEX_NO_ERROR;
+
+    return wxMUTEX_NO_ERROR;
 }
 
 #else
@@ -221,26 +231,27 @@ wxMutexError wxMutexInternal::Unlock()
 class wxMutexInternal
 {
 public:
-       wxMutexInternal(wxMutexType mutexType) ;
-       ~wxMutexInternal() ;
-       bool IsOk() const { return m_isOk; }
-       
-       wxMutexError Lock() ;
-       wxMutexError TryLock() ;
-       wxMutexError Unlock();
-private:               
+    wxMutexInternal(wxMutexType mutexType) ;
+    ~wxMutexInternal() ;
+    bool IsOk() const { return m_isOk; }
+
+    wxMutexError Lock() ;
+    wxMutexError TryLock() ;
+    wxMutexError Unlock();
+private:
     MPCriticalRegionID m_critRegion ;
     bool m_isOk ;
 };
 
 wxMutexInternal::wxMutexInternal(wxMutexType mutexType )
 {
+    wxMacMPThreadsInitVerify() ;
     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") ) ;
 }
@@ -248,50 +259,50 @@ wxMutexInternal::wxMutexInternal(wxMutexType mutexType )
 wxMutexInternal::~wxMutexInternal()
 {
     if ( m_critRegion != kInvalidID )
-           MPDeleteCriticalRegion( m_critRegion);
+        MPDeleteCriticalRegion( m_critRegion);
 }
 
 wxMutexError wxMutexInternal::Lock()
 {
     wxCHECK_MSG( m_isOk , wxMUTEX_MISC_ERROR , wxT("Invalid Mutex") ) ;
-       OSStatus err = MPEnterCriticalRegion( m_critRegion, kDurationForever);
-       if ( err)
+    OSStatus err = MPEnterCriticalRegion( m_critRegion, kDurationForever);
+    if ( err)
     {
-               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 = MPEnterCriticalRegion( m_critRegion, kDurationImmediate);
-       if ( err)
+    OSStatus err = MPEnterCriticalRegion( m_critRegion, kDurationImmediate);
+    if ( err)
     {
-               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);
-       if ( err)
+    OSStatus err = MPExitCriticalRegion( m_critRegion);
+    if ( err)
     {
-               wxLogSysError(_("Could not unlock mutex"));
-               return wxMUTEX_MISC_ERROR;        
+        wxLogSysError(_("Could not unlock mutex"));
+        return wxMUTEX_MISC_ERROR;
     }
-    
-       return wxMUTEX_NO_ERROR;
+
+    return wxMUTEX_NO_ERROR;
 }
 
 #endif
@@ -303,24 +314,24 @@ 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);
+    ~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();
+
 private:
     MPSemaphoreID m_semaphore;
     bool m_isOk ;
@@ -328,16 +339,17 @@ private:
 
 wxSemaphoreInternal::wxSemaphoreInternal(int initialcount, int maxcount)
 {
+    wxMacMPThreadsInitVerify() ;
     m_isOk = false ;
     m_semaphore = kInvalidID ;
-       if ( maxcount == 0 )
+    if ( maxcount == 0 )
     {
-               // make it practically infinite
-               maxcount = INT_MAX;
+        // make it practically infinite
+        maxcount = INT_MAX;
     }
-       verify_noerr( MPCreateSemaphore( maxcount, initialcount, & m_semaphore) );
+    verify_noerr( MPCreateSemaphore( maxcount, initialcount, & m_semaphore) );
     m_isOk = ( m_semaphore != kInvalidID ) ;
-    
+
     if ( !IsOk() )
         wxFAIL_MSG(wxT("Error when creating semaphore") ) ;
 }
@@ -345,31 +357,31 @@ wxSemaphoreInternal::wxSemaphoreInternal(int initialcount, int maxcount)
 wxSemaphoreInternal::~wxSemaphoreInternal()
 {
     if( m_semaphore != kInvalidID )
-           MPDeleteSemaphore( m_semaphore);
+        MPDeleteSemaphore( m_semaphore);
 }
 
 wxSemaError wxSemaphoreInternal::WaitTimeout(unsigned long milliseconds)
 {
-       OSStatus err = MPWaitOnSemaphore( m_semaphore, milliseconds);
-       if ( err)
+    OSStatus err = MPWaitOnSemaphore( m_semaphore, milliseconds);
+    if ( err)
     {
-               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);
-       if ( err)
+    OSStatus err = MPSignalSemaphore( m_semaphore);
+    if ( err)
     {
-               return wxSEMA_MISC_ERROR;
+        return wxSEMA_MISC_ERROR;
     }
-       return wxSEMA_NO_ERROR;
+    return wxSEMA_NO_ERROR;
 }
 
 // ----------------------------------------------------------------------------
@@ -381,56 +393,56 @@ wxSemaError wxSemaphoreInternal::Post()
 class wxConditionInternal
 {
 public:
-       
-       wxConditionInternal(wxMutex& mutex) 
+
+    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);
-       }
-    
+    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);
+    }
+
 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();
        if ( ++ m_waiters == INT_MAX)
     {
@@ -441,24 +453,24 @@ wxCondError wxConditionInternal::WaitTimeout(unsigned long msectimeout)
                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_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)
                                {
@@ -501,15 +513,15 @@ wxCondError wxConditionInternal::WaitTimeout(unsigned long msectimeout)
                }
     }
        m_varSection.Leave();
-       
+
        m_mutex.Lock();
-       
-       if ( err)
+
+    if ( err)
     {
                return err == wxSEMA_TIMEOUT ? wxCOND_TIMEOUT : wxCOND_MISC_ERROR;
     }
-    
-       return wxCOND_NO_ERROR;
+
+    return wxCOND_NO_ERROR;
 }
 
 
@@ -517,36 +529,36 @@ wxCondError wxConditionInternal::DoSignal( bool signalAll)
 {
        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;
     }
-       
+
        if ( 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
     {
                wxSemaError err = m_semaphore.Post();
                wxASSERT( err == wxSEMA_NO_ERROR);
     } while ( -- n);
-       
+
        return wxCOND_NO_ERROR;
 }
 
@@ -705,14 +717,14 @@ public:
                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()
     {
@@ -752,7 +764,7 @@ public:
        // Get the ID of this thread's underlying MP Services task.
        MPTaskID  GetId() const { return m_tid; }
 
-    void SetCancelFlag() { m_cancelled = TRUE; }
+    void SetCancelFlag() { m_cancelled = true; }
     bool WasCancelled() const { return m_cancelled; }
     // exit code
     void SetExitCode(wxThread::ExitCode exitcode) { m_exitcode = exitcode; }
@@ -767,8 +779,8 @@ public:
     {
         wxCriticalSectionLocker lock(m_csJoinFlag);
 
-        m_shouldBeJoined = FALSE;
-        m_isDetached = TRUE;
+        m_shouldBeJoined = false;
+        m_isDetached = true;
     }
 
 private:
@@ -779,7 +791,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;
@@ -839,7 +851,7 @@ OSStatus wxThreadInternal::MacThreadStart(void *parameter)
             pthread->SetState(STATE_EXITED);
         }
     }
-    
+
     if ( dontRunAtAll )
     {
         if ( pthread->m_isDetached )
@@ -861,12 +873,13 @@ OSStatus wxThreadInternal::MacThreadStart(void *parameter)
 
 bool wxThreadInternal::Create(wxThread *thread, unsigned int stackSize)
 {
+    wxMacMPThreadsInitVerify() ;
     wxASSERT_MSG( m_state == STATE_NEW && !m_tid,
                     _T("Create()ing thread twice?") );
 
        OSStatus err = noErr ;
        m_thread = thread;
-       
+
        if ( m_notifyQueueId == kInvalidID )
     {
                OSStatus err = MPCreateQueue( & m_notifyQueueId);
@@ -876,9 +889,9 @@ bool wxThreadInternal::Create(wxThread *thread, unsigned int stackSize)
                        return false;
                }
     }
-       
+
        m_state = STATE_NEW;
-       
+
        err = MPCreateTask( MacThreadStart,
                                                (void*) m_thread,
                                                stackSize,
@@ -887,33 +900,33 @@ bool wxThreadInternal::Create(wxThread *thread, unsigned int stackSize)
                                                0,
                                                0,
                                                &m_tid);
-       
+
        if ( err)
     {
-               wxLogSysError(_("Can't create thread"));                
+               wxLogSysError(_("Can't create thread"));
                return false;
     }
-       
+
        if ( m_prio != WXTHREAD_DEFAULT_PRIORITY )
     {
                SetPriority(m_prio);
     }
-       
+
        return true;
 }
 
 void wxThreadInternal::SetPriority( int priority)
 {
        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
+               // 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);
     }
 }
@@ -949,14 +962,14 @@ void wxThreadInternal::Wait()
             void * param2;
             void * rc;
 
-            OSStatus err = MPWaitOnQueue ( m_notifyQueueId, 
-                                & param1, 
-                                & param2, 
-                                & rc, 
+            OSStatus err = MPWaitOnQueue ( m_notifyQueueId,
+                                & param1,
+                                & param2,
+                                & rc,
                                 kDurationForever);
             if ( err)
             {
-                wxLogSysError( _( "Cannot wait on thread to exit."));
+                wxLogSysError( _( "Cannot wait for thread termination."));
                 rc = (void*) -1;
             }
 
@@ -964,7 +977,7 @@ void wxThreadInternal::Wait()
             // but we don't need this here
             m_exitcode = rc;
 
-            m_shouldBeJoined = FALSE;
+            m_shouldBeJoined = false;
         }
     }
 
@@ -1059,7 +1072,7 @@ wxThread::wxThread(wxThreadKind kind)
 {
        g_numberOfThreads++;
        m_internal = new wxThreadInternal();
-       
+
        m_isDetached = (kind == wxTHREAD_DETACHED);
 }
 
@@ -1088,7 +1101,7 @@ wxThread::~wxThread()
 wxThreadError wxThread::Create(unsigned int stackSize)
 {
        wxCriticalSectionLocker lock(m_critsect);
-       
+
     if ( m_isDetached )
     {
         m_internal->Detach() ;
@@ -1098,7 +1111,7 @@ wxThreadError wxThread::Create(unsigned int stackSize)
         m_internal->SetState(STATE_EXITED);
         return wxTHREAD_NO_RESOURCE;
     }
-       
+
        return wxTHREAD_NO_ERROR;
 }
 
@@ -1149,16 +1162,9 @@ wxThreadError wxThread::Resume()
     switch ( state )
     {
         case STATE_PAUSED:
-            wxLogTrace(TRACE_THREADS, _T("Thread %ld suspended, resuming."),
-                       GetId());
-
             m_internal->Resume();
-
             return wxTHREAD_NO_ERROR;
-
         case STATE_EXITED:
-            wxLogTrace(TRACE_THREADS, _T("Thread %ld exited, won't resume."),
-                       GetId());
             return wxTHREAD_NO_ERROR;
 
         default:
@@ -1290,7 +1296,7 @@ void wxThread::Exit(ExitCode status)
     OnExit();
 
     MPTerminateTask( m_internal->GetId() , (long) status) ;
-    
+
     if ( IsDetached() )
     {
         delete this;
@@ -1391,10 +1397,10 @@ bool wxThread::IsAlive() const
     {
         case STATE_RUNNING:
         case STATE_PAUSED:
-            return TRUE;
+            return true;
 
         default:
-            return FALSE;
+            return false;
     }
 }
 
@@ -1414,7 +1420,7 @@ class wxThreadModule : public wxModule
 public:
        virtual bool OnInit();
        virtual void OnExit();
-       
+
 private:
                DECLARE_DYNAMIC_CLASS(wxThreadModule)
 };
@@ -1423,27 +1429,23 @@ IMPLEMENT_DYNAMIC_CLASS(wxThreadModule, wxModule)
 
 bool wxThreadModule::OnInit()
 {
-       bool hasThreadManager = false ;
-       hasThreadManager = MPLibraryIsLoaded();
-    
-       if ( !hasThreadManager )
+       if ( !wxMacMPThreadsInitVerify() )
     {
-               wxMessageBox( "Error" , "MP Thread Support is not available on this System" , wxOK ) ;
-               return FALSE ;
+               return false ;
     }
-       
+
        verify_noerr( MPAllocateTaskStorageIndex( &gs_tlsForWXThread ) ) ;
        // main thread's This() is NULL
        verify_noerr( MPSetTaskStorageValue( gs_tlsForWXThread , NULL ) ) ;
 
        gs_idMainThread = wxThread::GetCurrentId() ;
-       
+
     gs_critsectWaitingForGui = new wxCriticalSection();
 
     gs_critsectGui = new wxCriticalSection();
     gs_critsectGui->Enter();
-       
-       return TRUE;
+
+       return true;
 }
 
 void wxThreadModule::OnExit()