about summary refs log tree commit homepage
path: root/lib/PublicInbox/DS.pm
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2023-10-04 08:50:56 +0000
committerEric Wong <e@80x24.org>2023-10-04 17:46:52 +0000
commit1897c3be1ed644a05f96ed06cde4a9cc2ad0e5a4 (patch)
tree6d346e7ba6e04804a527a91c69241a7d57307c6b /lib/PublicInbox/DS.pm
parent6382fa476abc4f044e7723d5e6e4f848e9077f51 (diff)
downloadpublic-inbox-1897c3be1ed644a05f96ed06cde4a9cc2ad0e5a4.tar.gz
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.
Diffstat (limited to 'lib/PublicInbox/DS.pm')
-rw-r--r--lib/PublicInbox/DS.pm10
1 files changed, 7 insertions, 3 deletions
diff --git a/lib/PublicInbox/DS.pm b/lib/PublicInbox/DS.pm
index d8824a55..e085a010 100644
--- a/lib/PublicInbox/DS.pm
+++ b/lib/PublicInbox/DS.pm
@@ -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));