Ticket #382: backendmanager-remotetcp-clean-up-child-pids.patch
File backendmanager-remotetcp-clean-up-child-pids.patch, 2.5 KB (added by , 15 years ago) |
---|
-
harness/backendmanager_remotetcp.cc
69 69 70 70 // We can't dynamically allocate memory for this because it confuses the leak 71 71 // detector. We only have 1-3 child fds open at once anyway, so a fixed size 72 // array isn't a problem, and linear scanning isn't a problem .72 // array isn't a problem, and linear scanning isn't a problem either. 73 73 struct pid_fd { 74 74 pid_t pid; 75 75 int fd; … … 77 77 78 78 static pid_fd pid_to_fd[16]; 79 79 80 static void 81 clean_up_fd_for_pid(pid_t pid) 82 { 83 for (unsigned i = 0; i < sizeof(pid_to_fd) / sizeof(pid_fd); ++i) { 84 if (pid_to_fd[i].pid == pid) { 85 int fd = pid_to_fd[i].fd; 86 pid_to_fd[i].fd = -1; 87 pid_to_fd[i].pid = 0; 88 // NB close() *is* safe to use in a signal handler. 89 close(fd); 90 break; 91 } 92 } 93 } 94 80 95 extern "C" { 96 81 97 static void 82 98 on_SIGCHLD(int /*sig*/) 83 99 { 84 100 int status; 85 101 pid_t child; 86 102 while ((child = waitpid(-1, &status, WNOHANG)) > 0) { 87 for (unsigned i = 0; i < sizeof(pid_to_fd) / sizeof(pid_fd); ++i) { 88 if (pid_to_fd[i].pid == child) { 89 int fd = pid_to_fd[i].fd; 90 pid_to_fd[i].fd = -1; 91 pid_to_fd[i].pid = -1; 92 // NB close() *is* safe to use in a signal handler. 93 close(fd); 94 break; 95 } 96 } 103 clean_up_fd_for_pid(child); 97 104 } 98 105 } 106 99 107 } 100 108 101 109 static int … … 104 112 int port = DEFAULT_PORT; 105 113 106 114 // We want to be able to get the exit status of the child process we fork 107 // i nxapian-tcpsrv doesn't start listening successfully.115 // if xapian-tcpsrv doesn't start listening successfully. 108 116 signal(SIGCHLD, SIG_DFL); 109 117 try_next_port: 110 118 string cmd = XAPIAN_TCPSRV" --one-shot --interface "LOCALHOST" --port " + om_tostring(port) + " " + args; … … 150 158 msg += strerror(errno); 151 159 throw msg; 152 160 } 161 153 162 string output; 154 163 while (true) { 155 164 char buf[256]; 156 165 if (fgets(buf, sizeof(buf), fh) == NULL) { 157 166 fclose(fh); 167 // Wait for the child to exit. 158 168 int status; 159 169 if (waitpid(child, &status, 0) == -1) { 160 170 string msg("waitpid failed: "); … … 191 201 // Find a slot to track the pid->fd mapping in. If we can't find a slot 192 202 // it just means we'll leak the fd, so don't worry about that too much. 193 203 for (unsigned i = 0; i < sizeof(pid_to_fd) / sizeof(pid_fd); ++i) { 194 if (pid_to_fd[i].pid == -1) {204 if (pid_to_fd[i].pid == 0) { 195 205 pid_to_fd[i].fd = tracked_fd; 196 206 pid_to_fd[i].pid = child; 197 207 break;