From: Dave Mitchell Date: Sun, 16 Oct 2005 14:53:45 +0000 (+0000) Subject: free a thread's interpreter after $t->join() rather than after undef $t X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=2e6764678abb1cb3486981641d2ecc61ea8a3c6e;p=p5sagit%2Fp5-mst-13.2.git free a thread's interpreter after $t->join() rather than after undef $t This should fix some ithreads memory leaks. p4raw-id: //depot/perl@25769 --- diff --git a/ext/threads/threads.xs b/ext/threads/threads.xs index 272a2a6..f2e85eb 100755 --- a/ext/threads/threads.xs +++ b/ext/threads/threads.xs @@ -86,14 +86,49 @@ ithread* Perl_ithread_get (pTHX) { } +/* free any data (such as the perl interpreter) attached to an + * ithread structure. This is a bit like undef on SVs, where the SV + * isn't freed, but the PVX is. + * Must be called with thread->mutex already held + */ + +static void +Perl_ithread_clear(pTHX_ ithread* thread) +{ + PerlInterpreter *interp; + assert(thread->state & PERL_ITHR_FINISHED && + (thread->state & PERL_ITHR_DETACHED || + thread->state & PERL_ITHR_JOINED)); + + interp = thread->interp; + if (interp) { + dTHXa(interp); + ithread* current_thread; +#ifdef OEMVS + void *ptr; +#endif + PERL_SET_CONTEXT(interp); + current_thread = Perl_ithread_get(aTHX); + Perl_ithread_set(aTHX_ thread); + + SvREFCNT_dec(thread->params); + + thread->params = Nullsv; + perl_destruct(interp); + thread->interp = NULL; + } + if (interp) + perl_free(interp); + PERL_SET_CONTEXT(aTHX); +} + /* - * Clear up after thread is done with + * free an ithread structure and any attached data if its count == 0 */ void Perl_ithread_destruct (pTHX_ ithread* thread, const char *why) { - PerlInterpreter *freeperl = NULL; MUTEX_LOCK(&thread->mutex); if (!thread->next) { MUTEX_UNLOCK(&thread->mutex); @@ -127,28 +162,7 @@ Perl_ithread_destruct (pTHX_ ithread* thread, const char *why) MUTEX_UNLOCK(&create_destruct_mutex); /* Thread is now disowned */ - if(thread->interp) { - dTHXa(thread->interp); - ithread* current_thread; -#ifdef OEMVS - void *ptr; -#endif - PERL_SET_CONTEXT(thread->interp); - current_thread = Perl_ithread_get(aTHX); - Perl_ithread_set(aTHX_ thread); - - - - - SvREFCNT_dec(thread->params); - - - - thread->params = Nullsv; - perl_destruct(thread->interp); - freeperl = thread->interp; - thread->interp = NULL; - } + Perl_ithread_clear(aTHX_ thread); MUTEX_UNLOCK(&thread->mutex); MUTEX_DESTROY(&thread->mutex); #ifdef WIN32 @@ -157,10 +171,6 @@ Perl_ithread_destruct (pTHX_ ithread* thread, const char *why) thread->handle = 0; #endif PerlMemShared_free(thread); - if (freeperl) - perl_free(freeperl); - - PERL_SET_CONTEXT(aTHX); } int @@ -650,6 +660,7 @@ Perl_ithread_join(pTHX_ SV *obj) } /* We are finished with it */ thread->state |= PERL_ITHR_JOINED; + Perl_ithread_clear(aTHX_ thread); MUTEX_UNLOCK(&thread->mutex); return retparam;