From: Peter Rabbitson Date: Sun, 12 Jan 2014 12:36:30 +0000 (+0100) Subject: Centralize handling of refcount in DBIC::_Util X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=dac7972a0974db384637b7a8d9a661b08853b3cf;p=dbsrgits%2FDBIx-Class-Historic.git Centralize handling of refcount in DBIC::_Util --- diff --git a/lib/DBIx/Class/Schema.pm b/lib/DBIx/Class/Schema.pm index 76395ae..4c3cce5 100644 --- a/lib/DBIx/Class/Schema.pm +++ b/lib/DBIx/Class/Schema.pm @@ -8,8 +8,8 @@ use base 'DBIx::Class'; use DBIx::Class::Carp; use Try::Tiny; use Scalar::Util qw/weaken blessed/; +use DBIx::Class::_Util 'refcount'; use Sub::Name 'subname'; -use B 'svref_2object'; use Devel::GlobalDestruction; use namespace::clean; @@ -1405,7 +1405,7 @@ sub DESTROY { # which will serve as a signal to not try doing anything else # however beware - on older perls the exception seems randomly untrappable # due to some weird race condition during thread joining :((( - if (ref $srcs->{$source_name} and svref_2object($srcs->{$source_name})->REFCNT > 1) { + if (length ref $srcs->{$source_name} and refcount($srcs->{$source_name}) > 1) { local $@; eval { $srcs->{$source_name}->schema($self); diff --git a/lib/DBIx/Class/_Util.pm b/lib/DBIx/Class/_Util.pm index cf7443f..0afe2ea 100644 --- a/lib/DBIx/Class/_Util.pm +++ b/lib/DBIx/Class/_Util.pm @@ -53,7 +53,7 @@ use Carp; use Scalar::Util qw(refaddr weaken); use base 'Exporter'; -our @EXPORT_OK = qw(sigwarn_silencer modver_gt_or_eq fail_on_internal_wantarray); +our @EXPORT_OK = qw(sigwarn_silencer modver_gt_or_eq fail_on_internal_wantarray refcount); sub sigwarn_silencer { my $pattern = shift; @@ -65,6 +65,15 @@ sub sigwarn_silencer { return sub { &$orig_sig_warn unless $_[0] =~ $pattern }; } +sub refcount { + croak "Expecting a reference" if ! length ref $_[0]; + + require B; + # No tempvars - must operate on $_[0], otherwise the pad + # will count as an extra ref + B::svref_2object($_[0])->REFCNT; +} + sub modver_gt_or_eq { my ($mod, $ver) = @_; diff --git a/t/lib/DBICTest/Util/LeakTracer.pm b/t/lib/DBICTest/Util/LeakTracer.pm index 2c10000..8320efe 100644 --- a/t/lib/DBICTest/Util/LeakTracer.pm +++ b/t/lib/DBICTest/Util/LeakTracer.pm @@ -5,7 +5,7 @@ use strict; use Carp; use Scalar::Util qw/isweak weaken blessed reftype refaddr/; -use B 'svref_2object'; +use DBIx::Class::_Util 'refcount'; use DBICTest::Util 'stacktrace'; use base 'Exporter'; @@ -142,10 +142,8 @@ sub assert_empty_weakregistry { and my $expected_refcnt = $classdata_refcounts->{$weak_registry->{$slot}{refaddr}} ) { - # need to store the SVref and examine it separately, - # to push the weakref instance off the pad - my $sv = svref_2object($weak_registry->{$slot}{weakref}); - delete $weak_registry->{$slot} if $sv->REFCNT == $expected_refcnt; + delete $weak_registry->{$slot} + if refcount($weak_registry->{$slot}{weakref}) == $expected_refcnt; } } }