]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 1282606 - Fix TrackingFlags memory leak
authorDylan Hardison <dylan@mozilla.com>
Mon, 4 Jul 2016 21:36:58 +0000 (17:36 -0400)
committerDylan Hardison <dylan@mozilla.com>
Mon, 4 Jul 2016 21:36:58 +0000 (17:36 -0400)
Bugzilla.pm
Bugzilla/Attachment.pm
Bugzilla/Bug.pm
Bugzilla/Comment.pm
extensions/TrackingFlags/Extension.pm
extensions/TrackingFlags/lib/Flag.pm
extensions/TrackingFlags/lib/Flag/Value.pm

index 4f80a2ed4b9a2589a95620a00c7ce4005015e540..56bbb5c153afc2a7e8399e583fd80a0541d528a5 100644 (file)
@@ -827,6 +827,7 @@ sub _cleanup {
 
     # BMO - allow "end of request" processing
     Bugzilla::Hook::process('request_cleanup');
+    Bugzilla::Bug->CLEANUP;
 
     my $main   = Bugzilla->request_cache->{dbh_main};
     my $shadow = Bugzilla->request_cache->{dbh_shadow};
index 0cdec6bf04d6d67d0d12cf7c246f113688e0bd74..3b4953f64e3cf0ba71de7337119dab3fea1d92ee 100644 (file)
@@ -62,6 +62,7 @@ use Bugzilla::Hook;
 
 use File::Copy;
 use List::Util qw(max);
+use Scalar::Util qw(weaken);
 use Storable qw(dclone);
 
 use base qw(Bugzilla::Object);
@@ -157,8 +158,12 @@ the bug object to which the attachment is attached
 =cut
 
 sub bug {
+    my ($self) = @_;
     require Bugzilla::Bug;
-    return $_[0]->{bug} //= Bugzilla::Bug->new({ id => $_[0]->bug_id, cache => 1 });
+    return $self->{bug} if defined $self->{bug};
+    my $bug = $self->{bug} = Bugzilla::Bug->new({ id => $_[0]->bug_id, cache => 1 });
+    weaken($self->{bug});
+    return $bug;
 }
 
 =over
index 09696f97b75fb81a3560acb5640dd1697252f979..327fb866c6d1d69934dac0c0474434c2b7054dca 100644 (file)
@@ -66,6 +66,8 @@ use base qw(Bugzilla::Object Exporter);
     editable_bug_fields
 );
 
+my %CLEANUP;
+
 #####################################################################
 # Constants
 #####################################################################
@@ -367,6 +369,9 @@ sub new {
         return $error_self;
     }
 
+    $CLEANUP{$self->id} = $self;
+    weaken($CLEANUP{$self->id});
+
     return $self;
 }
 
@@ -381,6 +386,15 @@ sub object_cache_key {
     return $key . ',' . Bugzilla->user->id;
 }
 
+sub CLEANUP {
+    foreach my $bug (values %CLEANUP) {
+        next unless $bug;
+        delete $bug->{depends_on_obj};
+        delete $bug->{blocks_obj};
+    }
+    %CLEANUP = ();
+}
+
 sub check {
     my $class = shift;
     my ($param, $field) = @_;
index 69e973c7feca986fb3e6d44e3064b96570b6c2e8..ff718c9e17ce3ef1329cec6d39e0bb3681030197 100644 (file)
@@ -34,7 +34,7 @@ use Bugzilla::User;
 use Bugzilla::Util;
 
 use List::Util qw(first);
-use Scalar::Util qw(blessed);
+use Scalar::Util qw(blessed weaken);
 
 ###############################
 ####    Initialization     ####
@@ -241,8 +241,9 @@ sub collapsed_reason {
 sub bug {
     my $self = shift;
     require Bugzilla::Bug;
-    $self->{bug} ||= new Bugzilla::Bug($self->bug_id);
-    return $self->{bug};
+    my $bug = $self->{bug} ||= new Bugzilla::Bug($self->bug_id);
+    weaken($self->{bug});
+    return $bug;
 }
 
 sub is_about_attachment {
index b150faea27e1c5d519f1c604acb735e352fbebf4..08e7968a03aa73a571d016a77de5101c3b0572e0 100644 (file)
@@ -29,6 +29,7 @@ use JSON;
 use List::MoreUtils qw(none);
 
 our $VERSION = '1';
+our @FLAG_CACHE;
 
 BEGIN {
     *Bugzilla::tracking_flags      = \&_tracking_flags;
@@ -552,6 +553,20 @@ sub _tracking_flags_search_nonchanged {
     }
 }
 
+sub request_cleanup {
+    foreach my $flag (@FLAG_CACHE) {
+        my $bug_flag = delete $flag->{bug_flag};
+        if ($bug_flag) {
+            delete $bug_flag->{bug};
+            delete $bug_flag->{tracking_flag};
+        }
+        foreach my $value (@{ $flag->{values} }) {
+            delete $value->{tracking_flag};
+        }
+    }
+    @FLAG_CACHE = ();
+}
+
 sub bug_end_of_create {
     my ($self, $args) = @_;
     my $bug       = $args->{'bug'};
index cfda0bad560a9fc55cb49be647e2f320b602f0c3..7b6effa9873d0e3a1a5963df395f6d498818010f 100644 (file)
@@ -87,6 +87,16 @@ sub new {
     return $class->SUPER::new($param);
 }
 
+sub new_from_hash {
+    my $class = shift;
+    my $cache = Bugzilla->request_cache->{'tracking_flags'} //= {};
+    my $flag = $class->SUPER::new_from_hash(@_);
+    if ($flag) {
+        push @Bugzilla::Extension::TrackingFlags::FLAG_CACHE, $flag;
+    }
+    return $flag;
+}
+
 sub create {
     my $class = shift;
     my $params = shift;
index 964d76810a4325e85cf7b2dc3d1acf74f8901120..15be61bc7109df7103cfa6084f46c471d8015fd0 100644 (file)
@@ -15,7 +15,7 @@ use warnings;
 use Bugzilla::Error;
 use Bugzilla::Group;
 use Bugzilla::Util qw(detaint_natural trim);
-use Scalar::Util qw(blessed);
+use Scalar::Util qw(blessed weaken);
 
 ###############################
 ####    Initialization     ####
@@ -118,9 +118,12 @@ sub is_active        { return $_[0]->{'is_active'};        }
 sub comment          { return $_[0]->{'comment'};          }
 
 sub tracking_flag {
-    return $_[0]->{'tracking_flag'} ||= Bugzilla::Extension::TrackingFlags::Flag->new({
+    return $_[0]->{'tracking_flag'} if $_[0]->{'tracking_flag'};
+    my $tf = $_[0]->{'tracking_flag'} = Bugzilla::Extension::TrackingFlags::Flag->new({
         id => $_[0]->tracking_flag_id, cache => 1
     });
+    weaken($_[0]->{'tracking_flag'});
+    return $tf;
 }
 
 sub setter_group {