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

Side by Side 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 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 "platform/globals.h" 5 #include "platform/globals.h"
6 #if defined(TARGET_OS_LINUX) 6 #if defined(TARGET_OS_LINUX)
7 7
8 #include "bin/process.h" 8 #include "bin/process.h"
9 9
10 #include <errno.h> // NOLINT 10 #include <errno.h> // NOLINT
11 #include <fcntl.h> // NOLINT 11 #include <fcntl.h> // NOLINT
12 #include <poll.h> // NOLINT 12 #include <poll.h> // NOLINT
13 #include <stdio.h> // NOLINT 13 #include <stdio.h> // NOLINT
14 #include <stdlib.h> // NOLINT 14 #include <stdlib.h> // NOLINT
15 #include <string.h> // NOLINT 15 #include <string.h> // NOLINT
16 #include <sys/wait.h> // NOLINT 16 #include <sys/wait.h> // NOLINT
17 #include <unistd.h> // NOLINT 17 #include <unistd.h> // NOLINT
18 18
19 #include "bin/fdutils.h" 19 #include "bin/fdutils.h"
20 #include "bin/log.h" 20 #include "bin/log.h"
21 #include "bin/signal_blocker.h"
21 #include "bin/thread.h" 22 #include "bin/thread.h"
22 23
23 24
24 extern char **environ; 25 extern char **environ;
25 26
26 27
27 namespace dart { 28 namespace dart {
28 namespace bin { 29 namespace bin {
29 30
30 // ProcessInfo is used to map a process id to the file descriptor for 31 // ProcessInfo is used to map a process id to the file descriptor for
(...skipping 592 matching lines...) Expand 10 before | Expand all | Expand 10 after
623 624
624 void Process::TerminateExitCodeHandler() { 625 void Process::TerminateExitCodeHandler() {
625 ExitCodeHandler::TerminateExitCodeThread(); 626 ExitCodeHandler::TerminateExitCodeThread();
626 } 627 }
627 628
628 629
629 intptr_t Process::CurrentProcessId() { 630 intptr_t Process::CurrentProcessId() {
630 return static_cast<intptr_t>(getpid()); 631 return static_cast<intptr_t>(getpid());
631 } 632 }
632 633
634
635 static Mutex* signal_mutex = new Mutex();
636 static const int kSignalsCount = 3;
637 static const int kSignals[kSignalsCount] = {
638 SIGINT,
639 SIGWINCH,
640 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.
641 };
642
643
644 class SignalInfo {
645 public:
646 SignalInfo(int fd, SignalInfo* prev = NULL)
647 : fd_(fd), port_(Dart_GetMainPortId()), next_(NULL), prev_(prev) {
648 if (prev_ != NULL) {
649 prev_->next_ = this;
650 }
651 }
652
653 void Unlink() {
654 if (prev_ != NULL) {
655 prev_->next_ = next_;
656 }
657 if (next_ != NULL) {
658 next_->prev_ = prev_;
659 }
660 }
661
662 int fd() const { return fd_; }
663 Dart_Port port() const { return port_; }
664 SignalInfo* next() const { return next_; }
665
666 private:
667 int fd_;
668 Dart_Port port_;
669 SignalInfo* next_;
670 SignalInfo* prev_;
671 };
672
673
674 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.
675
676
677 static void SignalHandler(int signal) {
678 MutexLocker lock(signal_mutex);
679 const SignalInfo* handler = signal_handlers[signal];
680 while (handler != NULL) {
681 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.
682 VOID_TEMP_FAILURE_RETRY(write(handler->fd(), &value, 1));
683 handler = handler->next();
684 }
685 }
686
687
688 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.
689 int fds[2];
690 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS(pipe(fds)) != 0) {
691 return -1;
692 }
693 if (!FDUtils::SetNonBlocking(fds[0])) {
694 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fds[0]));
695 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fds[1]));
696 return -1;
697 }
698 ThreadSignalBlocker blocker(kSignalsCount, kSignals);
699 MutexLocker lock(signal_mutex);
700 if (signal_handlers[signal] == NULL) {
701 struct sigaction act;
702 bzero(&act, sizeof(act));
703 act.sa_handler = SignalHandler;
704 int status = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(
705 sigaction(signal, &act, NULL));
706 if (status < 0) {
707 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fds[0]));
708 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fds[1]));
709 return -1;
710 }
711 SignalInfo* info = new SignalInfo(fds[1]);
712 signal_handlers[signal] = info;
713 } else {
714 new SignalInfo(fds[1], signal_handlers[signal]);
715 }
716 return fds[0];
717 }
718
719
720 void Process::ClearSignalHandler(intptr_t signal) {
721 ThreadSignalBlocker blocker(kSignalsCount, kSignals);
722 MutexLocker lock(signal_mutex);
723 SignalInfo * handler = signal_handlers[signal];
724 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
725 if (handler->port() == Dart_GetMainPortId()) {
726 handler->Unlink();
727 break;
728 }
729 }
730 if (handler != NULL) {
731 if (signal_handlers[signal] == handler) {
732 signal_handlers[signal] = handler->next();
733 }
734 if (signal_handlers[signal] == NULL) {
735 struct sigaction act;
736 bzero(&act, sizeof(act));
737 act.sa_handler = SIG_DFL;
738 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(sigaction(signal, &act, NULL));
739 }
740 }
741 delete handler;
742 }
743
633 } // namespace bin 744 } // namespace bin
634 } // namespace dart 745 } // namespace dart
635 746
636 #endif // defined(TARGET_OS_LINUX) 747 #endif // defined(TARGET_OS_LINUX)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698