On Fri Dec 02 11:08:09 2011, davem wrote: > > This is a bug report for perl from davem@iabyn.com, > generated with the help of perlbug 1.39 running under perl 5.15.5. > > This fails: > > use threads; > > my $s = threads->new(sub { return sub { $::x = 1} })->join; > $s->(); > print "ok\n" if $::x == 1; > > When the thread is created, *::x (and thus $::x) are cloned into the > child > thread. When it returns the anon sub, that sub is cloned back into the > parent thread, and by extension, everything in its pad, including, > *::x. > This leaves two copies of *::x in the parent thread, one linked to > from > %::, and one from &$s's pad. > > I spotted this due to my work in the 're_eval' bug; now that qr//s are > proper closures, this returns a regex that sets the wrong $::x: > > my $s = threads->new(sub { return qr/(?{ $::x = 1})/ })->join; The cloning code avoids duplicating stashes during a join if they exist in the parent thread. The relevant code is in S_sv_dup_common in sv.c: if(param->flags & CLONEf_JOIN_IN) { /** We are joining here so we don't want do clone something that is bad **/ if (SvTYPE(sstr) == SVt_PVHV) { const HEK * const hvname = HvNAME_HEK(sstr); if (hvname) { /** don't clone stashes if they already exist **/ dstr = MUTABLE_SV(gv_stashpvn(HEK_KEY(hvname), HEK_LEN(hvname), HEK_UTF8(hvname) ? SVf_UTF8 : 0)); ptr_table_store(PL_ptr_table, sstr, dstr); return dstr; } } } Should this be changed to include globs as well? (And I suppose orphaned globs *should* be cloned, right?) Would it apply just to those in op trees, or to typeglobs in general? -- Father ChrysostomosThread Previous | Thread Next