diff --git a/dist/threads-shared/lib/threads/shared.pm b/dist/threads-shared/lib/threads/shared.pm index fef27aba11..03b7f94978 100644 --- a/dist/threads-shared/lib/threads/shared.pm +++ b/dist/threads-shared/lib/threads/shared.pm @@ -8,7 +8,7 @@ use Config; use Scalar::Util qw(reftype refaddr blessed); -our $VERSION = '1.69'; # Please update the pod, too. +our $VERSION = '1.70'; # Please update the pod, too. my $XS_VERSION = $VERSION; $VERSION = eval $VERSION; @@ -196,7 +196,7 @@ threads::shared - Perl extension for sharing data structures between threads =head1 VERSION -This document describes threads::shared version 1.68 +This document describes threads::shared version 1.70 =head1 SYNOPSIS diff --git a/dist/threads-shared/shared.xs b/dist/threads-shared/shared.xs index 938f963f5e..77250cdbd8 100644 --- a/dist/threads-shared/shared.xs +++ b/dist/threads-shared/shared.xs @@ -1080,6 +1080,14 @@ sharedsv_elem_mg_DELETE(pTHX_ SV *sv, MAGIC *mg) return (0); } +static int +sharedsv_elem_mg_free(pTHX_ SV* nsv, MAGIC *mg) +{ + if (mg->mg_private) + sharedsv_elem_mg_DELETE(aTHX_ nsv, mg); + return (0); +} + /* Called during cloning of PERL_MAGIC_tiedelem(p) magic in new * thread */ @@ -1092,16 +1100,26 @@ sharedsv_elem_mg_dup(pTHX_ MAGIC *mg, CLONE_PARAMS *param) return (0); } +static int +sharedsv_elem_mg_local(pTHX_ SV* nsv, MAGIC *mg) +{ + MAGIC* magic = sv_magicext(nsv, mg->mg_obj, mg->mg_type, mg->mg_virtual, + mg->mg_ptr, mg->mg_len); + magic->mg_flags = mg->mg_flags; + magic->mg_private = mg_find(nsv, PERL_MAGIC_shared_scalar) ? 0 : 1; + return (0); +} + const MGVTBL sharedsv_elem_vtbl = { sharedsv_elem_mg_FETCH, /* get */ sharedsv_elem_mg_STORE, /* set */ 0, /* len */ sharedsv_elem_mg_DELETE, /* clear */ - 0, /* free */ + sharedsv_elem_mg_free, /* free */ 0, /* copy */ sharedsv_elem_mg_dup, /* dup */ #ifdef MGf_LOCAL - 0, /* local */ + sharedsv_elem_mg_local, /* local */ #endif }; @@ -1191,7 +1209,11 @@ sharedsv_array_mg_copy(pTHX_ SV *sv, MAGIC* mg, toLOWER(mg->mg_type),&sharedsv_elem_vtbl, name, namlen); PERL_UNUSED_ARG(sv); - nmg->mg_flags |= MGf_DUP; + nmg->mg_flags |= MGf_DUP +#ifdef MGf_LOCAL + |MGf_LOCAL +#endif + ; return (1); } diff --git a/dist/threads-shared/t/hv_simple.t b/dist/threads-shared/t/hv_simple.t index 574d8d5508..5ce7afc9a5 100644 --- a/dist/threads-shared/t/hv_simple.t +++ b/dist/threads-shared/t/hv_simple.t @@ -27,7 +27,7 @@ sub ok { BEGIN { $| = 1; - print("1..16\n"); ### Number of tests that will be run ### + print("1..18\n"); ### Number of tests that will be run ### }; use threads; @@ -55,23 +55,28 @@ $hash{"3"} = 3; ok(7, keys %hash == 4, "Check keys"); ok(8, exists($hash{"1"}), "Exist on existing key"); ok(9, !exists($hash{"4"}), "Exists on non existing key"); + +{ local $hash{"4"} = 1 } +ok(10, keys %hash == 4, "Localization left 3 keys"); +ok(11, !exists($hash{"4"}), "Localization didn't leave extra key"); + my %seen; foreach my $key ( keys %hash) { $seen{$key}++; } -ok(10, $seen{1} == 1, "Keys.."); -ok(11, $seen{2} == 1, "Keys.."); -ok(12, $seen{3} == 1, "Keys.."); -ok(13, $seen{"foo"} == 1, "Keys.."); +ok(12, $seen{1} == 1, "Keys.."); +ok(13, $seen{2} == 1, "Keys.."); +ok(14, $seen{3} == 1, "Keys.."); +ok(15, $seen{"foo"} == 1, "Keys.."); # bugid #24407: the stringification of the numeric 1 got allocated to the # wrong thread memory pool, which crashes on Windows. -ok(14, exists $hash{1}, "Check numeric key"); +ok(16, exists $hash{1}, "Check numeric key"); threads->create(sub { %hash = () })->join(); -ok(15, keys %hash == 0, "Check clear"); +ok(17, keys %hash == 0, "Check clear"); -ok(16, is_shared(%hash), "Check for sharing"); +ok(18, is_shared(%hash), "Check for sharing"); exit(0);