diff options
author | kaie%kuix.de <devnull@localhost> | 2007-07-07 01:02:16 +0000 |
---|---|---|
committer | kaie%kuix.de <devnull@localhost> | 2007-07-07 01:02:16 +0000 |
commit | f5443eff54f9e2a9e3b6bf2ecaede020bf454e1f (patch) | |
tree | 57c1ac6c9cf76fa54e72d231d20c3a28c05eba3f | |
parent | 2abcf384aef0555a84d93f9b7bd3d76a4118309c (diff) | |
download | nspr-hg-WEB_CONTENT_HANDLING_20070621_PREMERGE_20070719.tar.gz |
Bug 383977, Crash on exit caused by thread local storage cleanup [@ PL_DHashTableOperate]WEB_CONTENT_HANDLING_20070621_PREMERGE_20070719UPDATE_PACKAGING_R9UPDATE_PACKAGING_R8UPDATE_PACKAGING_R7UPDATE_PACKAGING_R6UPDATE_PACKAGING_R5UPDATE_PACKAGING_R4UPDATE_PACKAGING_R3UPDATE_PACKAGING_R2UPDATE_PACKAGING_R14UPDATE_PACKAGING_R13UPDATE_PACKAGING_R12UPDATE_PACKAGING_R11_1UPDATE_PACKAGING_R11UPDATE_PACKAGING_R10UPDATE_PACKAGING_R1NSPRPUB_PRE_4_2_CLIENT_BRANCH
r=wtc
-rw-r--r-- | pr/src/pthreads/ptthread.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/pr/src/pthreads/ptthread.c b/pr/src/pthreads/ptthread.c index 96999dfd..ce319809 100644 --- a/pr/src/pthreads/ptthread.c +++ b/pr/src/pthreads/ptthread.c @@ -75,6 +75,7 @@ static struct _PT_Bookeeping } pt_book = {0}; static void _pt_thread_death(void *arg); +static void _pt_thread_death_internal(void *arg, PRBool callDestructors); static void init_pthread_gc_support(void); #if defined(_PR_DCETHREADS) || defined(_POSIX_THREAD_PRIORITY_SCHEDULING) @@ -807,6 +808,12 @@ PR_IMPLEMENT(PRStatus) PR_Sleep(PRIntervalTime ticks) static void _pt_thread_death(void *arg) { + /* PR_TRUE for: call destructors */ + _pt_thread_death_internal(arg, PR_TRUE); +} + +static void _pt_thread_death_internal(void *arg, PRBool callDestructors) +{ PRThread *thred = (PRThread*)arg; if (thred->state & (PT_THREAD_FOREIGN|PT_THREAD_PRIMORD)) @@ -822,7 +829,8 @@ static void _pt_thread_death(void *arg) thred->next->prev = thred->prev; PR_Unlock(pt_book.ml); } - _PR_DestroyThreadPrivate(thred); + if (callDestructors) + _PR_DestroyThreadPrivate(thred); PR_Free(thred->privateData); if (NULL != thred->errorString) PR_Free(thred->errorString); @@ -996,7 +1004,11 @@ void _PR_Fini(void) _PT_PTHREAD_GETSPECIFIC(pt_book.key, thred); if (NULL != thred) { - _pt_thread_death(thred); + /* + * PR_FALSE, because it is unsafe to call back to the + * thread private data destructors at final cleanup. + */ + _pt_thread_death_internal(thred, PR_FALSE); rv = pthread_setspecific(pt_book.key, NULL); PR_ASSERT(0 == rv); } |