]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/carbon/thread.cpp
carbon event handlers for app level
[wxWidgets.git] / src / mac / carbon / thread.cpp
index a8243467ed776479f8c49ec19c51c8774ca9d3e7..75db6e539e8c3ca261f1199b7d4e6adee95736bc 100644 (file)
 #include "wx/module.h"
 #include "wx/thread.h"
 
+#ifdef __WXMAC__
+#include <Threads.h>
+#include "wx/mac/uma.h"
+#endif
+
 // ----------------------------------------------------------------------------
 // constants
 // ----------------------------------------------------------------------------
@@ -63,13 +68,15 @@ static bool gs_waitingForThread = FALSE ;
 class wxMacStCritical
 {
 public :
-    wxMacStCritical() 
+    wxMacStCritical()
     {
-        ThreadBeginCritical() ;
+        if ( UMASystemIsInitialized() )
+            ThreadBeginCritical() ;
     }
     ~wxMacStCritical()
     {
-        ThreadEndCritical() ;
+        if ( UMASystemIsInitialized() )
+            ThreadEndCritical() ;
     }
 };
 
@@ -85,7 +92,7 @@ public:
         m_owner = kNoThreadID ;
     }
 
-    ~wxMutexInternal() 
+    ~wxMutexInternal()
     {
     }
 
@@ -114,19 +121,21 @@ wxMutex::~wxMutex()
 wxMutexError wxMutex::Lock()
 {
     wxMacStCritical critical ;
-    
-    OSErr err ;
-    ThreadID current = kNoThreadID;
-    err = ::MacGetCurrentThread(&current);
-    // if we are not the owner, add this thread to the list of waiting threads, stop this thread
-    // and invoke the scheduler to continue executing the owner's thread
-    while ( m_internal->m_owner != kNoThreadID && m_internal->m_owner != current) 
-    {
-        m_internal->m_waiters.Add(current);
-        err = ::SetThreadStateEndCritical(kCurrentThreadID, kStoppedThreadState, m_internal->m_owner);
-        err = ::ThreadBeginCritical();
+    if ( UMASystemIsInitialized() )
+    {
+        OSErr err ;
+        ThreadID current = kNoThreadID;
+        err = ::MacGetCurrentThread(&current);
+        // if we are not the owner, add this thread to the list of waiting threads, stop this thread
+        // and invoke the scheduler to continue executing the owner's thread
+        while ( m_internal->m_owner != kNoThreadID && m_internal->m_owner != current)
+        {
+            m_internal->m_waiters.Add(current);
+            err = ::SetThreadStateEndCritical(kCurrentThreadID, kStoppedThreadState, m_internal->m_owner);
+            err = ::ThreadBeginCritical();
+        }
+        m_internal->m_owner = current;
     }
-    m_internal->m_owner = current;
     m_locked++;
 
     return wxMUTEX_NO_ERROR;
@@ -135,15 +144,16 @@ wxMutexError wxMutex::Lock()
 wxMutexError wxMutex::TryLock()
 {
     wxMacStCritical critical ;
-    
-    OSErr err ;
-    ThreadID current = kNoThreadID;
-    ::MacGetCurrentThread(&current);
-    // if we are not the owner, give an error back
-    if ( m_internal->m_owner != kNoThreadID && m_internal->m_owner != current ) 
-        return wxMUTEX_BUSY;
-        
-    m_internal->m_owner = current;
+    if ( UMASystemIsInitialized() )
+    {
+        ThreadID current = kNoThreadID;
+        ::MacGetCurrentThread(&current);
+        // if we are not the owner, give an error back
+        if ( m_internal->m_owner != kNoThreadID && m_internal->m_owner != current )
+            return wxMUTEX_BUSY;
+
+        m_internal->m_owner = current;
+    }
     m_locked++;
 
    return wxMUTEX_NO_ERROR;
@@ -151,32 +161,39 @@ wxMutexError wxMutex::TryLock()
 
 wxMutexError wxMutex::Unlock()
 {
-    OSErr err;
-    err = ::ThreadBeginCritical();
-    
-    if (m_locked > 0)
-        m_locked--;
+    if ( UMASystemIsInitialized() )
+    {
+        OSErr err;
+        err = ::ThreadBeginCritical();
 
-    // this mutex is not owned by anybody anmore
-    m_internal->m_owner = kNoThreadID;
+        if (m_locked > 0)
+            m_locked--;
 
-    // now pass on to the first waiting thread
-    ThreadID firstWaiting = kNoThreadID;
-    bool found = false;
-    while (!m_internal->m_waiters.IsEmpty() && !found) 
+        // this mutex is not owned by anybody anmore
+        m_internal->m_owner = kNoThreadID;
+
+        // now pass on to the first waiting thread
+        ThreadID firstWaiting = kNoThreadID;
+        bool found = false;
+        while (!m_internal->m_waiters.IsEmpty() && !found)
+        {
+            firstWaiting = m_internal->m_waiters[0];
+            err = ::SetThreadState(firstWaiting, kReadyThreadState, kNoThreadID);
+            // in case this was not successful (dead thread), we just loop on and reset the id
+            found = (err != threadNotFoundErr);
+            if ( !found )
+                firstWaiting = kNoThreadID ;
+            m_internal->m_waiters.RemoveAt(0) ;
+        }
+        // now we have a valid firstWaiting thread, which has been scheduled to run next, just end the
+        // critical section and invoke the scheduler
+        err = ::SetThreadStateEndCritical(kCurrentThreadID, kReadyThreadState, firstWaiting);
+    }
+    else
     {
-        firstWaiting = m_internal->m_waiters[0];
-        err = ::SetThreadState(firstWaiting, kReadyThreadState, kNoThreadID);
-        // in case this was not successful (dead thread), we just loop on and reset the id
-        found = (err != threadNotFoundErr);    
-        if ( !found )
-            firstWaiting = kNoThreadID ;
-        m_internal->m_waiters.RemoveAt(0) ;
+        if (m_locked > 0)
+            m_locked--;
     }
-    // now we have a valid firstWaiting thread, which has been scheduled to run next, just end the
-    // critical section and invoke the scheduler
-    err = ::SetThreadStateEndCritical(kCurrentThreadID, kReadyThreadState, firstWaiting);
-
     return wxMUTEX_NO_ERROR;
 }
 
@@ -187,7 +204,7 @@ wxMutexError wxMutex::Unlock()
 class wxConditionInternal
 {
 public:
-    wxConditionInternal()
+    wxConditionInternal(wxMutex& mutex) : m_mutex(mutex)
     {
         m_excessSignals = 0 ;
     }
@@ -229,11 +246,12 @@ public:
 
     wxArrayLong m_waiters ;
     wxInt32     m_excessSignals ;
+    wxMutex&    m_mutex;
 };
 
-wxCondition::wxCondition()
+wxCondition::wxCondition(wxMutex& mutex)
 {
-    m_internal = new wxConditionInternal;
+    m_internal = new wxConditionInternal(mutex);
 }
 
 wxCondition::~wxCondition()
@@ -246,10 +264,9 @@ void wxCondition::Wait()
     (void)m_internal->Wait(0xFFFFFFFFL);
 }
 
-bool wxCondition::Wait(unsigned long sec,
-                       unsigned long nsec)
+bool wxCondition::Wait(unsigned long timeout_millis)
 {
-    return m_internal->Wait(sec*1000 + nsec/1000000);
+    return m_internal->Wait(timeout_millis);
 }
 
 void wxCondition::Signal()
@@ -267,7 +284,7 @@ void wxCondition::Broadcast()
     // this works because all these threads are already waiting and so each
     // SetEvent() inside Signal() is really a PulseEvent() because the event
     // state is immediately returned to non-signaled
-    for ( int i = 0; i < m_internal->m_waiters.Count(); i++ )
+    for ( size_t i = 0; i < m_internal->m_waiters.Count(); i++ )
     {
         Signal();
     }
@@ -319,7 +336,7 @@ public:
     // thread priority
     void SetPriority(unsigned int priority);
     unsigned int GetPriority() const { return m_priority; }
-    
+
     void SetResult( void *res ) { m_result = res ; }
     void *GetResult() { return m_result ; }
 
@@ -405,7 +422,7 @@ bool wxThreadInternal::Create(wxThread *thread, unsigned int stackSize)
 bool wxThreadInternal::Suspend()
 {
     OSErr err ;
-    
+
     ::ThreadBeginCritical();
 
     if ( m_state != STATE_RUNNING )
@@ -430,18 +447,18 @@ bool wxThreadInternal::Resume()
 
     wxASSERT( err == noErr ) ;
     wxASSERT( current != m_tid ) ;
-        
+
     ::ThreadBeginCritical();
     if ( m_state != STATE_PAUSED && m_state != STATE_NEW )
     {
         ::ThreadEndCritical() ;
         wxLogSysError(_("Can not resume thread %x"), m_tid);
         return FALSE;
-        
+
     }
     err = ::SetThreadStateEndCritical(m_tid, kReadyThreadState, kNoThreadID);
     wxASSERT( err == noErr ) ;
-    
+
     m_state = STATE_RUNNING;
     ::ThreadEndCritical() ;
     ::YieldToAnyThread() ;
@@ -453,13 +470,13 @@ bool wxThreadInternal::Resume()
 wxThread *wxThread::This()
 {
     wxMacStCritical critical ;
-    
+
     ThreadID current ;
     OSErr err ;
-    
+
     err = MacGetCurrentThread( &current ) ;
-    
-    for ( int i = 0 ; i < s_threads.Count() ; ++i )
+
+    for ( size_t i = 0 ; i < s_threads.Count() ; ++i )
     {
         if ( ( (wxThread*) s_threads[i] )->GetId() == current )
             return (wxThread*) s_threads[i] ;
@@ -473,7 +490,7 @@ bool wxThread::IsMain()
 {
     ThreadID current ;
     OSErr err ;
-    
+
     err = MacGetCurrentThread( &current ) ;
     return current == gs_idMainThread;
 }
@@ -490,7 +507,7 @@ void wxThread::Yield()
 void wxThread::Sleep(unsigned long milliseconds)
 {
         clock_t start = clock() ;
-        do 
+        do
         {
             YieldToAnyThread() ;
         } while( clock() - start < milliseconds / CLOCKS_PER_SEC ) ;
@@ -502,6 +519,13 @@ int wxThread::GetCPUCount()
     return 1;
 }
 
+unsigned long wxThread::GetCurrentId()
+{
+    ThreadID current ;
+    MacGetCurrentThread( &current ) ;
+    return (unsigned long)current;
+}
+
 bool wxThread::SetConcurrency(size_t level)
 {
     wxASSERT_MSG( IsMain(), _T("should only be called from the main thread") );
@@ -517,7 +541,7 @@ bool wxThread::SetConcurrency(size_t level)
         // processor system it doesn't make much sense anyhow
         return level == 1;
     }
-    
+
     return TRUE ;
 }
 
@@ -728,7 +752,7 @@ void wxThread::Exit(ExitCode status)
 
     m_internal->SetResult( status ) ;
 
-/*    
+/*
 #if defined(__VISUALC__) || (defined(__BORLANDC__) && (__BORLANDC__ >= 0x500))
     _endthreadex((unsigned)status);
 #else // !VC++
@@ -844,7 +868,7 @@ bool WXDLLEXPORT wxGuiOwnedByMainThread()
     return false ;
 }
 
-// wake up the main thread 
+// wake up the main thread
 void WXDLLEXPORT wxWakeUpMainThread()
 {
     wxMacWakeUp() ;