From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-Status: No, score=-4.0 required=3.0 tests=ALL_TRUSTED,BAYES_00 shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 2D5941F5AE for ; Tue, 23 Jun 2020 23:21:14 +0000 (UTC) From: Eric Wong To: meta@public-inbox.org Subject: [PATCH] git_async_cat: remove circular reference Date: Tue, 23 Jun 2020 23:21:12 +0000 Message-Id: <20200623232112.98782-1-e@yhbt.net> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: While this circular reference was carefully managed to not leak memory; it was still triggering a warning at -imapd/-nntpd shutdown due to the EPOLL_CTL_DEL op failing after the $Epoll FD gets closed. So remove the circular reference by providing a ref to `undef', instead. --- lib/PublicInbox/Git.pm | 4 +--- lib/PublicInbox/GitAsyncCat.pm | 10 +++++----- lib/PublicInbox/IMAP.pm | 2 +- lib/PublicInbox/NNTP.pm | 9 +++------ 4 files changed, 10 insertions(+), 15 deletions(-) diff --git a/lib/PublicInbox/Git.pm b/lib/PublicInbox/Git.pm index a55c48d5..776e4832 100644 --- a/lib/PublicInbox/Git.pm +++ b/lib/PublicInbox/Git.pm @@ -295,9 +295,7 @@ sub qx { sub cleanup { my ($self) = @_; local $in_cleanup = 1; - if (my $ac = $self->{async_cat}) { - $ac->close; # PublicInbox::GitAsyncCat::close -> EPOLL_CTL_DEL - } + delete $self->{async_cat}; cat_async_wait($self); _destroy($self, qw(cat_rbuf in out pid)); _destroy($self, qw(chk_rbuf in_c out_c pid_c err_c)); diff --git a/lib/PublicInbox/GitAsyncCat.pm b/lib/PublicInbox/GitAsyncCat.pm index 8701e4cf..098101ae 100644 --- a/lib/PublicInbox/GitAsyncCat.pm +++ b/lib/PublicInbox/GitAsyncCat.pm @@ -15,20 +15,20 @@ use fields qw(git); use PublicInbox::Syscall qw(EPOLLIN EPOLLET); our @EXPORT = qw(git_async_cat); -sub new { +sub _add { my ($class, $git) = @_; my $self = fields::new($class); $git->batch_prepare; $self->SUPER::new($git->{in}, EPOLLIN|EPOLLET); $self->{git} = $git; - $self; + \undef; # this is a true ref() } sub event_step { my ($self) = @_; my $git = $self->{git} or return; # ->close-ed my $inflight = $git->{inflight}; - if (@$inflight) { + if ($inflight && @$inflight) { $git->cat_async_step($inflight); $self->requeue if @$inflight || exists $git->{cat_rbuf}; } @@ -37,7 +37,7 @@ sub event_step { sub close { my ($self) = @_; if (my $git = delete $self->{git}) { - delete $git->{async_cat}; # drop circular reference + delete $git->{async_cat}; } $self->SUPER::close; # PublicInbox::DS::close } @@ -45,7 +45,7 @@ sub close { sub git_async_cat ($$$$) { my ($git, $oid, $cb, $arg) = @_; $git->cat_async($oid, $cb, $arg); - $git->{async_cat} //= new(__PACKAGE__, $git); # circular reference + $git->{async_cat} //= _add(__PACKAGE__, $git); } 1; diff --git a/lib/PublicInbox/IMAP.pm b/lib/PublicInbox/IMAP.pm index dec10d61..0a6993c6 100644 --- a/lib/PublicInbox/IMAP.pm +++ b/lib/PublicInbox/IMAP.pm @@ -1294,7 +1294,7 @@ sub long_step { } elsif ($more) { # $self->{wbuf}: $self->update_idle_time; - # control passed to $more may be a GitAsyncCat object + # control passed to git_async_cat if $more == \undef requeue_once($self) if !ref($more); } else { # all done! delete $self->{long_cb}; diff --git a/lib/PublicInbox/NNTP.pm b/lib/PublicInbox/NNTP.pm index 6df19f32..76f14bbd 100644 --- a/lib/PublicInbox/NNTP.pm +++ b/lib/PublicInbox/NNTP.pm @@ -553,8 +553,7 @@ sub cmd_article ($;$) { return $smsg unless ref $smsg; set_art($self, $art); $smsg->{nntp} = $self; - git_async_cat($self->{ng}->git, $smsg->{blob}, \&blob_cb, $smsg); - undef; + ${git_async_cat($self->{ng}->git, $smsg->{blob}, \&blob_cb, $smsg)}; } sub cmd_head ($;$) { @@ -564,8 +563,7 @@ sub cmd_head ($;$) { set_art($self, $art); $smsg->{nntp} = $self; $smsg->{nntp_code} = 221; - git_async_cat($self->{ng}->git, $smsg->{blob}, \&blob_cb, $smsg); - undef; + ${git_async_cat($self->{ng}->git, $smsg->{blob}, \&blob_cb, $smsg)}; } sub cmd_body ($;$) { @@ -575,8 +573,7 @@ sub cmd_body ($;$) { set_art($self, $art); $smsg->{nntp} = $self; $smsg->{nntp_code} = 222; - git_async_cat($self->{ng}->git, $smsg->{blob}, \&blob_cb, $smsg); - undef; + ${git_async_cat($self->{ng}->git, $smsg->{blob}, \&blob_cb, $smsg)}; } sub cmd_stat ($;$) {