summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorArtur Bergman <sky@nanisky.com>2003-02-01 21:04:36 +0000
committerArtur Bergman <sky@nanisky.com>2003-02-01 21:04:36 +0000
commit3b1c327365c3ef67a4c31617c95680c19a00f118 (patch)
treea301b01a1c3ae098b21e68986e792a2634ece231 /ext
parentb68cc5bb49d07a56be57a2adbd469fa7bf097c7d (diff)
downloadperl-3b1c327365c3ef67a4c31617c95680c19a00f118.tar.gz
Fix bug #15837, temporary from storable call hadn't gotten
freed yet and was cloned but without a real (AvREAL) reference to it. @_ doesn't refcount! p4raw-id: //depot/perl@18618
Diffstat (limited to 'ext')
-rwxr-xr-xext/threads/threads.xs47
1 files changed, 47 insertions, 0 deletions
diff --git a/ext/threads/threads.xs b/ext/threads/threads.xs
index c9c20636b2..68cb699ff9 100755
--- a/ext/threads/threads.xs
+++ b/ext/threads/threads.xs
@@ -129,7 +129,13 @@ Perl_ithread_destruct (pTHX_ ithread* thread, const char *why)
PERL_SET_CONTEXT(thread->interp);
PERL_THREAD_GETSPECIFIC(self_key,current_thread);
PERL_THREAD_SETSPECIFIC(self_key,thread);
+
+
+
SvREFCNT_dec(thread->params);
+
+
+
thread->params = Nullsv;
perl_destruct(thread->interp);
perl_free(thread->interp);
@@ -362,6 +368,10 @@ Perl_ithread_create(pTHX_ SV *obj, char* classname, SV* init_function, SV* param
ithread* thread;
CLONE_PARAMS clone_param;
ithread* current_thread;
+
+ SV** tmps_tmp = PL_tmps_stack;
+ I32 tmps_ix = PL_tmps_ix;
+
PERL_THREAD_GETSPECIFIC(self_key,current_thread);
MUTEX_LOCK(&create_destruct_mutex);
thread = PerlMemShared_malloc(sizeof(ithread));
@@ -384,6 +394,9 @@ Perl_ithread_create(pTHX_ SV *obj, char* classname, SV* init_function, SV* param
PerlIO_flush((PerlIO*)NULL);
PERL_THREAD_SETSPECIFIC(self_key,thread);
+
+
+
#ifdef WIN32
thread->interp = perl_clone(aTHX, CLONEf_KEEP_PTR_TABLE | CLONEf_CLONE_HOST);
#else
@@ -406,9 +419,42 @@ Perl_ithread_create(pTHX_ SV *obj, char* classname, SV* init_function, SV* param
if (SvREFCNT(thread->init_function) == 0) {
SvREFCNT_inc(thread->init_function);
}
+
+
thread->params = sv_dup(params, &clone_param);
SvREFCNT_inc(thread->params);
+
+
+ /* The code below checks that anything living on
+ the tmps stack and has been cloned (so it lives in the
+ ptr_table) has a refcount higher than 0
+
+ If the refcount is 0 it means that a something on the
+ stack/context was holding a reference to it and
+ since we init_stacks() in perl_clone that won't get
+ cleaned and we will get a leaked scalar.
+ The reason it was cloned was that it lived on the
+ @_ stack.
+
+ Example of this can be found in bugreport 15837
+ where calls in the parameter list end up as a temp
+
+ One could argue that this fix should be in perl_clone
+ */
+
+
+ while (tmps_ix > 0) {
+ SV* sv = (SV*)ptr_table_fetch(PL_ptr_table, tmps_tmp[tmps_ix]);
+ tmps_ix--;
+ if (sv && SvREFCNT(sv) == 0) {
+ SvREFCNT_inc(sv);
+ SvREFCNT_dec(sv);
+ }
+ }
+
+
+
SvTEMP_off(thread->init_function);
ptr_table_free(PL_ptr_table);
PL_ptr_table = NULL;
@@ -452,6 +498,7 @@ Perl_ithread_create(pTHX_ SV *obj, char* classname, SV* init_function, SV* param
active_threads++;
MUTEX_UNLOCK(&create_destruct_mutex);
sv_2mortal(params);
+
return ithread_to_SV(aTHX_ obj, thread, classname, FALSE);
}