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:
crs 2001-10-20 20:43:31 +00:00
parent 9435639545
commit 3cfbc0f68c
2 changed files with 44 additions and 27 deletions

View File

@ -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

View File

@ -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;