about summary refs log tree commit homepage
path: root/xt
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2023-03-21 23:07:26 +0000
committerEric Wong <e@80x24.org>2023-03-25 09:37:48 +0000
commitd00087bcdf3a4c2411ecdf75b4f7ee583db530fb (patch)
tree092723bc50a32272eae50e13871b74d953a14a0e /xt
parent87a8527cb3e09b88f224b8ba0aad28cb8ec8eba8 (diff)
downloadpublic-inbox-d00087bcdf3a4c2411ecdf75b4f7ee583db530fb.tar.gz
This allows us to avoid repeatedly using memory-intensive
anonymous subs in CodeSearchIdx where the callback is assigned
frequently.  Anonymous subs are known to leak memory in old
Perls (e.g. 5.16.3 in enterprise distros) and still expensive in
newer Perls.  So favor the (\&subroutine, @args) form which
allows us to eliminate anonymous subs going forward.

Only CodeSearchIdx takes advantage of the new API at the moment,
since it's the biggest repeat user of post-loop callback
changes.

Getting rid of the subroutine and relying on a global `our'
variable also has two advantages:

1) Perl warnings can detect typos at compile-time, whereas the
   (now gone) method could only detect errors at run-time.

2) `our' variable assignment can be `local'-ized to a scope
Diffstat (limited to 'xt')
-rw-r--r--xt/mem-imapd-tls.t7
-rw-r--r--xt/mem-nntpd-tls.t8
-rw-r--r--xt/net_writer-imap.t4
3 files changed, 9 insertions, 10 deletions
diff --git a/xt/mem-imapd-tls.t b/xt/mem-imapd-tls.t
index 75f2911f..00199a9b 100644
--- a/xt/mem-imapd-tls.t
+++ b/xt/mem-imapd-tls.t
@@ -82,7 +82,7 @@ sub once { 0 }; # stops event loop
 # setup the event loop so that it exits at every step
 # while we're still doing connect(2)
 PublicInbox::DS->SetLoopTimeout(0);
-PublicInbox::DS->SetPostLoopCallback(\&once);
+local @PublicInbox::DS::post_loop_do = (\&once);
 my $pid = $td->{pid};
 if ($^O eq 'linux' && open(my $f, '<', "/proc/$pid/status")) {
         diag(grep(/RssAnon/, <$f>));
@@ -101,14 +101,13 @@ foreach my $n (1..$nfd) {
         if (!($n % 128) && $DONE != $n) {
                 diag("nr: ($n) $DONE/$nfd");
                 PublicInbox::DS->SetLoopTimeout(-1);
-                PublicInbox::DS->SetPostLoopCallback(sub { $DONE != $n });
+                local @PublicInbox::DS::post_loop_do = (sub { $DONE != $n });
 
                 # clear the backlog:
                 PublicInbox::DS::event_loop();
 
                 # resume looping
                 PublicInbox::DS->SetLoopTimeout(0);
-                PublicInbox::DS->SetPostLoopCallback(\&once);
         }
 }
 
@@ -116,7 +115,7 @@ foreach my $n (1..$nfd) {
 diag "done?: @".time." $DONE/$nfd";
 if ($DONE != $nfd) {
         PublicInbox::DS->SetLoopTimeout(-1);
-        PublicInbox::DS->SetPostLoopCallback(sub { $DONE != $nfd });
+        local @PublicInbox::DS::post_loop_do = (sub { $DONE != $nfd });
         PublicInbox::DS::event_loop();
 }
 is($nfd, $DONE, "$nfd/$DONE done");
diff --git a/xt/mem-nntpd-tls.t b/xt/mem-nntpd-tls.t
index 6e34d233..a861e318 100644
--- a/xt/mem-nntpd-tls.t
+++ b/xt/mem-nntpd-tls.t
@@ -105,7 +105,7 @@ sub once { 0 }; # stops event loop
 # setup the event loop so that it exits at every step
 # while we're still doing connect(2)
 PublicInbox::DS->SetLoopTimeout(0);
-PublicInbox::DS->SetPostLoopCallback(\&once);
+local @PublicInbox::DS::post_loop_do = (\&once);
 
 foreach my $n (1..$nfd) {
         my $io = tcp_connect($nntps, Blocking => 0);
@@ -120,14 +120,14 @@ foreach my $n (1..$nfd) {
         if (!($n % 128) && $n != $DONE) {
                 diag("nr: ($n) $DONE/$nfd");
                 PublicInbox::DS->SetLoopTimeout(-1);
-                PublicInbox::DS->SetPostLoopCallback(sub { $DONE != $n });
+                @PublicInbox::DS::post_loop_do = (sub { $DONE != $n });
 
                 # clear the backlog:
                 PublicInbox::DS::event_loop();
 
                 # resume looping
                 PublicInbox::DS->SetLoopTimeout(0);
-                PublicInbox::DS->SetPostLoopCallback(\&once);
+                @PublicInbox::DS::post_loop_do = (\&once);
         }
 }
 my $pid = $td->{pid};
@@ -141,7 +141,7 @@ $dump_rss->();
 # run the event loop normally, now:
 if ($DONE != $nfd) {
         PublicInbox::DS->SetLoopTimeout(-1);
-        PublicInbox::DS->SetPostLoopCallback(sub {
+        @PublicInbox::DS::post_loop_do = (sub {
                 diag "done: ".time." $DONE";
                 $DONE != $nfd;
         });
diff --git a/xt/net_writer-imap.t b/xt/net_writer-imap.t
index 333e0e3b..f7796e8e 100644
--- a/xt/net_writer-imap.t
+++ b/xt/net_writer-imap.t
@@ -1,5 +1,5 @@
 #!perl -w
-# Copyright (C) 2021 all contributors <meta@public-inbox.org>
+# Copyright (C) all contributors <meta@public-inbox.org>
 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
 use strict; use v5.10.1; use PublicInbox::TestCommon;
 use Sys::Hostname qw(hostname);
@@ -233,7 +233,7 @@ EOM
         my $pub_cfg = PublicInbox::Config->new;
         PublicInbox::DS->Reset;
         my $ii = PublicInbox::InboxIdle->new($pub_cfg);
-        my $cb = sub { PublicInbox::DS->SetPostLoopCallback(sub {}) };
+        my $cb = sub { @PublicInbox::DS::post_loop_do = (sub {}) };
         my $obj = bless \$cb, 'PublicInbox::TestCommon::InboxWakeup';
         $pub_cfg->each_inbox(sub { $_[0]->subscribe_unlock('ident', $obj) });
         my $w = start_script(['-watch'], undef, { 2 => $err_wr });