]> git.ipfire.org Git - thirdparty/public-inbox.git/commitdiff
ds: Reset: replace Poller object early
authorEric Wong <e@80x24.org>
Wed, 4 Oct 2023 08:50:56 +0000 (08:50 +0000)
committerEric Wong <e@80x24.org>
Wed, 4 Oct 2023 17:46:52 +0000 (17:46 +0000)
Process shutdown can be chaotic and unpredictable.  Try to make
it more predictable by ensuring any PublicInbox::Select object
can't hold references to any objects.

This should fix the following error I saw in syslog during a deploy:

Can't call method "FILENO" on an undefined value at
.../PublicInbox/Select.pm line 34 during global destruction.

Replacing $Poller with PublicInbox::Select (instead of undef-ing
it) means we can avoid adding branches to ->epwait and ->close
before calls to ->ep_mod and ->ep_del, respectively.

lib/PublicInbox/DS.pm

index d8824a55d640f0079295e88deb9b6d87dcdd8ea4..e085a010eda3a43bdb912514f78a97a8ae832c25 100644 (file)
@@ -69,7 +69,11 @@ Reset all state
 sub Reset {
        do {
                $in_loop = undef; # first in case DESTROY callbacks use this
-               %DescriptorMap = ();
+               # clobbering $Poller may call DSKQXS::DESTROY,
+               # we must always have this set to something to avoid
+               # needing branches before ep_del/ep_mod calls (via ->close).
+               $Poller = PublicInbox::Select->new;
+               %DescriptorMap = (); # likely to call ep_del
                @Timers = ();
                %UniqTimer = ();
                @post_loop_do = ();
@@ -77,8 +81,8 @@ sub Reset {
                # we may be iterating inside one of these on our stack
                my @q = delete @Stack{keys %Stack};
                for my $q (@q) { @$q = () }
-               $AWAIT_PIDS = $nextq = $ToClose = undef;
-               $Poller = undef; # may call DSKQXS::DESTROY
+               $AWAIT_PIDS = $nextq = $ToClose = undef; # may call ep_del
+               $Poller = PublicInbox::Select->new;
        } while (@Timers || keys(%Stack) || $nextq || $AWAIT_PIDS ||
                $ToClose || keys(%DescriptorMap) ||
                @post_loop_do || keys(%UniqTimer));