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 |