Francois Gouget : testbot: Avoid reference cycles between Items and their Collection.

Alexandre Julliard julliard at winehq.org
Thu Dec 21 07:24:24 CST 2017


Module: tools
Branch: master
Commit: 0de6856d608d6d44ab36f0b16248c8998e9455b7
URL:    http://source.winehq.org/git/tools.git/?a=commit;h=0de6856d608d6d44ab36f0b16248c8998e9455b7

Author: Francois Gouget <fgouget at 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 at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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();
 }




More information about the wine-cvs mailing list