Module: tools Branch: master Commit: 0de6856d608d6d44ab36f0b16248c8998e9455b7 URL: http://source.winehq.org/git/tools.git/?a=commit;h=0de6856d608d6d44ab36f0b16...
Author: Francois Gouget fgouget@codeweavers.com Date: Thu Dec 21 12:13:59 2017 +0100
testbot: Avoid reference cycles between Items and their Collection.
Reference cycles cause Perl's primitive reference-count based garbage collector to leak memory.
Signed-off-by: Francois Gouget fgouget@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
testbot/lib/ObjectModel/Item.pm | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/testbot/lib/ObjectModel/Item.pm b/testbot/lib/ObjectModel/Item.pm index c27e40c..88c9d1a 100644 --- a/testbot/lib/ObjectModel/Item.pm +++ b/testbot/lib/ObjectModel/Item.pm @@ -26,6 +26,7 @@ ObjectModel::Item - Base class for items
=cut
+use Scalar::Util qw(weaken); use ObjectModel::BackEnd; use ObjectModel::Collection; use ObjectModel::PropertyDescriptor; @@ -68,6 +69,9 @@ sub new($$@) $self->{TableName} = $Collection->{TableName}; $self->{ScopeItems} = $Collection->{AllScopeItems}->{ref($Collection)}; $self->{AllScopeItems} = $Collection->{AllScopeItems}; + # Avoid memory cycles + weaken($self->{ScopeItems}); + weaken($self->{AllScopeItems}); $self->{PropertyDescriptors} = $Collection->{PropertyDescriptors}; $self->{MasterColNames} = $Collection->{MasterColNames}; $self->{MasterColValues} = $Collection->{MasterColValues}; @@ -509,14 +513,21 @@ sub MasterKeyChanged($$) { my ($self, $MasterColValues) = @_;
- my $Key = $self->GetKey(); - my $FullKey = $self->GetFullKey($Key); - delete($self->{ScopeItems}->{$FullKey}) if (defined $FullKey); + my $Key; + if ($self->{ScopeItems}) + { + $Key = $self->GetKey(); + my $FullKey = $self->GetFullKey($Key); + delete($self->{ScopeItems}->{$FullKey}) if (defined $FullKey); + }
$self->{MasterColValues} = $MasterColValues; $self->{MasterKey} = ObjectModel::Collection::ComputeMasterKey($MasterColValues); - $FullKey = $self->GetFullKey($Key); - $self->{ScopeItems}->{$FullKey} = $self if (defined $FullKey); + if ($self->{ScopeItems}) + { + my $FullKey = $self->GetFullKey($Key); + $self->{ScopeItems}->{$FullKey} = $self if (defined $FullKey); + }
$self->KeyChanged(); }