Chromium Code Reviews| Index: runtime/bin/process_linux.cc |
| diff --git a/runtime/bin/process_linux.cc b/runtime/bin/process_linux.cc |
| index 5cd52fb38285302ddfb7c2aa956da8586a793d20..a20571ed92220def8ace3676cd7f31df5915c390 100644 |
| --- a/runtime/bin/process_linux.cc |
| +++ b/runtime/bin/process_linux.cc |
| @@ -25,6 +25,12 @@ |
| class ProcessInfo { |
| public: |
| ProcessInfo(pid_t pid, intptr_t fd) : pid_(pid), fd_(fd) { } |
| + ~ProcessInfo() { |
| + int closed = TEMP_FAILURE_RETRY(close(fd_)); |
| + if (closed != 0) { |
| + FATAL("Failed to close process exit code pipe"); |
| + } |
| + } |
| pid_t pid() { return pid_; } |
| intptr_t fd() { return fd_; } |
| ProcessInfo* next() { return next_; } |
| @@ -101,6 +107,8 @@ dart::Mutex ProcessInfoList::mutex_; |
| // event loop. |
| class ExitCodeHandler { |
| public: |
| + static const char kTerminateByte = 1; |
|
Søren Gjesse
2012/02/01 07:39:17
uint8_t?
Mads Ager (google)
2012/02/01 09:08:57
Done.
|
| + |
| // Ensure that the ExitCodeHandler has been initialized. |
| static bool EnsureInitialized() { |
| // Multiple isolates could be starting processes at the same |
| @@ -136,6 +144,18 @@ class ExitCodeHandler { |
| return sig_chld_fds_[1]; |
| } |
| + static void Terminate() { |
| + MutexLocker locker(&mutex_); |
| + if (!initialized_) { |
| + return; |
| + } |
| + char data = ExitCodeHandler::kTerminateByte; |
| + ssize_t result = TEMP_FAILURE_RETRY(write(WakeUpFd(), &data, 1)); |
| + if (result < 1) { |
| + perror("Failed to write to wake-up fd in SIGCHLD handler"); |
| + } |
| + } |
| + |
| private: |
| // GetProcessExitCodes is called on a separate thread when a SIGCHLD |
| // signal is received to retrieve the exit codes and post them to |
| @@ -155,13 +175,13 @@ class ExitCodeHandler { |
| } |
| intptr_t exit_code_fd = ProcessInfoList::LookupProcessExitFd(pid); |
| if (exit_code_fd != 0) { |
| - int message[3] = { pid, exit_code, negative }; |
| + int message[2] = { exit_code, negative }; |
| ssize_t result = |
| FDUtils::WriteToBlocking(exit_code_fd, &message, sizeof(message)); |
| if (result != sizeof(message) && errno != EPIPE) { |
| perror("ExitHandler notification failed"); |
| } |
| - TEMP_FAILURE_RETRY(close(exit_code_fd)); |
| + ProcessInfoList::RemoveProcess(pid); |
| } |
| } |
| } |
| @@ -188,6 +208,10 @@ class ExitCodeHandler { |
| if (read_bytes < 1) { |
| perror("Failed to read from wake-up fd in exit-code handler"); |
| } |
| + // Check if the ExitCodeHandler has been terminated. |
| + if (data == ExitCodeHandler::kTerminateByte) { |
| + return; |
| + } |
| // Get the exit code from all processes that have died. |
| GetProcessExitCodes(); |
| } |
| @@ -488,6 +512,6 @@ bool Process::Kill(intptr_t id) { |
| } |
| -void Process::Exit(intptr_t id) { |
| - ProcessInfoList::RemoveProcess(id); |
| +void Process::TerminateExitCodeHandler() { |
| + ExitCodeHandler::Terminate(); |
| } |