diff options
author | kaie%kuix.de <devnull@localhost> | 2007-07-07 01:01:42 +0000 |
---|---|---|
committer | kaie%kuix.de <devnull@localhost> | 2007-07-07 01:01:42 +0000 |
commit | b63dbe41f3f8b8de4e79ce1b9ce2677782fba1eb (patch) | |
tree | c9383315dd6b27a1dd9df28ee58f1730536e426b /pr/src/pthreads | |
parent | db0a25d7ed9f1bfa8e3d54d4f41bb290cc2a0a54 (diff) | |
download | nspr-hg-b63dbe41f3f8b8de4e79ce1b9ce2677782fba1eb.tar.gz |
Bug 383977, Crash on exit caused by thread local storage cleanup [@ PL_DHashTableOperate]WEB_CONTENT_HANDLING_20070621_POST_HANDLER_SERVICE_20070720WEB_CONTENT_HANDLING_20070621_POSTMERGE_20070719_FIXEDNSPR_HEAD_20070713MOZILLA_1_9a7_RELEASEMOZILLA_1_9a7_RC1
r=wtc
Diffstat (limited to 'pr/src/pthreads')
-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); } |