static size_t gs_nThreadsBeingDeleted = 0;
// a mutex to protect gs_nThreadsBeingDeleted
-static pthread_mutex_t gs_mutexDeleteThread = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t gs_mutexDeleteThread;
// and a condition variable which will be signaled when all
// gs_nThreadsBeingDeleted will have been deleted
{
m_internal = new wxMutexInternal;
- pthread_mutex_init(&(m_internal->m_mutex),
- (pthread_mutexattr_t*) NULL );
+ // support recursive locks like Win32, i.e. a thread can lock a mutex which
+ // it had itself already locked
+ //
+ // but initialization of recursive mutexes is non portable <sigh>, so try
+ // several methods
+#ifdef HAVE_PTHREAD_MUTEXATTR_T
+ pthread_mutexattr_t attr;
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+
+ pthread_mutex_init(&(m_internal->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_internal->m_mutex = mutex;
+#else // no recursive mutexes
+ pthread_mutex_init(&(m_internal->m_mutex), NULL);
+#endif // HAVE_PTHREAD_MUTEXATTR_T/...
+
m_locked = 0;
}
wxMutexGuiLeave();
bool isDetached = m_isDetached;
- long id = GetId();
- wxLogTrace(TRACE_THREADS, _T("Starting to wait for thread %ld to exit."),
+#ifdef __VMS
+ long long id = (long long)GetId();
+#else
+ long id = (long)GetId();
+#endif
+ wxLogTrace(TRACE_THREADS, _T("Starting to wait for thread %ld to exit."),
id);
// wait until the thread terminates (we're blocking in _another_ thread,
// we're cancelled inside pthread_join(), things will almost
// certainly break - but if we disable the cancellation, we
// might deadlock
- if ( pthread_join(id, &m_exitcode) != 0 )
+ if ( pthread_join((pthread_t)id, &m_exitcode) != 0 )
{
wxLogError(_("Failed to join a thread, potential memory leak "
"detected - please restart the program"));
void wxThread::Yield()
{
+#ifdef HAVE_SCHED_YIELD
sched_yield();
+#endif
}
void wxThread::Sleep(unsigned long milliseconds)
int wxThread::GetCPUCount()
{
-#if defined(__LINUX__)
+#if defined(__LINUX__) && wxUSE_FFILE
// read from proc (can't use wxTextFile here because it's a special file:
// it has 0 size but still can be read from)
wxLogNull nolog;
wxLogError(_("Cannot retrieve thread scheduling policy."));
}
- int min_prio = sched_get_priority_min(policy),
- max_prio = sched_get_priority_max(policy),
+#ifdef __VMS__
+ /* the pthread.h contains too many spaces. This is a work-around */
+# undef sched_get_priority_max
+#undef sched_get_priority_min
+#define sched_get_priority_max(_pol_) \
+ (_pol_ == SCHED_OTHER ? PRI_FG_MAX_NP : PRI_FIFO_MAX)
+#define sched_get_priority_min(_pol_) \
+ (_pol_ == SCHED_OTHER ? PRI_FG_MIN_NP : PRI_FIFO_MIN)
+#endif
+
+ int max_prio = sched_get_priority_max(policy),
+ min_prio = sched_get_priority_min(policy),
prio = m_internal->GetPriority();
if ( min_prio == -1 || max_prio == -1 )
return m_internal->GetPriority();
}
+#ifdef __VMS
+unsigned long long wxThread::GetId() const
+{
+ return (unsigned long long)m_internal->GetId();
+#else
unsigned long wxThread::GetId() const
{
return (unsigned long)m_internal->GetId();
+#endif
}
// -----------------------------------------------------------------------------
#if !HAVE_THREAD_CLEANUP_FUNCTIONS
ScheduleThreadForDeletion();
- OnExit();
+ // don't call OnExit() here, it can only be called in the
+ // threads context and we're in the context of another thread
DeleteThread(this);
#endif // HAVE_THREAD_CLEANUP_FUNCTIONS
gs_mutexGui->Lock();
#endif // wxUSE_GUI
+ // under Solaris we get a warning from CC when using
+ // PTHREAD_MUTEX_INITIALIZER, so do it dynamically
+ pthread_mutex_init(&gs_mutexDeleteThread, NULL);
+
return TRUE;
}