threading fixes. had sigmask set in wrong place. was setting
m_exit flag potentially after the object had been destroyed. most importantly, RTTI must be enabled on PPC to avoid SIGILL.
This commit is contained in:
parent
9435639545
commit
3cfbc0f68c
|
@ -15,7 +15,7 @@ RMR = /bin/rm -rf
|
||||||
#
|
#
|
||||||
GCXXDEFS = -D_XOPEN_SOURCE=500
|
GCXXDEFS = -D_XOPEN_SOURCE=500
|
||||||
GCXXINCS = -I$(DEPTH)/include -I/usr/X11R6/include
|
GCXXINCS = -I$(DEPTH)/include -I/usr/X11R6/include
|
||||||
GCXXOPTS = -Wall -W -fexceptions -fno-rtti
|
GCXXOPTS = -Wall -W -fexceptions
|
||||||
CXXOPTIMIZER = -g
|
CXXOPTIMIZER = -g
|
||||||
#CXXOPTIMIZER = -O2 -DNDEBUG
|
#CXXOPTIMIZER = -O2 -DNDEBUG
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#if defined(CONFIG_PTHREADS)
|
#if defined(CONFIG_PTHREADS)
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#define SIGWAKEUP SIGUSR1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// FIXME -- temporary exception type
|
// FIXME -- temporary exception type
|
||||||
|
@ -35,17 +36,6 @@ CThreadRep::CThreadRep() : m_prev(NULL),
|
||||||
#if defined(CONFIG_PTHREADS)
|
#if defined(CONFIG_PTHREADS)
|
||||||
// get main thread id
|
// get main thread id
|
||||||
m_thread = pthread_self();
|
m_thread = pthread_self();
|
||||||
|
|
||||||
// install SIGALRM handler
|
|
||||||
struct sigaction act;
|
|
||||||
act.sa_handler = &threadCancel;
|
|
||||||
# if defined(SA_INTERRUPT)
|
|
||||||
act.sa_flags = SA_INTERRUPT;
|
|
||||||
# else
|
|
||||||
act.sa_flags = 0;
|
|
||||||
# endif
|
|
||||||
sigemptyset(&act.sa_mask);
|
|
||||||
sigaction(SIGALRM, &act, NULL);
|
|
||||||
#elif defined(CONFIG_PLATFORM_WIN32)
|
#elif defined(CONFIG_PLATFORM_WIN32)
|
||||||
// get main thread id
|
// get main thread id
|
||||||
m_thread = NULL;
|
m_thread = NULL;
|
||||||
|
@ -86,10 +76,6 @@ CThreadRep::CThreadRep(IJob* job, void* userData) :
|
||||||
int status = pthread_create(&m_thread, NULL, threadFunc, (void*)this);
|
int status = pthread_create(&m_thread, NULL, threadFunc, (void*)this);
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
throw XThreadUnavailable();
|
throw XThreadUnavailable();
|
||||||
sigset_t sigset;
|
|
||||||
sigemptyset(&sigset);
|
|
||||||
sigaddset(&sigset, SIGALRM);
|
|
||||||
pthread_sigmask(SIG_UNBLOCK, &sigset, NULL);
|
|
||||||
#elif defined(CONFIG_PLATFORM_WIN32)
|
#elif defined(CONFIG_PLATFORM_WIN32)
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
m_thread = reinterpret_cast<HANDLE>(_beginthreadex(NULL, 0,
|
m_thread = reinterpret_cast<HANDLE>(_beginthreadex(NULL, 0,
|
||||||
|
@ -132,6 +118,25 @@ void CThreadRep::initThreads()
|
||||||
{
|
{
|
||||||
if (s_mutex == NULL) {
|
if (s_mutex == NULL) {
|
||||||
s_mutex = new CMutex;
|
s_mutex = new CMutex;
|
||||||
|
|
||||||
|
#if defined(CONFIG_PTHREADS)
|
||||||
|
// install SIGWAKEUP handler
|
||||||
|
struct sigaction act;
|
||||||
|
act.sa_handler = &threadCancel;
|
||||||
|
# if defined(SA_INTERRUPT)
|
||||||
|
act.sa_flags = SA_INTERRUPT;
|
||||||
|
# else
|
||||||
|
act.sa_flags = 0;
|
||||||
|
# endif
|
||||||
|
sigemptyset(&act.sa_mask);
|
||||||
|
sigaction(SIGWAKEUP, &act, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// set signal mask
|
||||||
|
sigset_t sigset;
|
||||||
|
sigemptyset(&sigset);
|
||||||
|
sigaddset(&sigset, SIGWAKEUP);
|
||||||
|
pthread_sigmask(SIG_UNBLOCK, &sigset, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,7 +233,7 @@ void CThreadRep::doThreadFunc()
|
||||||
m_job->run();
|
m_job->run();
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (XThreadCancel&) {
|
catch (XThreadCancel& e) {
|
||||||
// client called cancel()
|
// client called cancel()
|
||||||
log((CLOG_DEBUG "caught cancel on thread %p", this));
|
log((CLOG_DEBUG "caught cancel on thread %p", this));
|
||||||
}
|
}
|
||||||
|
@ -239,8 +244,9 @@ void CThreadRep::doThreadFunc()
|
||||||
log((CLOG_DEBUG "caught exit on thread %p", this));
|
log((CLOG_DEBUG "caught exit on thread %p", this));
|
||||||
}
|
}
|
||||||
catch (...) {
|
catch (...) {
|
||||||
log((CLOG_DEBUG "caught exit on thread %p", this));
|
log((CLOG_DEBUG "exception on thread %p", this));
|
||||||
// note -- don't catch (...) to avoid masking bugs
|
// note -- don't catch (...) to avoid masking bugs
|
||||||
|
delete m_job;
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,11 +296,14 @@ void CThreadRep::cancel()
|
||||||
CLock lock(s_mutex);
|
CLock lock(s_mutex);
|
||||||
if (m_cancellable && !m_cancelling) {
|
if (m_cancellable && !m_cancelling) {
|
||||||
m_cancel = true;
|
m_cancel = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// break out of system calls
|
// break out of system calls
|
||||||
log((CLOG_DEBUG "cancel thread %p", this));
|
log((CLOG_DEBUG "cancel thread %p", this));
|
||||||
pthread_kill(m_thread, SIGALRM);
|
pthread_kill(m_thread, SIGWAKEUP);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CThreadRep::testCancel()
|
void CThreadRep::testCancel()
|
||||||
|
@ -355,15 +364,23 @@ void* CThreadRep::threadFunc(void* arg)
|
||||||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
|
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
|
||||||
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
|
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
|
||||||
|
|
||||||
|
// set signal mask
|
||||||
|
sigset_t sigset;
|
||||||
|
sigemptyset(&sigset);
|
||||||
|
sigaddset(&sigset, SIGWAKEUP);
|
||||||
|
pthread_sigmask(SIG_UNBLOCK, &sigset, NULL);
|
||||||
|
|
||||||
// run thread
|
// run thread
|
||||||
rep->doThreadFunc();
|
rep->doThreadFunc();
|
||||||
|
|
||||||
// unref thread
|
{
|
||||||
rep->unref();
|
|
||||||
|
|
||||||
// mark as terminated
|
// mark as terminated
|
||||||
CLock lock(s_mutex);
|
CLock lock(s_mutex);
|
||||||
rep->m_exit = true;
|
rep->m_exit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// unref thread
|
||||||
|
rep->unref();
|
||||||
|
|
||||||
// terminate the thread
|
// terminate the thread
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
Loading…
Reference in New Issue