]> git.saurik.com Git - wxWidgets.git/blobdiff - src/unix/threadpsx.cpp
first attempt for full screen implementation
[wxWidgets.git] / src / unix / threadpsx.cpp
index b4b91685b9d24b9eb12619421cda46bc92fbbb92..3da088548daaf881646ef59286630d172693e54c 100644 (file)
 // headers
 // ----------------------------------------------------------------------------
 
 // headers
 // ----------------------------------------------------------------------------
 
-#ifdef __GNUG__
+#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
     #pragma implementation "thread.h"
 #endif
 
     #pragma implementation "thread.h"
 #endif
 
-#include "wx/defs.h"
+// for compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
 
 #if wxUSE_THREADS
 
 
 #if wxUSE_THREADS
 
     #include <sys/resource.h>
 #endif
 
     #include <sys/resource.h>
 #endif
 
+#ifdef __VMS
+    #define THR_ID(thr) ((long long)(thr)->GetId())
+#else
+    #define THR_ID(thr) ((long)(thr)->GetId())
+#endif
+
 // ----------------------------------------------------------------------------
 // constants
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 // constants
 // ----------------------------------------------------------------------------
@@ -106,7 +113,7 @@ WX_DEFINE_ARRAY(wxThread *, wxArrayThread);
 static wxArrayThread gs_allThreads;
 
 // the id of the main thread
 static wxArrayThread gs_allThreads;
 
 // the id of the main thread
-static pthread_t gs_tidMain;
+static pthread_t gs_tidMain = (pthread_t)-1;
 
 // the key for the pointer to the associated wxThread object
 static pthread_key_t gs_keySelf;
 
 // the key for the pointer to the associated wxThread object
 static pthread_key_t gs_keySelf;
@@ -122,10 +129,10 @@ static wxMutex *gs_mutexDeleteThread = (wxMutex *)NULL;
 // gs_nThreadsBeingDeleted will have been deleted
 static wxCondition *gs_condAllDeleted = (wxCondition *)NULL;
 
 // gs_nThreadsBeingDeleted will have been deleted
 static wxCondition *gs_condAllDeleted = (wxCondition *)NULL;
 
-#if wxUSE_GUI
-    // this mutex must be acquired before any call to a GUI function
-    static wxMutex *gs_mutexGui;
-#endif // wxUSE_GUI
+// this mutex must be acquired before any call to a GUI function
+// (it's not inside #if wxUSE_GUI because this file is compiled as part
+// of wxBase)
+static wxMutex *gs_mutexGui = NULL;
 
 // when we wait for a thread to exit, we're blocking on a condition which the
 // thread signals in its SignalExit() method -- but this condition can't be a
 
 // when we wait for a thread to exit, we're blocking on a condition which the
 // thread signals in its SignalExit() method -- but this condition can't be a
@@ -166,6 +173,12 @@ private:
     friend class wxConditionInternal;
 };
 
     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;
 wxMutexInternal::wxMutexInternal(wxMutexType mutexType)
 {
     int err;
@@ -488,14 +501,14 @@ wxSemaError wxSemaphoreInternal::Wait()
     while ( m_count == 0 )
     {
         wxLogTrace(TRACE_SEMA,
     while ( m_count == 0 )
     {
         wxLogTrace(TRACE_SEMA,
-                   "Thread %ld waiting for semaphore to become signalled",
+                   _T("Thread %ld waiting for semaphore to become signalled"),
                    wxThread::GetCurrentId());
 
         if ( m_cond.Wait() != wxCOND_NO_ERROR )
             return wxSEMA_MISC_ERROR;
 
         wxLogTrace(TRACE_SEMA,
                    wxThread::GetCurrentId());
 
         if ( m_cond.Wait() != wxCOND_NO_ERROR )
             return wxSEMA_MISC_ERROR;
 
         wxLogTrace(TRACE_SEMA,
-                   "Thread %ld finished waiting for semaphore, count = %lu",
+                   _T("Thread %ld finished waiting for semaphore, count = %lu"),
                    wxThread::GetCurrentId(), (unsigned long)m_count);
     }
 
                    wxThread::GetCurrentId(), (unsigned long)m_count);
     }
 
@@ -532,8 +545,17 @@ wxSemaError wxSemaphoreInternal::WaitTimeout(unsigned long milliseconds)
             return wxSEMA_TIMEOUT;
         }
 
             return wxSEMA_TIMEOUT;
         }
 
-        if ( m_cond.Wait(remainingTime) != wxCOND_NO_ERROR )
-            return wxSEMA_MISC_ERROR;
+        switch ( m_cond.WaitTimeout(remainingTime) )
+        {
+            case wxCOND_TIMEOUT:
+                return wxSEMA_TIMEOUT;
+
+            default:
+                return wxSEMA_MISC_ERROR;
+
+            case wxCOND_NO_ERROR:
+                ;
+        }
     }
 
     m_count--;
     }
 
     m_count--;
@@ -553,7 +575,7 @@ wxSemaError wxSemaphoreInternal::Post()
     m_count++;
 
     wxLogTrace(TRACE_SEMA,
     m_count++;
 
     wxLogTrace(TRACE_SEMA,
-               "Thread %ld about to signal semaphore, count = %lu",
+               _T("Thread %ld about to signal semaphore, count = %lu"),
                wxThread::GetCurrentId(), (unsigned long)m_count);
 
     return m_cond.Signal() == wxCOND_NO_ERROR ? wxSEMA_NO_ERROR
                wxThread::GetCurrentId(), (unsigned long)m_count);
 
     return m_cond.Signal() == wxCOND_NO_ERROR ? wxSEMA_NO_ERROR
@@ -656,7 +678,7 @@ public:
 private:
     pthread_t     m_threadId;   // id of the thread
     wxThreadState m_state;      // see wxThreadState enum
 private:
     pthread_t     m_threadId;   // id of the thread
     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;
 
     // this flag is set when the thread should terminate
     bool m_cancelled;
@@ -696,12 +718,8 @@ void *wxThreadInternal::PthreadStart(wxThread *thread)
 {
     wxThreadInternal *pthread = thread->m_internal;
 
 {
     wxThreadInternal *pthread = thread->m_internal;
 
-#ifdef __VMS
-   wxLogTrace(TRACE_THREADS, _T("Thread %ld started."), (long long)pthread->GetId());
-#else
-   wxLogTrace(TRACE_THREADS, _T("Thread %ld started."), (long)pthread->GetId());
-#endif
-   
+    wxLogTrace(TRACE_THREADS, _T("Thread %ld started."), THR_ID(pthread));
+
     // associate the thread pointer with the newly created thread so that
     // wxThread::This() will work
     int rc = pthread_setspecific(gs_keySelf, thread);
     // associate the thread pointer with the newly created thread so that
     // wxThread::This() will work
     int rc = pthread_setspecific(gs_keySelf, thread);
@@ -737,22 +755,16 @@ void *wxThreadInternal::PthreadStart(wxThread *thread)
     if ( !dontRunAtAll )
     {
         // call the main entry
     if ( !dontRunAtAll )
     {
         // call the main entry
-        wxLogTrace(TRACE_THREADS, _T("Thread %ld about to enter its Entry()."),
-#ifdef __VMS
-                   (long long)pthread->GetId());
-#else
-                   (long)pthread->GetId());
-#endif
-       
+        wxLogTrace(TRACE_THREADS,
+                   _T("Thread %ld about to enter its Entry()."),
+                   THR_ID(pthread));
+
         pthread->m_exitcode = thread->Entry();
 
         pthread->m_exitcode = thread->Entry();
 
-        wxLogTrace(TRACE_THREADS, _T("Thread %ld Entry() returned %lu."),
-#ifdef __VMS
-                   (long long)pthread->GetId(), (unsigned long)pthread->m_exitcode);
-#else
-                   (long)pthread->GetId(), (unsigned long)pthread->m_exitcode);
-#endif
-       
+        wxLogTrace(TRACE_THREADS,
+                   _T("Thread %ld Entry() returned %lu."),
+                   THR_ID(pthread), (unsigned long)pthread->m_exitcode);
+
         {
             wxCriticalSectionLocker lock(thread->m_critsect);
 
         {
             wxCriticalSectionLocker lock(thread->m_critsect);
 
@@ -861,12 +873,9 @@ void wxThreadInternal::Wait()
         wxMutexGuiLeave();
 
     wxLogTrace(TRACE_THREADS,
         wxMutexGuiLeave();
 
     wxLogTrace(TRACE_THREADS,
-#ifdef __VMS
-               _T("Starting to wait for thread %ld to exit."), (long long)GetId());
-#else
-               _T("Starting to wait for thread %ld to exit."), (long)GetId());
-#endif
-   
+               _T("Starting to wait for thread %ld to exit."),
+               THR_ID(this));
+
     // to avoid memory leaks we should call pthread_join(), but it must only be
     // done once so use a critical section to serialize the code below
     {
     // to avoid memory leaks we should call pthread_join(), but it must only be
     // done once so use a critical section to serialize the code below
     {
@@ -884,8 +893,7 @@ void wxThreadInternal::Wait()
                 // wxLogDebug: it is possible to bring the system to its knees
                 // by creating too many threads and not joining them quite
                 // easily
                 // wxLogDebug: it is possible to bring the system to its knees
                 // by creating too many threads and not joining them quite
                 // easily
-                wxLogError(_("Failed to join a thread, potential memory leak "
-                             "detected - please restart the program"));
+                wxLogError(_("Failed to join a thread, potential memory leak detected - please restart the program"));
             }
 
             m_shouldBeJoined = FALSE;
             }
 
             m_shouldBeJoined = FALSE;
@@ -904,12 +912,9 @@ void wxThreadInternal::Pause()
     wxCHECK_RET( m_state == STATE_PAUSED,
                  wxT("thread must first be paused with wxThread::Pause().") );
 
     wxCHECK_RET( m_state == STATE_PAUSED,
                  wxT("thread must first be paused with wxThread::Pause().") );
 
-#ifdef __VMS
-   wxLogTrace(TRACE_THREADS, _T("Thread %ld goes to sleep."), (long long)GetId());
-#else
-   wxLogTrace(TRACE_THREADS, _T("Thread %ld goes to sleep."), (long)GetId());
-#endif
-   
+   wxLogTrace(TRACE_THREADS,
+              _T("Thread %ld goes to sleep."), THR_ID(this));
+
     // wait until the semaphore is Post()ed from Resume()
     m_semSuspend.Wait();
 }
     // wait until the semaphore is Post()ed from Resume()
     m_semSuspend.Wait();
 }
@@ -923,12 +928,9 @@ void wxThreadInternal::Resume()
     // TestDestroy() since the last call to Pause() for example
     if ( IsReallyPaused() )
     {
     // TestDestroy() since the last call to Pause() for example
     if ( IsReallyPaused() )
     {
-#ifdef __VMS
-       wxLogTrace(TRACE_THREADS, _T("Waking up thread %ld"), (long long)GetId());
-#else
-       wxLogTrace(TRACE_THREADS, _T("Waking up thread %ld"), (long)GetId());
-#endif
-       
+       wxLogTrace(TRACE_THREADS,
+                  _T("Waking up thread %ld"), THR_ID(this));
+
         // wake up Pause()
         m_semSuspend.Post();
 
         // wake up Pause()
         m_semSuspend.Post();
 
@@ -937,12 +939,8 @@ void wxThreadInternal::Resume()
     }
     else
     {
     }
     else
     {
-        wxLogTrace(TRACE_THREADS, _T("Thread %ld is not yet really paused"),
-#ifdef __VMS
-                   (long long)GetId());
-#else
-                   (long)GetId());
-#endif
+        wxLogTrace(TRACE_THREADS,
+                   _T("Thread %ld is not yet really paused"), THR_ID(this));
     }
 
     SetState(STATE_RUNNING);
     }
 
     SetState(STATE_RUNNING);
@@ -959,7 +957,7 @@ wxThread *wxThread::This()
 
 bool wxThread::IsMain()
 {
 
 bool wxThread::IsMain()
 {
-    return (bool)pthread_equal(pthread_self(), gs_tidMain);
+    return (bool)pthread_equal(pthread_self(), gs_tidMain) || gs_tidMain == (pthread_t)-1;
 }
 
 void wxThread::Yield()
 }
 
 void wxThread::Yield()
@@ -971,7 +969,7 @@ void wxThread::Yield()
 
 void wxThread::Sleep(unsigned long milliseconds)
 {
 
 void wxThread::Sleep(unsigned long milliseconds)
 {
-    wxUsleep(milliseconds);
+    wxMilliSleep(milliseconds);
 }
 
 int wxThread::GetCPUCount()
 }
 
 int wxThread::GetCPUCount()
@@ -988,8 +986,8 @@ int wxThread::GetCPUCount()
         wxString s;
         if ( file.ReadAll(&s) )
         {
         wxString s;
         if ( file.ReadAll(&s) )
         {
-            // (ab)use Replace() to find the number of "processor" strings
-            size_t count = s.Replace(_T("processor"), _T(""));
+            // (ab)use Replace() to find the number of "processor: num" strings
+            size_t count = s.Replace(_T("processor\t:"), _T(""));
             if ( count > 0 )
             {
                 return count;
             if ( count > 0 )
             {
                 return count;
@@ -1015,19 +1013,24 @@ int wxThread::GetCPUCount()
     return -1;
 }
 
     return -1;
 }
 
+// VMS is a 64 bit system and threads have 64 bit pointers.
+// FIXME: also needed for other systems????
 #ifdef __VMS
 #ifdef __VMS
-  // VMS is a 64 bit system and threads have 64 bit pointers.
-  // ??? also needed for other systems????
 unsigned long long wxThread::GetCurrentId()
 {
     return (unsigned long long)pthread_self();
 unsigned long long wxThread::GetCurrentId()
 {
     return (unsigned long long)pthread_self();
-#else
+}
+
+#else // !__VMS
+
 unsigned long wxThread::GetCurrentId()
 {
     return (unsigned long)pthread_self();
 unsigned long wxThread::GetCurrentId()
 {
     return (unsigned long)pthread_self();
-#endif
 }
 
 }
 
+#endif // __VMS/!__VMS
+
+
 bool wxThread::SetConcurrency(size_t level)
 {
 #ifdef HAVE_THR_SETCONCURRENCY
 bool wxThread::SetConcurrency(size_t level)
 {
 #ifdef HAVE_THR_SETCONCURRENCY
@@ -1452,8 +1455,7 @@ wxThreadError wxThread::Kill()
 void wxThread::Exit(ExitCode status)
 {
     wxASSERT_MSG( This() == this,
 void wxThread::Exit(ExitCode status)
 {
     wxASSERT_MSG( This() == this,
-                  _T("wxThread::Exit() can only be called in the "
-                     "context of the same thread") );
+                  _T("wxThread::Exit() can only be called in the context of the same thread") );
 
     if ( m_isDetached )
     {
 
     if ( m_isDetached )
     {
@@ -1492,8 +1494,7 @@ void wxThread::Exit(ExitCode status)
 bool wxThread::TestDestroy()
 {
     wxASSERT_MSG( This() == this,
 bool wxThread::TestDestroy()
 {
     wxASSERT_MSG( This() == this,
-                  _T("wxThread::TestDestroy() can only be called in the "
-                     "context of the same thread") );
+                  _T("wxThread::TestDestroy() can only be called in the context of the same thread") );
 
     m_critsect.Enter();
 
 
     m_critsect.Enter();
 
@@ -1526,8 +1527,7 @@ wxThread::~wxThread()
     if ( m_internal->GetState() != STATE_EXITED &&
          m_internal->GetState() != STATE_NEW )
     {
     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(_T("The thread %ld is being destroyed although it is still running! The application may crash."), GetId());
     }
 
     m_critsect.Leave();
     }
 
     m_critsect.Leave();
@@ -1593,19 +1593,15 @@ bool wxThreadModule::OnInit()
     int rc = pthread_key_create(&gs_keySelf, NULL /* dtor function */);
     if ( rc != 0 )
     {
     int rc = pthread_key_create(&gs_keySelf, NULL /* dtor function */);
     if ( rc != 0 )
     {
-        wxLogSysError(rc, _("Thread module initialization failed: "
-                            "failed to create thread key"));
+        wxLogSysError(rc, _("Thread module initialization failed: failed to create thread key"));
 
         return FALSE;
     }
 
     gs_tidMain = pthread_self();
 
 
         return FALSE;
     }
 
     gs_tidMain = pthread_self();
 
-#if wxUSE_GUI
     gs_mutexGui = new wxMutex();
     gs_mutexGui = new wxMutex();
-
     gs_mutexGui->Lock();
     gs_mutexGui->Lock();
-#endif // wxUSE_GUI
 
     gs_mutexDeleteThread = new wxMutex();
     gs_condAllDeleted = new wxCondition( *gs_mutexDeleteThread );
 
     gs_mutexDeleteThread = new wxMutex();
     gs_condAllDeleted = new wxCondition( *gs_mutexDeleteThread );
@@ -1650,12 +1646,9 @@ void wxThreadModule::OnExit()
         gs_allThreads[0]->Delete();
     }
 
         gs_allThreads[0]->Delete();
     }
 
-#if wxUSE_GUI
     // destroy GUI mutex
     gs_mutexGui->Unlock();
     // destroy GUI mutex
     gs_mutexGui->Unlock();
-
     delete gs_mutexGui;
     delete gs_mutexGui;
-#endif // wxUSE_GUI
 
     // and free TLD slot
     (void)pthread_key_delete(gs_keySelf);
 
     // and free TLD slot
     (void)pthread_key_delete(gs_keySelf);
@@ -1704,16 +1697,12 @@ static void DeleteThread(wxThread *This)
 
 void wxMutexGuiEnter()
 {
 
 void wxMutexGuiEnter()
 {
-#if wxUSE_GUI
     gs_mutexGui->Lock();
     gs_mutexGui->Lock();
-#endif // wxUSE_GUI
 }
 
 void wxMutexGuiLeave()
 {
 }
 
 void wxMutexGuiLeave()
 {
-#if wxUSE_GUI
     gs_mutexGui->Unlock();
     gs_mutexGui->Unlock();
-#endif // wxUSE_GUI
 }
 
 // ----------------------------------------------------------------------------
 }
 
 // ----------------------------------------------------------------------------