Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(591)

Unified Diff: runtime/bin/process_macos.cc

Issue 8227010: Fix deadlock in process exit handling (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Addressed review comments from @ager Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/bin/process_linux.cc ('k') | runtime/tests/dart/dart.status » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/bin/process_macos.cc
diff --git a/runtime/bin/process_macos.cc b/runtime/bin/process_macos.cc
index e43f486f76114115a9134a47ed0105d0292c1492..acf2d872e2f035d67c6ab0beeffd8cd61b445d99 100644
--- a/runtime/bin/process_macos.cc
+++ b/runtime/bin/process_macos.cc
@@ -15,21 +15,60 @@
#include "bin/set.h"
-class ActiveProcess {
+class ProcessInfo {
public:
- pid_t pid;
- intptr_t fd;
+ ProcessInfo(pid_t pid, intptr_t fd) : pid_(pid), fd_(fd) { }
+
+ pid_t pid() { return pid_; }
+ intptr_t fd() { return fd_; }
+ ProcessInfo* next() { return next_; }
+ void set_next(ProcessInfo* next) { next_ = next; }
+
+ private:
+ pid_t pid_; // Process pid.
+ intptr_t fd_; // File descriptor for pipe to report exit code.
+ ProcessInfo* next_;
+};
+
+
+ProcessInfo* active_processes = NULL;
+
+
+static void AddProcess(ProcessInfo* process) {
+ process->set_next(active_processes);
+ active_processes = process;
+}
+
- bool operator==(const ActiveProcess &other) const {
- if (pid == other.pid) {
- return true;
+static ProcessInfo* LookupProcess(pid_t pid) {
+ ProcessInfo* current = active_processes;
+ while (current != NULL) {
+ if (current->pid() == pid) {
+ return current;
}
- return false;
+ current = current->next();
}
-};
+ return NULL;
+}
-static Set<ActiveProcess> activeProcesses;
+static ProcessInfo* RemoveProcess(pid_t pid) {
+ ProcessInfo* prev = NULL;
+ ProcessInfo* current = active_processes;
+ while (current != NULL) {
+ if (current->pid() == pid) {
+ if (prev == NULL) {
+ active_processes = current->next();
+ } else {
+ prev->set_next(current->next());
+ }
+ return current;
+ }
+ prev = current;
+ current = current->next();
+ }
+ return NULL;
+}
static char* SafeStrNCpy(char* dest, const char* src, size_t n) {
@@ -45,8 +84,8 @@ static void SetChildOsErrorMessage(char* os_error_message,
}
-void ExitHandle(int processSignal, siginfo_t* siginfo, void* tmp) {
- assert(processSignal == SIGCHLD);
+void ExitHandler(int process_signal, siginfo_t* siginfo, void* tmp) {
+ assert(process_signal == SIGCHLD);
struct sigaction act;
bzero(&act, sizeof(act));
act.sa_handler = SIG_IGN;
@@ -54,23 +93,18 @@ void ExitHandle(int processSignal, siginfo_t* siginfo, void* tmp) {
if (sigaction(SIGCHLD, &act, 0) != 0) {
perror("Process start: disabling signal handler failed");
}
- pid_t pid = siginfo->si_pid;
- ActiveProcess element;
- element.pid = pid;
- ActiveProcess* current = activeProcesses.Remove(element);
- if (current != NULL) {
- intptr_t message = siginfo->si_status;
+ ProcessInfo* process = LookupProcess(siginfo->si_pid);
+ if (process != NULL) {
+ intptr_t message[2] = { siginfo->si_pid, siginfo->si_status };
intptr_t result =
- FDUtils::WriteToBlocking(current->fd, &message, sizeof(message));
+ FDUtils::WriteToBlocking(process->fd(), &message, sizeof(message));
if (result != sizeof(message)) {
- perror("ExitHandle notification failed");
+ perror("ExitHandler notification failed");
}
- close(current->fd);
-
- delete current;
+ close(process->fd());
}
act.sa_handler = 0;
- act.sa_sigaction = ExitHandle;
+ act.sa_sigaction = ExitHandler;
if (sigaction(SIGCHLD, &act, 0) != 0) {
perror("Process start: enabling signal handler failed");
}
@@ -160,7 +194,7 @@ int Process::Start(const char* path,
struct sigaction act;
bzero(&act, sizeof(act));
- act.sa_sigaction = ExitHandle;
+ act.sa_sigaction = ExitHandler;
act.sa_flags = SA_NOCLDSTOP | SA_SIGINFO;
if (sigaction(SIGCHLD, &act, 0) != 0) {
perror("Process start: setting signal handler failed");
@@ -231,10 +265,8 @@ int Process::Start(const char* path,
return errno;
}
- ActiveProcess* activeProcess = new ActiveProcess();
- activeProcess->pid = pid;
- activeProcess->fd = event_fds[1];
- activeProcesses.Add(*activeProcess);
+ ProcessInfo* process = new ProcessInfo(pid, event_fds[1]);
+ AddProcess(process);
*exit_event = event_fds[0];
FDUtils::SetNonBlocking(event_fds[0]);
@@ -300,3 +332,8 @@ bool Process::Kill(intptr_t id) {
}
return true;
}
+
+
+void Process::Exit(intptr_t id) {
+ RemoveProcess(id);
+}
« no previous file with comments | « runtime/bin/process_linux.cc ('k') | runtime/tests/dart/dart.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698