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

Unified Diff: runtime/bin/process_linux.cc

Issue 108003009: Signal handling. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: 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
Index: runtime/bin/process_linux.cc
diff --git a/runtime/bin/process_linux.cc b/runtime/bin/process_linux.cc
index 95d11cdce7dc2b8ee6a2aaf0ce1bcf12900d69de..02546987011b491e9329b9af650741706957146a 100644
--- a/runtime/bin/process_linux.cc
+++ b/runtime/bin/process_linux.cc
@@ -18,6 +18,7 @@
#include "bin/fdutils.h"
#include "bin/log.h"
+#include "bin/signal_blocker.h"
#include "bin/thread.h"
@@ -630,6 +631,116 @@ intptr_t Process::CurrentProcessId() {
return static_cast<intptr_t>(getpid());
}
+
+static Mutex* signal_mutex = new Mutex();
+static const int kSignalsCount = 3;
+static const int kSignals[kSignalsCount] = {
+ SIGINT,
+ SIGWINCH,
+ SIGTERM
Søren Gjesse 2013/12/18 08:07:14 Shouldn't the SIGUSR1 and SIGUSR2 be in this list
Anders Johnsen 2013/12/18 21:20:29 Done.
+};
+
+
+class SignalInfo {
+ public:
+ SignalInfo(int fd, SignalInfo* prev = NULL)
+ : fd_(fd), port_(Dart_GetMainPortId()), next_(NULL), prev_(prev) {
+ if (prev_ != NULL) {
+ prev_->next_ = this;
+ }
+ }
+
+ void Unlink() {
+ if (prev_ != NULL) {
+ prev_->next_ = next_;
+ }
+ if (next_ != NULL) {
+ next_->prev_ = prev_;
+ }
+ }
+
+ int fd() const { return fd_; }
+ Dart_Port port() const { return port_; }
+ SignalInfo* next() const { return next_; }
+
+ private:
+ int fd_;
+ Dart_Port port_;
+ SignalInfo* next_;
+ SignalInfo* prev_;
+};
+
+
+static SignalInfo* signal_handlers[32] = { NULL };
Søren Gjesse 2013/12/18 08:07:14 Wouldn't it be OK to have the signal in the Signal
Anders Johnsen 2013/12/18 21:20:29 Done.
+
+
+static void SignalHandler(int signal) {
+ MutexLocker lock(signal_mutex);
+ const SignalInfo* handler = signal_handlers[signal];
+ while (handler != NULL) {
+ int value = 0;
Søren Gjesse 2013/12/18 08:07:14 Can we loose a signal here if the non-blocking wri
Anders Johnsen 2013/12/18 21:20:29 This write is blocking.
+ VOID_TEMP_FAILURE_RETRY(write(handler->fd(), &value, 1));
+ handler = handler->next();
+ }
+}
+
+
+intptr_t Process::SetSignalHandler(intptr_t signal) {
Søren Gjesse 2013/12/18 08:07:14 Check that the signal is actually in the kSignals
Anders Johnsen 2013/12/18 21:20:29 Done.
+ 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);
+ if (signal_handlers[signal] == NULL) {
+ 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;
+ }
+ SignalInfo* info = new SignalInfo(fds[1]);
+ signal_handlers[signal] = info;
+ } else {
+ new SignalInfo(fds[1], signal_handlers[signal]);
+ }
+ return fds[0];
+}
+
+
+void Process::ClearSignalHandler(intptr_t signal) {
+ ThreadSignalBlocker blocker(kSignalsCount, kSignals);
+ MutexLocker lock(signal_mutex);
+ SignalInfo * handler = signal_handlers[signal];
+ while (handler != NULL) {
Søren Gjesse 2013/12/18 08:07:14 Why this loop? Seems that port is always equals to
Anders Johnsen 2013/12/18 21:20:29 This is a way to map it to different isolates. We
+ if (handler->port() == Dart_GetMainPortId()) {
+ handler->Unlink();
+ break;
+ }
+ }
+ if (handler != NULL) {
+ if (signal_handlers[signal] == handler) {
+ signal_handlers[signal] = handler->next();
+ }
+ if (signal_handlers[signal] == NULL) {
+ struct sigaction act;
+ bzero(&act, sizeof(act));
+ act.sa_handler = SIG_DFL;
+ VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(sigaction(signal, &act, NULL));
+ }
+ }
+ delete handler;
+}
+
} // namespace bin
} // namespace dart

Powered by Google App Engine
This is Rietveld 408576698