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

Unified Diff: runtime/bin/process_macos.cc

Issue 108003009: Signal handling. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Nicer API and Android+Mac versions. Created 7 years 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/bin/process_patch.dart » ('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 edb222af3fb11acc7037a1f9a813ba374529ea63..6fd82a3f1d6c265b87a8538db71c99ea9684ffdf 100644
--- a/runtime/bin/process_macos.cc
+++ b/runtime/bin/process_macos.cc
@@ -18,6 +18,7 @@
#include "bin/fdutils.h"
#include "bin/log.h"
+#include "bin/signal_blocker.h"
#include "bin/thread.h"
extern char **environ;
@@ -636,6 +637,115 @@ intptr_t Process::CurrentProcessId() {
return static_cast<intptr_t>(getpid());
}
+
+static Mutex* signal_mutex = new Mutex();
+static SignalInfo* signal_handlers = NULL;
+static const int kSignalsCount = 5;
+static const int kSignals[kSignalsCount] = {
+ SIGINT,
+ SIGWINCH,
+ SIGTERM,
+ SIGUSR1,
+ SIGUSR2
+};
+
+
+SignalInfo::~SignalInfo() {
+ VOID_TEMP_FAILURE_RETRY(close(fd_));
+}
+
+
+static void SignalHandler(int signal) {
+ MutexLocker lock(signal_mutex);
+ const SignalInfo* handler = signal_handlers;
+ while (handler != NULL) {
+ if (handler->signal() == signal) {
+ int value = 0;
+ VOID_TEMP_FAILURE_RETRY(write(handler->fd(), &value, 1));
+ }
+ handler = handler->next();
+ }
+}
+
+
+intptr_t Process::SetSignalHandler(intptr_t signal) {
+ bool found = false;
+ for (int i = 0; i < kSignalsCount; i++) {
+ if (kSignals[i] == signal) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) return -1;
+ int fds[2];
+ if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS(pipe(fds)) != 0) {
+ return -1;
+ }
+ if (!FDUtils::SetNonBlocking(fds[0])) {
+ VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fds[0]));
+ VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fds[1]));
+ return -1;
+ }
+ ThreadSignalBlocker blocker(kSignalsCount, kSignals);
+ MutexLocker lock(signal_mutex);
+ SignalInfo* handler = signal_handlers;
+ bool listen = true;
+ while (handler != NULL) {
+ if (handler->signal() == signal) {
+ listen = false;
+ break;
+ }
+ handler = handler->next();
+ }
+ if (listen) {
+ struct sigaction act;
+ bzero(&act, sizeof(act));
+ act.sa_handler = SignalHandler;
+ int status = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(
+ sigaction(signal, &act, NULL));
+ if (status < 0) {
+ VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fds[0]));
+ VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fds[1]));
+ return -1;
+ }
+ }
+ if (signal_handlers == NULL) {
+ signal_handlers = new SignalInfo(fds[1], signal);
+ } else {
+ new SignalInfo(fds[1], signal, signal_handlers);
+ }
+ return fds[0];
+}
+
+
+void Process::ClearSignalHandler(intptr_t signal) {
+ ThreadSignalBlocker blocker(kSignalsCount, kSignals);
+ MutexLocker lock(signal_mutex);
+ SignalInfo* handler = signal_handlers;
+ bool unlisten = true;
+ while (handler != NULL) {
+ bool remove = false;
+ if (handler->signal() == signal) {
+ if (handler->port() == Dart_GetMainPortId()) {
+ if (signal_handlers == handler) signal_handlers = handler->next();
+ handler->Unlink();
+ remove = true;
+ } else {
+ unlisten = false;
+ }
+ }
+ SignalInfo* next = handler->next();
+ if (remove) delete handler;
+ handler = next;
+ }
+ if (unlisten) {
+ struct sigaction act;
+ bzero(&act, sizeof(act));
+ act.sa_handler = SIG_DFL;
+ VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(sigaction(signal, &act, NULL));
+ }
+}
+
} // namespace bin
} // namespace dart
« no previous file with comments | « runtime/bin/process_linux.cc ('k') | runtime/bin/process_patch.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698