Chromium Code Reviews| OLD | NEW |
|---|---|
| 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_WINDOWS) | 6 #if defined(TARGET_OS_WINDOWS) |
| 7 | 7 |
| 8 #include <process.h> // NOLINT | 8 #include <process.h> // NOLINT |
| 9 | 9 |
| 10 #include "bin/builtin.h" | 10 #include "bin/builtin.h" |
| 11 #include "bin/process.h" | 11 #include "bin/process.h" |
| 12 #include "bin/eventhandler.h" | 12 #include "bin/eventhandler.h" |
| 13 #include "bin/log.h" | 13 #include "bin/log.h" |
| 14 #include "bin/socket.h" | |
| 14 #include "bin/thread.h" | 15 #include "bin/thread.h" |
| 15 #include "bin/utils.h" | 16 #include "bin/utils.h" |
| 16 #include "bin/utils_win.h" | 17 #include "bin/utils_win.h" |
| 17 | 18 |
| 18 | 19 |
| 19 namespace dart { | 20 namespace dart { |
| 20 namespace bin { | 21 namespace bin { |
| 21 | 22 |
| 22 static const int kReadHandle = 0; | 23 static const int kReadHandle = 0; |
| 23 static const int kWriteHandle = 1; | 24 static const int kWriteHandle = 1; |
| (...skipping 818 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 842 | 843 |
| 843 void Process::TerminateExitCodeHandler() { | 844 void Process::TerminateExitCodeHandler() { |
| 844 // Nothing needs to be done on Windows. | 845 // Nothing needs to be done on Windows. |
| 845 } | 846 } |
| 846 | 847 |
| 847 | 848 |
| 848 intptr_t Process::CurrentProcessId() { | 849 intptr_t Process::CurrentProcessId() { |
| 849 return static_cast<intptr_t>(GetCurrentProcessId()); | 850 return static_cast<intptr_t>(GetCurrentProcessId()); |
| 850 } | 851 } |
| 851 | 852 |
| 853 | |
| 854 class SignalInfo { | |
| 855 public: | |
| 856 SignalInfo(intptr_t fd, int signal, SignalInfo* prev = NULL) | |
| 857 : fd_(fd), | |
| 858 signal_(signal), | |
| 859 port_(Dart_GetMainPortId()), | |
| 860 next_(NULL), | |
| 861 prev_(prev) { | |
| 862 if (prev_ != NULL) { | |
| 863 prev_->next_ = this; | |
| 864 } | |
| 865 } | |
| 866 | |
| 867 ~SignalInfo() { | |
| 868 reinterpret_cast<FileHandle*>(fd_)->Close(); | |
| 869 } | |
| 870 | |
| 871 void Unlink() { | |
| 872 if (prev_ != NULL) { | |
| 873 prev_->next_ = next_; | |
| 874 } | |
| 875 if (next_ != NULL) { | |
| 876 next_->prev_ = prev_; | |
| 877 } | |
| 878 } | |
| 879 | |
| 880 intptr_t fd() const { return fd_; } | |
| 881 int signal() const { return signal_; } | |
| 882 Dart_Port port() const { return port_; } | |
| 883 SignalInfo* next() const { return next_; } | |
| 884 | |
| 885 private: | |
| 886 intptr_t fd_; | |
| 887 int signal_; | |
| 888 Dart_Port port_; | |
| 889 SignalInfo* next_; | |
| 890 SignalInfo* prev_; | |
| 891 }; | |
| 892 | |
| 893 | |
| 894 static SignalInfo* signal_handlers = NULL; | |
| 895 static Mutex* signal_mutex = new Mutex(); | |
| 896 | |
| 897 | |
| 898 BOOL WINAPI SignalHandler(DWORD signal) { | |
| 899 MutexLocker lock(signal_mutex); | |
| 900 const SignalInfo* handler = signal_handlers; | |
| 901 bool handled = false; | |
| 902 while (handler != NULL) { | |
| 903 if (handler->signal() == signal) { | |
| 904 int value = 0; | |
| 905 Socket::Write(handler->fd(), &value, 1); | |
| 906 handled = true; | |
| 907 } | |
| 908 handler = handler->next(); | |
| 909 } | |
| 910 return handled; | |
| 911 } | |
| 912 | |
| 913 | |
| 914 intptr_t GetWinSignal(intptr_t signal) { | |
| 915 switch (signal) { | |
| 916 case 1: // SIGHUP | |
| 917 return CTRL_CLOSE_EVENT; | |
| 918 case 2: // SIGINT | |
| 919 return CTRL_C_EVENT; | |
| 920 default: | |
| 921 return -1; | |
| 922 } | |
| 923 } | |
| 924 | |
| 925 | |
| 926 intptr_t Process::SetSignalHandler(intptr_t signal) { | |
| 927 signal = GetWinSignal(signal); | |
| 928 if (signal == -1) return -1; | |
|
Søren Gjesse
2013/12/18 08:07:14
Throw here?
Dart_ThrowException(DartUtils::NewDar
Anders Johnsen
2013/12/18 21:20:29
Returning -1 will throw as well (in process.cc). W
| |
| 929 // Generate a unique pipe name for the named pipe. | |
|
Søren Gjesse
2013/12/18 08:07:14
Please factor out this named pipe name generation
Anders Johnsen
2013/12/18 21:20:29
Done.
| |
| 930 static const int kMaxPipeNameSize = 80; | |
| 931 wchar_t pipe_name[kMaxPipeNameSize]; | |
| 932 UUID uuid; | |
| 933 RPC_STATUS status = UuidCreateSequential(&uuid); | |
| 934 if (status != RPC_S_OK && status != RPC_S_UUID_LOCAL_ONLY) { | |
| 935 int error_code = GetLastError(); | |
| 936 Log::PrintErr("UuidCreateSequential failed %d\n", status); | |
| 937 SetLastError(error_code); | |
| 938 return -1; | |
| 939 } | |
| 940 RPC_WSTR uuid_string; | |
| 941 status = UuidToStringW(&uuid, &uuid_string); | |
| 942 if (status != RPC_S_OK) { | |
| 943 int error_code = GetLastError(); | |
| 944 Log::PrintErr("UuidToString failed %d\n", status); | |
| 945 SetLastError(error_code); | |
| 946 return -1; | |
| 947 } | |
| 948 static const wchar_t* prefix = L"\\\\.\\Pipe\\dart"; | |
| 949 _snwprintf(pipe_name, | |
| 950 kMaxPipeNameSize, | |
| 951 L"%s_%s", prefix, uuid_string); | |
| 952 status = RpcStringFreeW(&uuid_string); | |
| 953 if (status != RPC_S_OK) { | |
| 954 int error_code = GetLastError(); | |
| 955 Log::PrintErr("RpcStringFree failed %d\n", status); | |
| 956 SetLastError(error_code); | |
| 957 return -1; | |
| 958 } | |
| 959 HANDLE fds[2]; | |
| 960 if (!CreateProcessPipe(fds, pipe_name, kInheritNone)) { | |
| 961 int error_code = GetLastError(); | |
| 962 CloseProcessPipe(fds); | |
| 963 SetLastError(error_code); | |
| 964 return -1; | |
| 965 } | |
| 966 MutexLocker lock(signal_mutex); | |
| 967 FileHandle* write_handle = new FileHandle(fds[kWriteHandle]); | |
| 968 write_handle->EnsureInitialized(EventHandler::delegate()); | |
| 969 intptr_t write_fd = reinterpret_cast<intptr_t>(write_handle); | |
| 970 if (signal_handlers == NULL) { | |
| 971 if (SetConsoleCtrlHandler(SignalHandler, true) == 0) { | |
| 972 int error_code = GetLastError(); | |
| 973 delete write_handle; | |
| 974 CloseProcessPipe(fds); | |
| 975 SetLastError(error_code); | |
| 976 return -1; | |
| 977 } | |
| 978 signal_handlers = new SignalInfo(write_fd, signal); | |
| 979 } else { | |
| 980 new SignalInfo(write_fd, signal, signal_handlers); | |
| 981 } | |
| 982 return reinterpret_cast<intptr_t>(new FileHandle(fds[kReadHandle])); | |
| 983 } | |
| 984 | |
| 985 | |
| 986 void Process::ClearSignalHandler(intptr_t signal) { | |
| 987 signal = GetWinSignal(signal); | |
| 988 if (signal == -1) return; | |
| 989 MutexLocker lock(signal_mutex); | |
| 990 SignalInfo* handler = signal_handlers; | |
| 991 while (handler != NULL) { | |
| 992 if (handler->port() == Dart_GetMainPortId() && | |
| 993 handler->signal() == signal) { | |
| 994 handler->Unlink(); | |
| 995 break; | |
| 996 } | |
| 997 handler = handler->next(); | |
| 998 } | |
| 999 if (handler != NULL) { | |
| 1000 if (signal_handlers == handler) { | |
| 1001 signal_handlers = handler->next(); | |
| 1002 } | |
| 1003 if (signal_handlers == NULL) { | |
| 1004 USE(SetConsoleCtrlHandler(SignalHandler, false)); | |
| 1005 } | |
| 1006 } | |
| 1007 delete handler; | |
| 1008 } | |
| 1009 | |
| 852 } // namespace bin | 1010 } // namespace bin |
| 853 } // namespace dart | 1011 } // namespace dart |
| 854 | 1012 |
| 855 #endif // defined(TARGET_OS_WINDOWS) | 1013 #endif // defined(TARGET_OS_WINDOWS) |
| OLD | NEW |