]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/Daemon.pm
update copyrights for 2018
[public-inbox.git] / lib / PublicInbox / Daemon.pm
index 512bb2083c5c65f84f9627c455780c19b7abc62b..0329bd34ed3292ea93b7db3a737bded43119bf43 100644 (file)
@@ -1,5 +1,5 @@
-# Copyright (C) 2015 all contributors <meta@public-inbox.org>
-# License: AGPLv3 or later (https://www.gnu.org/licenses/agpl-3.0.txt)
+# Copyright (C) 2015-2018 all contributors <meta@public-inbox.org>
+# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
 # contains common daemon code for the nntpd and httpd servers.
 # This may be used for read-only IMAP server if we decide to implement it.
 package PublicInbox::Daemon;
@@ -9,6 +9,7 @@ use Getopt::Long qw/:config gnu_getopt no_ignore_case auto_abbrev/;
 use IO::Handle;
 use IO::Socket;
 use Cwd qw/abs_path/;
+use Time::HiRes qw(clock_gettime CLOCK_MONOTONIC);
 STDOUT->autoflush(1);
 STDERR->autoflush(1);
 require Danga::Socket;
@@ -102,17 +103,18 @@ sub check_absolute ($$) {
 }
 
 sub daemonize () {
-       foreach my $i (0..$#ARGV) {
-               my $arg = $ARGV[$i];
-               next unless -e $arg;
-               $ARGV[$i] = abs_path($arg);
-       }
-       check_absolute('stdout', $stdout);
-       check_absolute('stderr', $stderr);
-       check_absolute('pid-file', $pid_file);
+       if ($daemonize) {
+               foreach my $i (0..$#ARGV) {
+                       my $arg = $ARGV[$i];
+                       next unless -e $arg;
+                       $ARGV[$i] = abs_path($arg);
+               }
+               check_absolute('stdout', $stdout);
+               check_absolute('stderr', $stderr);
+               check_absolute('pid-file', $pid_file);
 
-       chdir '/' or die "chdir failed: $!";
-       open(STDIN, '+<', '/dev/null') or die "redirect stdin failed: $!";
+               chdir '/' or die "chdir failed: $!";
+       }
 
        return unless (defined $pid_file || defined $group || defined $user
                        || $daemonize);
@@ -145,6 +147,8 @@ sub daemonize () {
                die "could not fork: $!\n" unless defined $pid;
                exit if $pid;
 
+               open(STDIN, '+<', '/dev/null') or
+                                       die "redirect stdin failed: $!\n";
                open STDOUT, '>&STDIN' or die "redirect stdout failed: $!\n";
                open STDERR, '>&STDIN' or die "redirect stderr failed: $!\n";
                POSIX::setsid();
@@ -178,10 +182,11 @@ sub worker_quit {
        Danga::Socket->SetPostLoopCallback(sub {
                my ($dmap, undef) = @_;
                my $n = 0;
+               my $now = clock_gettime(CLOCK_MONOTONIC);
 
                foreach my $s (values %$dmap) {
                        $s->can('busy') or next;
-                       if ($s->busy) {
+                       if ($s->busy($now)) {
                                ++$n;
                        } else {
                                # close as much as possible, early as possible
@@ -376,12 +381,12 @@ sub master_loop {
                                exit if $quit++;
                                kill_workers($s);
                        } elsif ($s eq 'WINCH') {
-                               if ($daemonize) {
-                                       $worker_processes = 0;
-                               } else {
+                               if (-t STDIN || -t STDOUT || -t STDERR) {
                                        warn
 "ignoring SIGWINCH since we are not daemonized\n";
                                        $SIG{WINCH} = 'IGNORE';
+                               } else {
+                                       $worker_processes = 0;
                                }
                        } elsif ($s eq 'HUP') {
                                $worker_processes = $set_workers;
@@ -449,7 +454,8 @@ sub daemon_loop ($$) {
        $SIG{QUIT} = $SIG{INT} = $SIG{TERM} = *worker_quit;
        $SIG{USR1} = *reopen_logs;
        $SIG{HUP} = $refresh;
-       $SIG{$_} = 'DEFAULT' for qw(CHLD USR2 TTIN TTOU WINCH);
+       $SIG{CHLD} = 'DEFAULT';
+       $SIG{$_} = 'IGNORE' for qw(USR2 TTIN TTOU WINCH);
        # this calls epoll_create:
        @listeners = map {
                PublicInbox::Listener->new($_, $post_accept)