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

Side by Side Diff: runtime/bin/process_macos.cc

Issue 9307033: Revert "Changes to the process implementation." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 10 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/bin/process_linux.cc ('k') | runtime/bin/process_win.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "bin/process.h" 5 #include "bin/process.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <fcntl.h> 8 #include <fcntl.h>
9 #include <poll.h> 9 #include <poll.h>
10 #include <signal.h> 10 #include <signal.h>
11 #include <stdio.h> 11 #include <stdio.h>
12 #include <stdlib.h> 12 #include <stdlib.h>
13 #include <string.h> 13 #include <string.h>
14 #include <unistd.h> 14 #include <unistd.h>
15 15
16 #include "bin/fdutils.h" 16 #include "bin/fdutils.h"
17 #include "bin/thread.h" 17 #include "bin/thread.h"
18 18
19 19
20 // ProcessInfo is used to map a process id to the file descriptor for 20 // ProcessInfo is used to map a process id to the file descriptor for
21 // the pipe used to communicate the exit code of the process to Dart. 21 // the pipe used to communicate the exit code of the process to Dart.
22 // ProcessInfo objects are kept in the static singly-linked 22 // ProcessInfo objects are kept in the static singly-linked
23 // ProcessInfoList. 23 // ProcessInfoList.
24 class ProcessInfo { 24 class ProcessInfo {
25 public: 25 public:
26 ProcessInfo(pid_t pid, intptr_t fd) : pid_(pid), fd_(fd) { } 26 ProcessInfo(pid_t pid, intptr_t fd) : pid_(pid), fd_(fd) { }
27 ~ProcessInfo() {
28 int closed = TEMP_FAILURE_RETRY(close(fd_));
29 if (closed != 0) {
30 FATAL("Failed to close process exit code pipe");
31 }
32 }
33 pid_t pid() { return pid_; } 27 pid_t pid() { return pid_; }
34 intptr_t fd() { return fd_; } 28 intptr_t fd() { return fd_; }
35 ProcessInfo* next() { return next_; } 29 ProcessInfo* next() { return next_; }
36 void set_next(ProcessInfo* info) { next_ = info; } 30 void set_next(ProcessInfo* info) { next_ = info; }
37 31
38 private: 32 private:
39 pid_t pid_; 33 pid_t pid_;
40 intptr_t fd_; 34 intptr_t fd_;
41 ProcessInfo* next_; 35 ProcessInfo* next_;
42 }; 36 };
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 ProcessInfo* ProcessInfoList::active_processes_ = NULL; 93 ProcessInfo* ProcessInfoList::active_processes_ = NULL;
100 dart::Mutex ProcessInfoList::mutex_; 94 dart::Mutex ProcessInfoList::mutex_;
101 95
102 96
103 // The exit code handler sets up a separate thread which is signalled 97 // The exit code handler sets up a separate thread which is signalled
104 // on SIGCHLD. That separate thread can then get the exit code from 98 // on SIGCHLD. That separate thread can then get the exit code from
105 // processes that have exited and communicate it to Dart through the 99 // processes that have exited and communicate it to Dart through the
106 // event loop. 100 // event loop.
107 class ExitCodeHandler { 101 class ExitCodeHandler {
108 public: 102 public:
109 static const uint8_t kTerminateByte = 1;
110
111 // Ensure that the ExitCodeHandler has been initialized. 103 // Ensure that the ExitCodeHandler has been initialized.
112 static bool EnsureInitialized() { 104 static bool EnsureInitialized() {
113 // Multiple isolates could be starting processes at the same 105 // Multiple isolates could be starting processes at the same
114 // time. Make sure that only one of them initializes the 106 // time. Make sure that only one of them initializes the
115 // ExitCodeHandler. 107 // ExitCodeHandler.
116 MutexLocker locker(&mutex_); 108 MutexLocker locker(&mutex_);
117 if (initialized_) { 109 if (initialized_) {
118 return true; 110 return true;
119 } 111 }
120 112
(...skipping 15 matching lines...) Expand all
136 initialized_ = true; 128 initialized_ = true;
137 return true; 129 return true;
138 } 130 }
139 131
140 // Get the write end of the pipe. 132 // Get the write end of the pipe.
141 static int WakeUpFd() { 133 static int WakeUpFd() {
142 ASSERT(initialized_); 134 ASSERT(initialized_);
143 return sig_chld_fds_[1]; 135 return sig_chld_fds_[1];
144 } 136 }
145 137
146 static void Terminate() {
147 MutexLocker locker(&mutex_);
148 if (!initialized_) {
149 return;
150 }
151 char data = ExitCodeHandler::kTerminateByte;
152 ssize_t result = TEMP_FAILURE_RETRY(write(WakeUpFd(), &data, 1));
153 if (result < 1) {
154 perror("Failed to write to wake-up fd in SIGCHLD handler");
155 }
156 }
157
158 private: 138 private:
159 // GetProcessExitCodes is called on a separate thread when a SIGCHLD 139 // GetProcessExitCodes is called on a separate thread when a SIGCHLD
160 // signal is received to retrieve the exit codes and post them to 140 // signal is received to retrieve the exit codes and post them to
161 // dart. 141 // dart.
162 static void GetProcessExitCodes() { 142 static void GetProcessExitCodes() {
163 pid_t pid = 0; 143 pid_t pid = 0;
164 int status = 0; 144 int status = 0;
165 while ((pid = TEMP_FAILURE_RETRY(waitpid(-1, &status, WNOHANG))) > 0) { 145 while ((pid = TEMP_FAILURE_RETRY(waitpid(-1, &status, WNOHANG))) > 0) {
166 int exit_code = 0; 146 int exit_code = 0;
167 int negative = 0; 147 int negative = 0;
168 if (WIFEXITED(status)) { 148 if (WIFEXITED(status)) {
169 exit_code = WEXITSTATUS(status); 149 exit_code = WEXITSTATUS(status);
170 } 150 }
171 if (WIFSIGNALED(status)) { 151 if (WIFSIGNALED(status)) {
172 exit_code = WTERMSIG(status); 152 exit_code = WTERMSIG(status);
173 negative = 1; 153 negative = 1;
174 } 154 }
175 intptr_t exit_code_fd = ProcessInfoList::LookupProcessExitFd(pid); 155 intptr_t exit_code_fd = ProcessInfoList::LookupProcessExitFd(pid);
176 if (exit_code_fd != 0) { 156 if (exit_code_fd != 0) {
177 int message[2] = { exit_code, negative }; 157 int message[3] = { pid, exit_code, negative };
178 ssize_t result = 158 ssize_t result =
179 FDUtils::WriteToBlocking(exit_code_fd, &message, sizeof(message)); 159 FDUtils::WriteToBlocking(exit_code_fd, &message, sizeof(message));
180 if (result != sizeof(message) && errno != EPIPE) { 160 if (result != sizeof(message) && errno != EPIPE) {
181 perror("ExitHandler notification failed"); 161 perror("ExitHandler notification failed");
182 } 162 }
183 ProcessInfoList::RemoveProcess(pid); 163 TEMP_FAILURE_RETRY(close(exit_code_fd));
184 } 164 }
185 } 165 }
186 } 166 }
187 167
188 168
189 // Entry point for the separate exit code handler thread started by 169 // Entry point for the separate exit code handler thread started by
190 // the ExitCodeHandler. 170 // the ExitCodeHandler.
191 static void ExitCodeHandlerEntry(uword param) { 171 static void ExitCodeHandlerEntry(uword param) {
192 struct pollfd pollfds; 172 struct pollfd pollfds;
193 pollfds.fd = param; 173 pollfds.fd = param;
194 pollfds.events |= POLLIN; 174 pollfds.events |= POLLIN;
195 while (true) { 175 while (true) {
196 int result = TEMP_FAILURE_RETRY(poll(&pollfds, 1, -1)); 176 int result = TEMP_FAILURE_RETRY(poll(&pollfds, 1, -1));
197 if (result == -1) { 177 if (result == -1) {
198 ASSERT(EAGAIN == EWOULDBLOCK); 178 ASSERT(EAGAIN == EWOULDBLOCK);
199 if (errno != EWOULDBLOCK) { 179 if (errno != EWOULDBLOCK) {
200 perror("ExitCodeHandler poll failed"); 180 perror("ExitCodeHandler poll failed");
201 } 181 }
202 } else { 182 } else {
203 // Read the byte from the wake-up fd. 183 // Read the byte from the wake-up fd.
204 ASSERT(result = 1); 184 ASSERT(result = 1);
205 intptr_t data = 0; 185 intptr_t data = 0;
206 ssize_t read_bytes = FDUtils::ReadFromBlocking(pollfds.fd, &data, 1); 186 ssize_t read_bytes = FDUtils::ReadFromBlocking(pollfds.fd, &data, 1);
207 if (read_bytes < 1) { 187 if (read_bytes < 1) {
208 perror("Failed to read from wake-up fd in exit-code handler"); 188 perror("Failed to read from wake-up fd in exit-code handler");
209 } 189 }
210 // Check if the ExitCodeHandler has been terminated.
211 if (data == ExitCodeHandler::kTerminateByte) {
212 return;
213 }
214 // Get the exit code from all processes that have died. 190 // Get the exit code from all processes that have died.
215 GetProcessExitCodes(); 191 GetProcessExitCodes();
216 } 192 }
217 } 193 }
218 } 194 }
219 195
220 static dart::Mutex mutex_; 196 static dart::Mutex mutex_;
221 static bool initialized_; 197 static bool initialized_;
222 static int sig_chld_fds_[2]; 198 static int sig_chld_fds_[2];
223 }; 199 };
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after
504 480
505 bool Process::Kill(intptr_t id) { 481 bool Process::Kill(intptr_t id) {
506 int result = TEMP_FAILURE_RETRY(kill(id, SIGKILL)); 482 int result = TEMP_FAILURE_RETRY(kill(id, SIGKILL));
507 if (result == -1) { 483 if (result == -1) {
508 return false; 484 return false;
509 } 485 }
510 return true; 486 return true;
511 } 487 }
512 488
513 489
514 void Process::TerminateExitCodeHandler() { 490 void Process::Exit(intptr_t id) {
515 ExitCodeHandler::Terminate(); 491 ProcessInfoList::RemoveProcess(id);
516 } 492 }
OLDNEW
« no previous file with comments | « runtime/bin/process_linux.cc ('k') | runtime/bin/process_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698