chiark / gitweb /
prefork-interp: autoreload check
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 21 Aug 2022 11:53:13 +0000 (12:53 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Sun, 21 Aug 2022 20:21:10 +0000 (21:21 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
pm/Proc/Prefork/Interp.pm

index d11051f1f89bc12542d5161a77526269d08fa47e..14063516ab3e91c23f097ae4fdbcca785b3b7f0b 100644 (file)
@@ -11,6 +11,7 @@ use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
 use IO::FDPass;
 use POSIX qw(_exit setsid :sys_wait_h :errno_h :signal_h);
 use Sys::Syslog qw(openlog syslog LOG_INFO LOG_ERR LOG_WARNING);
+use Time::HiRes qw();
 
 our $logger;
 
@@ -156,6 +157,19 @@ sub protocol_exchange () {
   }
 }
 
+sub autoreload_check ($) {
+  my ($f) = @_;
+  my @s = Time::HiRes::stat($f);
+  if (!@s) {
+    $!==ENOENT or fail_log("autoreload check: stat failed: $f: $!");
+    return;
+  }
+  if ($s[9] > $startup_mtime) {
+    syslog(LOG_INFO, "$0 prefork [$$]: reloading; due to $f");
+    _exit(0);
+  }
+}
+
 sub initialisation_complete {
   my %opts = @_;
 
@@ -271,7 +285,14 @@ sub initialisation_complete {
       fail_log("watcher stderr read: $!");
     }
 
-    # TODO stat checking, quit here if we are stale
+    if (%opts{autoreload_inc} // 1) {
+      foreach my $f (values %INC) {
+       autoreload_check($f);
+      }
+    }
+    foreach my $f (@{ %opts{autoreload_extra} // [] }) {
+      autoreload_check($f);
+    }
 
     # Anything to accept ?
     if (accept(CALL, LISTEN)) {