]> git.saurik.com Git - wxWidgets.git/blobdiff - src/osx/carbon/thread.cpp
Don't call wxSafeYield() from wxGenericListCtrl::EditLabel().
[wxWidgets.git] / src / osx / carbon / thread.cpp
index d8bcd279da609785db1c81349a7e0c8da904675e..9b2573b6c049a247f175fd1c94f1323e335c17eb 100644 (file)
@@ -1,5 +1,5 @@
 /////////////////////////////////////////////////////////////////////////////
-// Name:        src/mac/carbon/thread.cpp
+// Name:        src/osx/carbon/thread.cpp
 // Purpose:     wxThread Implementation
 // Author:      Original from Wolfram Gloger/Guilhem Lavaux/Vadim Zeitlin
 // Modified by: Aj Lavin, Stefan Csomor
@@ -49,7 +49,7 @@ enum wxThreadState
 // ----------------------------------------------------------------------------
 
 // the task ID of the main thread
-static wxThreadIdType gs_idMainThread = kInvalidID;
+wxThreadIdType wxThread::ms_idMainThread = kInvalidID;
 
 // this is the Per-Task Storage for the pointer to the appropriate wxThread
 TaskStorageIndex gs_tlsForWXThread = 0;
@@ -106,7 +106,7 @@ MPCriticalRegionID gs_guiCritical = kInvalidID;
 // wxCriticalSection
 // ----------------------------------------------------------------------------
 
-wxCriticalSection::wxCriticalSection()
+wxCriticalSection::wxCriticalSection( wxCriticalSectionType WXUNUSED(critSecType) )
 {
     MPCreateCriticalRegion( (MPCriticalRegionID*) &m_critRegion );
 }
@@ -121,6 +121,11 @@ void wxCriticalSection::Enter()
     MPEnterCriticalRegion( (MPCriticalRegionID) m_critRegion, kDurationForever );
 }
 
+bool wxCriticalSection::TryEnter()
+{
+    return MPEnterCriticalRegion( (MPCriticalRegionID) m_critRegion, kDurationImmediate ) == noErr;
+}
+
 void wxCriticalSection::Leave()
 {
     MPExitCriticalRegion( (MPCriticalRegionID) m_critRegion );
@@ -134,270 +139,6 @@ void wxCriticalSection::Leave()
 #define wxUSE_MAC_CRITICAL_REGION_MUTEX 1
 #define wxUSE_MAC_PTHREADS_MUTEX 0
 
-#if wxUSE_MAC_PTHREADS_MUTEX
-
-#include <pthread.h>
-
-
-class wxMutexInternal
-{
-public:
-    wxMutexInternal( wxMutexType mutexType );
-    ~wxMutexInternal();
-
-    wxMutexError Lock();
-    wxMutexError TryLock();
-    wxMutexError Unlock();
-
-    bool IsOk() const
-    { return m_isOk; }
-
-private:
-    pthread_mutex_t m_mutex;
-    bool m_isOk;
-
-    // wxConditionInternal uses our m_mutex
-    friend class wxConditionInternal;
-};
-
-#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 );
-#endif
-
-wxMutexInternal::wxMutexInternal( wxMutexType mutexType )
-{
-    int err;
-    switch ( mutexType )
-    {
-        case wxMUTEX_RECURSIVE:
-            // support recursive locks like Win32, i.e. a thread can lock a
-            // mutex which it had itself already locked
-            //
-            // unfortunately initialization of recursive mutexes is non
-            // portable, so try several methods
-#ifdef HAVE_PTHREAD_MUTEXATTR_T
-            {
-                pthread_mutexattr_t attr;
-                pthread_mutexattr_init( &attr );
-                pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_RECURSIVE );
-
-                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
-            // first to a temp var - assigning directly to m_mutex wouldn't
-            // even compile
-            {
-                pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
-                m_mutex = mutex;
-            }
-#else // no recursive mutexes
-            err = EINVAL;
-#endif // HAVE_PTHREAD_MUTEXATTR_T/...
-            break;
-
-        default:
-            wxFAIL_MSG( wxT("unknown mutex type") );
-            // fall through
-
-        case wxMUTEX_DEFAULT:
-            err = pthread_mutex_init( &m_mutex, NULL );
-            break;
-    }
-
-    m_isOk = err == 0;
-    if ( !m_isOk )
-    {
-        wxLogApiError( wxT("pthread_mutex_init()"), err );
-    }
-}
-
-wxMutexInternal::~wxMutexInternal()
-{
-    if ( m_isOk )
-    {
-        int err = pthread_mutex_destroy( &m_mutex );
-        if ( err != 0 )
-        {
-            wxLogApiError( wxT("pthread_mutex_destroy()"), err );
-        }
-    }
-}
-
-wxMutexError wxMutexInternal::Lock()
-{
-    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( wxT("mutex deadlock prevented") );
-            return wxMUTEX_DEAD_LOCK;
-
-        case EINVAL:
-            wxLogDebug( wxT("pthread_mutex_lock(): mutex not initialized.") );
-            break;
-
-        case 0:
-            return wxMUTEX_NO_ERROR;
-
-        default:
-            wxLogApiError( wxT("pthread_mutex_lock()"), err );
-    }
-
-    return wxMUTEX_MISC_ERROR;
-}
-
-wxMutexError wxMutexInternal::TryLock()
-{
-    int err = pthread_mutex_trylock( &m_mutex );
-    switch ( err )
-    {
-        case EBUSY:
-            // not an error: mutex is already locked, but we're prepared for this case
-            return wxMUTEX_BUSY;
-
-        case EINVAL:
-            wxLogDebug( wxT("pthread_mutex_trylock(): mutex not initialized.") );
-            break;
-
-        case 0:
-            return wxMUTEX_NO_ERROR;
-
-        default:
-            wxLogApiError( wxT("pthread_mutex_trylock()"), err );
-    }
-
-    return wxMUTEX_MISC_ERROR;
-}
-
-wxMutexError wxMutexInternal::Unlock()
-{
-    int err = pthread_mutex_unlock( &m_mutex );
-    switch ( err )
-    {
-        case EPERM:
-            // we don't own the mutex
-            return wxMUTEX_UNLOCKED;
-
-        case EINVAL:
-            wxLogDebug( wxT("pthread_mutex_unlock(): mutex not initialized.") );
-            break;
-
-        case 0:
-            return wxMUTEX_NO_ERROR;
-
-        default:
-            wxLogApiError( wxT("pthread_mutex_unlock()"), err );
-    }
-
-    return wxMUTEX_MISC_ERROR;
-}
-
-#endif
-
-#if wxUSE_MAC_SEMAPHORE_MUTEX
-
-class wxMutexInternal
-{
-public:
-    wxMutexInternal( wxMutexType mutexType );
-    virtual ~wxMutexInternal();
-
-    bool IsOk() const
-    { return m_isOk; }
-
-    wxMutexError Lock();
-    wxMutexError TryLock();
-    wxMutexError Unlock();
-
-private:
-    MPSemaphoreID m_semaphore;
-    bool m_isOk;
-};
-
-wxMutexInternal::wxMutexInternal(wxMutexType 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;
-
-        case wxMUTEX_RECURSIVE :
-            wxFAIL_MSG( wxT("Recursive Mutex not supported yet") );
-            break;
-
-        default :
-            wxFAIL_MSG( wxT("Unknown mutex type") );
-            break;
-    }
-}
-
-wxMutexInternal::~wxMutexInternal()
-{
-    if ( m_semaphore != kInvalidID )
-        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 != noErr)
-    {
-        wxLogSysError( wxT("Could not lock mutex") );
-
-        return wxMUTEX_MISC_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 != noErr)
-    {
-        if (err == kMPTimeoutErr)
-            return wxMUTEX_BUSY;
-
-        wxLogSysError( wxT("Could not try lock mutex") );
-
-        return wxMUTEX_MISC_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 != noErr)
-    {
-        wxLogSysError( wxT("Could not unlock mutex") );
-        return wxMUTEX_MISC_ERROR;
-    }
-
-    return wxMUTEX_NO_ERROR;
-}
-
-#endif
-
 #if wxUSE_MAC_CRITICAL_REGION_MUTEX
 
 class wxMutexInternal
@@ -583,177 +324,6 @@ wxSemaError wxSemaphoreInternal::Post()
 // wxCondition implementation
 // ----------------------------------------------------------------------------
 
-#if 0
-
-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;
-    }
-
-    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 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_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;
-        }
-    }
-    else
-    {
-        // 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();
-        }
-    }
-
-    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_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;
-}
-
-#else
 class wxConditionInternal
 {
 public:
@@ -778,7 +348,7 @@ private:
     wxMutex& m_mutex;
     wxSemaphore m_semaphore;
 
-    DECLARE_NO_COPY_CLASS(wxConditionInternal)
+    wxDECLARE_NO_COPY_CLASS(wxConditionInternal);
 };
 
 wxConditionInternal::wxConditionInternal( wxMutex& mutex )
@@ -884,7 +454,6 @@ wxCondError wxConditionInternal::Broadcast()
 
     return wxCOND_NO_ERROR;
 }
-#endif
 
 // ----------------------------------------------------------------------------
 // wxCriticalSection implementation
@@ -1095,7 +664,7 @@ bool wxThreadInternal::Create( wxThread *thread, unsigned int stackSize )
         OSStatus err = MPCreateQueue( &m_notifyQueueId );
         if (err != noErr)
         {
-            wxLogSysError( wxT("Cant create the thread event queue") );
+            wxLogSysError( wxT("Can't create the thread event queue") );
 
             return false;
         }
@@ -1232,11 +801,6 @@ wxThread *wxThread::This()
     return thr;
 }
 
-bool wxThread::IsMain()
-{
-    return GetCurrentId() == gs_idMainThread || gs_idMainThread == kInvalidID ;
-}
-
 #ifdef Yield
 #undef Yield
 #endif
@@ -1284,7 +848,6 @@ wxThread::~wxThread()
 
     g_numberOfThreads--;
 
-#ifdef __WXDEBUG__
     m_critsect.Enter();
 
     // check that the thread either exited or couldn't be created
@@ -1297,7 +860,6 @@ wxThread::~wxThread()
     }
 
     m_critsect.Leave();
-#endif
 
     wxDELETE( m_internal ) ;
 }
@@ -1336,7 +898,7 @@ wxThreadError wxThread::Run()
 wxThreadError wxThread::Pause()
 {
     wxCHECK_MSG( This() != this, wxTHREAD_MISC_ERROR,
-                 _T("a thread can't pause itself") );
+                 wxT("a thread can't pause itself") );
 
     wxCriticalSectionLocker lock(m_critsect);
 
@@ -1383,7 +945,7 @@ wxThreadError wxThread::Resume()
 // exiting thread
 // -----------------------------------------------------------------------------
 
-wxThread::ExitCode wxThread::Wait()
+wxThread::ExitCode wxThread::Wait(wxThreadWait WXUNUSED(waitMode))
 {
     wxCHECK_MSG( This() != this, (ExitCode)-1,
                  wxT("a thread can't wait for itself") );
@@ -1396,7 +958,7 @@ wxThread::ExitCode wxThread::Wait()
     return m_internal->GetExitCode();
 }
 
-wxThreadError wxThread::Delete(ExitCode *rc)
+wxThreadError wxThread::Delete(ExitCode *rc, wxThreadWait WXUNUSED(waitMode))
 {
     wxCHECK_MSG( This() != this, wxTHREAD_MISC_ERROR,
                  wxT("a thread can't delete itself") );
@@ -1571,14 +1133,14 @@ void wxThread::SetPriority(unsigned int prio)
 
 unsigned int wxThread::GetPriority() const
 {
-    wxCriticalSectionLocker lock((wxCriticalSection &)m_critsect); // const_cast
+    wxCriticalSectionLocker lock(const_cast<wxCriticalSection &>(m_critsect));
 
     return m_internal->GetPriority();
 }
 
 unsigned long wxThread::GetId() const
 {
-    wxCriticalSectionLocker lock((wxCriticalSection &)m_critsect); // const_cast
+    wxCriticalSectionLocker lock(const_cast<wxCriticalSection &>(m_critsect));
 
     return (unsigned long)m_internal->GetId();
 }
@@ -1634,8 +1196,8 @@ IMPLEMENT_DYNAMIC_CLASS(wxThreadModule, wxModule)
 
 bool wxThreadModule::OnInit()
 {
-    bool hasThreadManager = 
-#ifdef __LP64__ 
+    bool hasThreadManager =
+#ifdef __LP64__
         true ; // TODO VERIFY IN NEXT BUILD
 #else
         MPLibraryIsLoaded();
@@ -1652,7 +1214,7 @@ bool wxThreadModule::OnInit()
     verify_noerr( MPAllocateTaskStorageIndex( &gs_tlsForWXThread ) ) ;
     verify_noerr( MPSetTaskStorageValue( gs_tlsForWXThread, 0 ) ) ;
 
-    gs_idMainThread = wxThread::GetCurrentId();
+    wxThread::ms_idMainThread = wxThread::GetCurrentId();
     gs_critsectWaitingForGui = new wxCriticalSection();
 
     gs_critsectGui = new wxCriticalSection();
@@ -1672,12 +1234,10 @@ void wxThreadModule::OnExit()
         }
 
         gs_critsectGui->Leave();
-        delete gs_critsectGui;
-        gs_critsectGui = NULL;
+        wxDELETE(gs_critsectGui);
     }
 
-    delete gs_critsectWaitingForGui;
-    gs_critsectWaitingForGui = NULL;
+    wxDELETE(gs_critsectWaitingForGui);
 }
 
 // ----------------------------------------------------------------------------