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

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

Powered by Google App Engine
This is Rietveld 408576698