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

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

Issue 9315037: Wait for exit-code thread to terminate before terminating main. (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
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>
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 ProcessInfo* ProcessInfoList::active_processes_ = NULL; 93 ProcessInfo* ProcessInfoList::active_processes_ = NULL;
94 dart::Mutex ProcessInfoList::mutex_; 94 dart::Mutex ProcessInfoList::mutex_;
95 95
96 96
97 // 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
98 // 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
99 // processes that have exited and communicate it to Dart through the 99 // processes that have exited and communicate it to Dart through the
100 // event loop. 100 // event loop.
101 class ExitCodeHandler { 101 class ExitCodeHandler {
102 public: 102 public:
103 static const uint8_t kThreadTerminateByte = 1;
104
103 // Ensure that the ExitCodeHandler has been initialized. 105 // Ensure that the ExitCodeHandler has been initialized.
104 static bool EnsureInitialized() { 106 static bool EnsureInitialized() {
105 // Multiple isolates could be starting processes at the same 107 // Multiple isolates could be starting processes at the same
106 // time. Make sure that only one of them initializes the 108 // time. Make sure that only one of them initializes the
107 // ExitCodeHandler. 109 // ExitCodeHandler.
108 MutexLocker locker(&mutex_); 110 MutexLocker locker(&mutex_);
109 if (initialized_) { 111 if (initialized_) {
110 return true; 112 return true;
111 } 113 }
112 114
(...skipping 15 matching lines...) Expand all
128 initialized_ = true; 130 initialized_ = true;
129 return true; 131 return true;
130 } 132 }
131 133
132 // Get the write end of the pipe. 134 // Get the write end of the pipe.
133 static int WakeUpFd() { 135 static int WakeUpFd() {
134 ASSERT(initialized_); 136 ASSERT(initialized_);
135 return sig_chld_fds_[1]; 137 return sig_chld_fds_[1];
136 } 138 }
137 139
140 static void TerminateExitCodeThread() {
141 MutexLocker locker(&mutex_);
142 if (!initialized_) {
143 return;
144 }
145
146 uint8_t data = kThreadTerminateByte;
147 ssize_t result =
148 TEMP_FAILURE_RETRY(write(ExitCodeHandler::WakeUpFd(), &data, 1));
149 if (result < 1) {
150 perror("Failed to write to wake-up fd to terminate exit code thread");
151 }
152
153 {
154 MonitorLocker terminate_locker(&thread_terminate_monitor_);
155 while (!thread_terminated_) {
156 terminate_locker.Wait();
157 }
158 }
159 }
160
161 static void ExitCodeThreadTerminated() {
162 MonitorLocker locker(&thread_terminate_monitor_);
163 thread_terminated_ = true;
164 locker.Notify();
165 }
166
138 private: 167 private:
139 // GetProcessExitCodes is called on a separate thread when a SIGCHLD 168 // GetProcessExitCodes is called on a separate thread when a SIGCHLD
140 // signal is received to retrieve the exit codes and post them to 169 // signal is received to retrieve the exit codes and post them to
141 // dart. 170 // dart.
142 static void GetProcessExitCodes() { 171 static void GetProcessExitCodes() {
143 pid_t pid = 0; 172 pid_t pid = 0;
144 int status = 0; 173 int status = 0;
145 while ((pid = TEMP_FAILURE_RETRY(waitpid(-1, &status, WNOHANG))) > 0) { 174 while ((pid = TEMP_FAILURE_RETRY(waitpid(-1, &status, WNOHANG))) > 0) {
146 int exit_code = 0; 175 int exit_code = 0;
147 int negative = 0; 176 int negative = 0;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 perror("ExitCodeHandler poll failed"); 209 perror("ExitCodeHandler poll failed");
181 } 210 }
182 } else { 211 } else {
183 // Read the byte from the wake-up fd. 212 // Read the byte from the wake-up fd.
184 ASSERT(result = 1); 213 ASSERT(result = 1);
185 intptr_t data = 0; 214 intptr_t data = 0;
186 ssize_t read_bytes = FDUtils::ReadFromBlocking(pollfds.fd, &data, 1); 215 ssize_t read_bytes = FDUtils::ReadFromBlocking(pollfds.fd, &data, 1);
187 if (read_bytes < 1) { 216 if (read_bytes < 1) {
188 perror("Failed to read from wake-up fd in exit-code handler"); 217 perror("Failed to read from wake-up fd in exit-code handler");
189 } 218 }
219 if (data == ExitCodeHandler::kThreadTerminateByte) {
220 ExitCodeThreadTerminated();
221 return;
222 }
190 // Get the exit code from all processes that have died. 223 // Get the exit code from all processes that have died.
191 GetProcessExitCodes(); 224 GetProcessExitCodes();
192 } 225 }
193 } 226 }
194 } 227 }
195 228
196 static dart::Mutex mutex_; 229 static dart::Mutex mutex_;
197 static bool initialized_; 230 static bool initialized_;
198 static int sig_chld_fds_[2]; 231 static int sig_chld_fds_[2];
232 static bool thread_terminated_;
233 static dart::Monitor thread_terminate_monitor_;
199 }; 234 };
200 235
201 236
202 dart::Mutex ExitCodeHandler::mutex_; 237 dart::Mutex ExitCodeHandler::mutex_;
203 bool ExitCodeHandler::initialized_ = false; 238 bool ExitCodeHandler::initialized_ = false;
204 int ExitCodeHandler::sig_chld_fds_[2] = { 0, 0 }; 239 int ExitCodeHandler::sig_chld_fds_[2] = { 0, 0 };
240 bool ExitCodeHandler::thread_terminated_ = false;
241 dart::Monitor ExitCodeHandler::thread_terminate_monitor_;
205 242
206 243
207 static char* SafeStrNCpy(char* dest, const char* src, size_t n) { 244 static char* SafeStrNCpy(char* dest, const char* src, size_t n) {
208 strncpy(dest, src, n); 245 strncpy(dest, src, n);
209 dest[n - 1] = '\0'; 246 dest[n - 1] = '\0';
210 return dest; 247 return dest;
211 } 248 }
212 249
213 250
214 static void SetChildOsErrorMessage(char* os_error_message, 251 static void SetChildOsErrorMessage(char* os_error_message,
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
483 if (result == -1) { 520 if (result == -1) {
484 return false; 521 return false;
485 } 522 }
486 return true; 523 return true;
487 } 524 }
488 525
489 526
490 void Process::Exit(intptr_t id) { 527 void Process::Exit(intptr_t id) {
491 ProcessInfoList::RemoveProcess(id); 528 ProcessInfoList::RemoveProcess(id);
492 } 529 }
530
531
532 void Process::TerminateExitCodeHandler() {
533 ExitCodeHandler::TerminateExitCodeThread();
534 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698