X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FResultSource.pm;h=821f5cbb1a2a556b6eccf4c36c4a070a6dc9ff51;hb=50261284a5486d1974adb202eb84e5ed782d3665;hp=e7ab22d80cf2d6de18987fe5627ab50c7c122f93;hpb=c76e5262bd2cdd19ac0260b1a916767db304a953;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/ResultSource.pm b/lib/DBIx/Class/ResultSource.pm index e7ab22d..821f5cb 100644 --- a/lib/DBIx/Class/ResultSource.pm +++ b/lib/DBIx/Class/ResultSource.pm @@ -10,6 +10,8 @@ use DBIx::Class::Exception; use Carp::Clan qw/^DBIx::Class/; use Try::Tiny; use List::Util 'first'; +use Scalar::Util qw/weaken isweak/; +use Storable qw/nfreeze thaw/; use namespace::clean; use base qw/DBIx::Class/; @@ -1742,6 +1744,56 @@ sub handle { }); } +{ + my $global_phase_destroy; + + END { $global_phase_destroy++ } + + sub DESTROY { + return if $global_phase_destroy; + +###### +# !!! ACHTUNG !!!! +###### +# +# Under no circumstances shall $_[0] be stored anywhere else (like copied to +# a lexical variable, or shifted, or anything else). Doing so will mess up +# the refcount of this particular result source, and will allow the $schema +# we are trying to save to reattach back to the source we are destroying. +# The relevant code checking refcounts is in ::Schema::DESTROY() + + # if we are not a schema instance holder - we don't matter + return if( + ! ref $_[0]->{schema} + or + isweak $_[0]->{schema} + ); + + # weaken our schema hold forcing the schema to find somewhere else to live + weaken $_[0]->{schema}; + + # if schema is still there reintroduce ourselves with strong refs back + if ($_[0]->{schema}) { + my $srcregs = $_[0]->{schema}->source_registrations; + for (keys %$srcregs) { + $srcregs->{$_} = $_[0] if $srcregs->{$_} == $_[0]; + } + } + } +} + +sub STORABLE_freeze { + my ($self, $cloning) = @_; + nfreeze($self->handle); +} + +sub STORABLE_thaw { + my ($self, $cloning, $ice) = @_; + %$self = %{ (thaw $ice)->resolve }; +} + + + =head2 throw_exception See L.