[PATCH] testbot: Avoid reference cycles between Items and their Collection.

Francois Gouget fgouget at codeweavers.com
Thu Dec 21 05:13:59 CST 2017


Reference cycles cause Perl's primitive reference-count based garbage
collector to leak memory.

Signed-off-by: Francois Gouget <fgouget at codeweavers.com>
---
 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 c27e40cf..88c9d1ae 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();
 }
-- 
2.15.1



More information about the wine-devel mailing list