So ... I need a good way to allow multiple signal handlers.
$SIG{'HUP'} = sub { $HUP_COUNT++; reset_caches(); }; sub reset_caches { %FileModTime = (); %Config = (); %FileBlockData = (); %FileBlockFlags = (); }Later ljlib.pl is included from lj-bml-init.pl:
## we want to set this right away, so when we get a HUP signal later ## and our signal handler sets it to true, perl doesn't need to malloc, ## since malloc may not be thread-safe and we could core dump. ## see LJ::clear_caches and LJ::handle_caches $LJ::CLEAR_CACHES = 0; ## if this library is used in a BML page, we don't want to destroy BML's ## HUP signal handler. if ($SIG{'HUP'}) { my $oldsig = $SIG{'HUP'}; $SIG{'HUP'} = sub { &{$oldsig}; &LJ::clear_caches; }; } else { $SIG{'HUP'} = \&LJ::clear_caches; } # called from a HUP signal handler, so intentionally very very simple # so we don't core dump on a system without reentrant libraries. sub clear_caches { $LJ::CLEAR_CACHES = 1; } # handle_caches # clears caches, if the CLEAR_CACHES flag is set from an earlier HUP signal. # always returns trues, so you can use it in a conjunction of statements # in a while loop around the application like: # while (LJ::handle_caches() && FCGI::accept()) sub handle_caches { return 1 unless ($LJ::CLEAR_CACHES); $LJ::CLEAR_CACHES = 0; %LJ::CACHE_STYLE = (); %LJ::CACHE_PROPS = (); $LJ::CACHED_MOODS = 0; $LJ::CACHED_MOOD_MAX = 0; %LJ::CACHE_MOODS = (); %LJ::CACHE_MOOD_THEME = (); %LJ::CACHE_USERID = (); %LJ::CACHE_USERNAME = (); %LJ::CACHE_USERPIC_SIZE = (); %LJ::CACHE_CODES = (); %LJ::CACHE_USERPROP = (); # {$prop}->{ 'upropid' => ... , 'indexed' => 0|1 }; return 1; }
The new hack is in bold. Proposals for a better way?
The only problem with this is that if ljlib.pl is included more than once, its signal handler is added to the list extra times. But since we're removing all "require 'ljlib.pl'" lines from the code, this isn't a problem, really.
Comments?