@matheusbsbs / matheus-bagliano / commits / 695605b508
Fork 0

git-daemon: Simplify dead-children reaping logic

Move almost all code out of the child_handler() into check_dead_children(). The fact that systemcalls get interrupted by signals allows us to make the SIGCHLD signal handler almost a no-op by simply running check_dead_children() right before waiting on poll(). In case some systems do not interrupt systemcalls upon signal receipt, all zombies will eventually be collected before the next poll() cycle. Signed-off-by: Stephen R. van den Berg <srb@cuci.nl> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Stephen R. van den Berg committed Aug 14, 2008 at 20:02 UTC 695605b5080e1957bd9dab1fed35a7fee9814297
1 file changed +23 -32
daemon.c
+23 -32
@@ -16,7 +16,6 @@
16 static int log_syslog;
17 static int verbose;
18 static int reuseaddr;
19 -static int child_handler_pipe[2];
19
20 static const char daemon_usage[] =
21 "git daemon [--verbose] [--syslog] [--export-all]\n"
@@ -680,6 +679,21 @@ static void check_dead_children(void)
679 {
680 unsigned spawned, reaped, deleted;
681
682 + for (;;) {
683 + int status;
684 + pid_t pid = waitpid(-1, &status, WNOHANG);
685 +
686 + if (pid > 0) {
687 + unsigned reaped = children_reaped;
688 + if (!WIFEXITED(status) || WEXITSTATUS(status) > 0)
689 + pid = -pid;
690 + dead_child[reaped % MAX_CHILDREN] = pid;
691 + children_reaped = reaped + 1;
692 + continue;
693 + }
694 + break;
695 + }
696 +
697 spawned = children_spawned;
698 reaped = children_reaped;
699 deleted = children_deleted;
@@ -760,21 +774,10 @@ static void handle(int incoming, struct sockaddr *addr, int addrlen)
774
775 static void child_handler(int signo)
776 {
763 - for (;;) {
764 - int status;
765 - pid_t pid = waitpid(-1, &status, WNOHANG);
766 -
767 - if (pid > 0) {
768 - unsigned reaped = children_reaped;
769 - if (!WIFEXITED(status) || WEXITSTATUS(status) > 0)
770 - pid = -pid;
771 - dead_child[reaped % MAX_CHILDREN] = pid;
772 - children_reaped = reaped + 1;
773 - write(child_handler_pipe[1], &status, 1);
774 - continue;
775 - }
776 - break;
777 - }
777 + /* Otherwise empty handler because systemcalls will get interrupted
778 + * upon signal receipt
779 + * SysV needs the handler to be rearmed
780 + */
781 signal(SIGCHLD, child_handler);
782 }
783
@@ -917,24 +920,21 @@ static int service_loop(int socknum, int *socklist)
920 struct pollfd *pfd;
921 int i;
922
920 - if (pipe(child_handler_pipe) < 0)
921 - die ("Could not set up pipe for child handler");
922 -
923 - pfd = xcalloc(socknum + 1, sizeof(struct pollfd));
923 + pfd = xcalloc(socknum, sizeof(struct pollfd));
924
925 for (i = 0; i < socknum; i++) {
926 pfd[i].fd = socklist[i];
927 pfd[i].events = POLLIN;
928 }
929 - pfd[socknum].fd = child_handler_pipe[0];
930 - pfd[socknum].events = POLLIN;
929
930 signal(SIGCHLD, child_handler);
931
932 for (;;) {
933 int i;
934
937 - if (poll(pfd, socknum + 1, -1) < 0) {
935 + check_dead_children();
936 +
937 + if (poll(pfd, socknum, -1) < 0) {
938 if (errno != EINTR) {
939 logerror("Poll failed, resuming: %s",
940 strerror(errno));
@@ -942,10 +942,6 @@ static int service_loop(int socknum, int *socklist)
942 }
943 continue;
944 }
945 - if (pfd[socknum].revents & POLLIN) {
946 - read(child_handler_pipe[0], &i, 1);
947 - check_dead_children();
948 - }
945
946 for (i = 0; i < socknum; i++) {
947 if (pfd[i].revents & POLLIN) {
@@ -1036,11 +1032,6 @@ int main(int argc, char **argv)
1032 gid_t gid = 0;
1033 int i;
1034
1039 - /* Without this we cannot rely on waitpid() to tell
1040 - * what happened to our children.
1041 - */
1042 - signal(SIGCHLD, SIG_DFL);
1043 -
1035 for (i = 1; i < argc; i++) {
1036 char *arg = argv[i];
1037