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

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: 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/bin/process_android.cc ('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 "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 SignalInfo* signal_handlers = NULL;
637 static const int kSignalsCount = 5;
638 static const int kSignals[kSignalsCount] = {
639 SIGINT,
640 SIGWINCH,
641 SIGTERM,
642 SIGUSR1,
643 SIGUSR2
644 };
645
646
647 SignalInfo::~SignalInfo() {
648 VOID_TEMP_FAILURE_RETRY(close(fd_));
649 }
650
651
652 static void SignalHandler(int signal) {
653 MutexLocker lock(signal_mutex);
654 const SignalInfo* handler = signal_handlers;
655 while (handler != NULL) {
656 if (handler->signal() == signal) {
657 int value = 0;
658 VOID_TEMP_FAILURE_RETRY(write(handler->fd(), &value, 1));
659 }
660 handler = handler->next();
661 }
662 }
663
664
665 intptr_t Process::SetSignalHandler(intptr_t signal) {
666 bool found = false;
667 for (int i = 0; i < kSignalsCount; i++) {
668 if (kSignals[i] == signal) {
669 found = true;
670 break;
671 }
672 }
673 if (!found) return -1;
674 int fds[2];
675 if (TEMP_FAILURE_RETRY_BLOCK_SIGNALS(pipe(fds)) != 0) {
676 return -1;
677 }
678 if (!FDUtils::SetNonBlocking(fds[0])) {
679 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fds[0]));
680 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fds[1]));
681 return -1;
682 }
683 ThreadSignalBlocker blocker(kSignalsCount, kSignals);
684 MutexLocker lock(signal_mutex);
685 SignalInfo* handler = signal_handlers;
686 bool listen = true;
687 while (handler != NULL) {
688 if (handler->signal() == signal) {
689 listen = false;
690 break;
691 }
692 handler = handler->next();
693 }
694 if (listen) {
695 struct sigaction act;
696 bzero(&act, sizeof(act));
697 act.sa_handler = SignalHandler;
698 int status = TEMP_FAILURE_RETRY_BLOCK_SIGNALS(
699 sigaction(signal, &act, NULL));
700 if (status < 0) {
701 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fds[0]));
702 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(close(fds[1]));
703 return -1;
704 }
705 }
706 if (signal_handlers == NULL) {
707 signal_handlers = new SignalInfo(fds[1], signal);
708 } else {
709 new SignalInfo(fds[1], signal, signal_handlers);
710 }
711 return fds[0];
712 }
713
714
715 void Process::ClearSignalHandler(intptr_t signal) {
716 ThreadSignalBlocker blocker(kSignalsCount, kSignals);
717 MutexLocker lock(signal_mutex);
718 SignalInfo* handler = signal_handlers;
719 bool unlisten = true;
720 while (handler != NULL) {
721 bool remove = false;
722 if (handler->signal() == signal) {
723 if (handler->port() == Dart_GetMainPortId()) {
724 if (signal_handlers == handler) signal_handlers = handler->next();
725 handler->Unlink();
726 remove = true;
727 } else {
728 unlisten = false;
729 }
730 }
731 SignalInfo* next = handler->next();
732 if (remove) delete handler;
733 handler = next;
734 }
735 if (unlisten) {
736 struct sigaction act;
737 bzero(&act, sizeof(act));
738 act.sa_handler = SIG_DFL;
739 VOID_TEMP_FAILURE_RETRY_BLOCK_SIGNALS(sigaction(signal, &act, NULL));
740 }
741 }
742
633 } // namespace bin 743 } // namespace bin
634 } // namespace dart 744 } // namespace dart
635 745
636 #endif // defined(TARGET_OS_LINUX) 746 #endif // defined(TARGET_OS_LINUX)
OLDNEW
« no previous file with comments | « runtime/bin/process_android.cc ('k') | runtime/bin/process_macos.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698