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

Side by Side Diff: runtime/bin/process_linux.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: Addressed comment. Added updated test binaries. 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.h ('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>
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 initialized_ = true; 129 initialized_ = true;
130 return true; 130 return true;
131 } 131 }
132 132
133 // Get the write end of the pipe. 133 // Get the write end of the pipe.
134 static int WakeUpFd() { 134 static int WakeUpFd() {
135 ASSERT(initialized_); 135 ASSERT(initialized_);
136 return sig_chld_fds_[1]; 136 return sig_chld_fds_[1];
137 } 137 }
138 138
139 static void TerminateExitCodeThread() {
140 MutexLocker locker(&mutex_);
141 if (!initialized_) {
142 return;
143 }
144
145 uint8_t data = kThreadTerminateByte;
146 ssize_t result =
147 TEMP_FAILURE_RETRY(write(ExitCodeHandler::WakeUpFd(), &data, 1));
148 if (result < 1) {
149 perror("Failed to write to wake-up fd to terminate exit code thread");
150 }
151
152 {
153 MonitorLocker terminate_locker(&thread_terminate_monitor_);
154 while (!thread_terminated_) {
155 terminate_locker.Wait();
156 }
157 }
158 }
159
160 static void ExitCodeThreadTerminated() {
161 MonitorLocker locker(&thread_terminate_monitor_);
162 thread_terminated_ = true;
163 locker.Notify();
164 }
165
139 private: 166 private:
167 static const uint8_t kThreadTerminateByte = 1;
168
140 // GetProcessExitCodes is called on a separate thread when a SIGCHLD 169 // GetProcessExitCodes is called on a separate thread when a SIGCHLD
141 // signal is received to retrieve the exit codes and post them to 170 // signal is received to retrieve the exit codes and post them to
142 // dart. 171 // dart.
143 static void GetProcessExitCodes() { 172 static void GetProcessExitCodes() {
144 pid_t pid = 0; 173 pid_t pid = 0;
145 int status = 0; 174 int status = 0;
146 while ((pid = TEMP_FAILURE_RETRY(waitpid(-1, &status, WNOHANG))) > 0) { 175 while ((pid = TEMP_FAILURE_RETRY(waitpid(-1, &status, WNOHANG))) > 0) {
147 int exit_code = 0; 176 int exit_code = 0;
148 int negative = 0; 177 int negative = 0;
149 if (WIFEXITED(status)) { 178 if (WIFEXITED(status)) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 perror("ExitCodeHandler poll failed"); 210 perror("ExitCodeHandler poll failed");
182 } 211 }
183 } else { 212 } else {
184 // Read the byte from the wake-up fd. 213 // Read the byte from the wake-up fd.
185 ASSERT(result = 1); 214 ASSERT(result = 1);
186 intptr_t data = 0; 215 intptr_t data = 0;
187 ssize_t read_bytes = FDUtils::ReadFromBlocking(pollfds.fd, &data, 1); 216 ssize_t read_bytes = FDUtils::ReadFromBlocking(pollfds.fd, &data, 1);
188 if (read_bytes < 1) { 217 if (read_bytes < 1) {
189 perror("Failed to read from wake-up fd in exit-code handler"); 218 perror("Failed to read from wake-up fd in exit-code handler");
190 } 219 }
220 if (data == ExitCodeHandler::kThreadTerminateByte) {
221 ExitCodeThreadTerminated();
222 return;
223 }
191 // Get the exit code from all processes that have died. 224 // Get the exit code from all processes that have died.
192 GetProcessExitCodes(); 225 GetProcessExitCodes();
193 } 226 }
194 } 227 }
195 } 228 }
196 229
197 static dart::Mutex mutex_; 230 static dart::Mutex mutex_;
198 static bool initialized_; 231 static bool initialized_;
199 static int sig_chld_fds_[2]; 232 static int sig_chld_fds_[2];
233 static bool thread_terminated_;
234 static dart::Monitor thread_terminate_monitor_;
200 }; 235 };
201 236
202 237
203 dart::Mutex ExitCodeHandler::mutex_; 238 dart::Mutex ExitCodeHandler::mutex_;
204 bool ExitCodeHandler::initialized_ = false; 239 bool ExitCodeHandler::initialized_ = false;
205 int ExitCodeHandler::sig_chld_fds_[2] = { 0, 0 }; 240 int ExitCodeHandler::sig_chld_fds_[2] = { 0, 0 };
241 bool ExitCodeHandler::thread_terminated_ = false;
242 dart::Monitor ExitCodeHandler::thread_terminate_monitor_;
206 243
207 244
208 static char* SafeStrNCpy(char* dest, const char* src, size_t n) { 245 static char* SafeStrNCpy(char* dest, const char* src, size_t n) {
209 strncpy(dest, src, n); 246 strncpy(dest, src, n);
210 dest[n - 1] = '\0'; 247 dest[n - 1] = '\0';
211 return dest; 248 return dest;
212 } 249 }
213 250
214 251
215 static void SetChildOsErrorMessage(char* os_error_message, 252 static void SetChildOsErrorMessage(char* os_error_message,
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 if (result == -1) { 521 if (result == -1) {
485 return false; 522 return false;
486 } 523 }
487 return true; 524 return true;
488 } 525 }
489 526
490 527
491 void Process::Exit(intptr_t id) { 528 void Process::Exit(intptr_t id) {
492 ProcessInfoList::RemoveProcess(id); 529 ProcessInfoList::RemoveProcess(id);
493 } 530 }
531
532
533 void Process::TerminateExitCodeHandler() {
534 ExitCodeHandler::TerminateExitCodeThread();
535 }
OLDNEW
« no previous file with comments | « runtime/bin/process.h ('k') | runtime/bin/process_macos.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698