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

Side by Side Diff: runtime/bin/process_win.cc

Issue 119093007: Signal handling, take 2. (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
« no previous file with comments | « runtime/bin/process_patch.dart ('k') | runtime/bin/signal_blocker.h » ('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_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 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 delete_proc_thread_attr_list = reinterpret_cast<DeleteProcThreadAttrListFn>( 344 delete_proc_thread_attr_list = reinterpret_cast<DeleteProcThreadAttrListFn>(
344 reinterpret_cast<DeleteProcThreadAttrListFn>( 345 reinterpret_cast<DeleteProcThreadAttrListFn>(
345 GetProcAddress(kernel32_module, "DeleteProcThreadAttributeList"))); 346 GetProcAddress(kernel32_module, "DeleteProcThreadAttributeList")));
346 load_attempted = true; 347 load_attempted = true;
347 return delete_proc_thread_attr_list != NULL; 348 return delete_proc_thread_attr_list != NULL;
348 } 349 }
349 return delete_proc_thread_attr_list != NULL; 350 return delete_proc_thread_attr_list != NULL;
350 } 351 }
351 352
352 353
354 const int kMaxPipeNameSize = 80;
355 template<int Count>
356 static int GenerateNames(wchar_t pipe_names[Count][kMaxPipeNameSize]) {
357 UUID uuid;
358 RPC_STATUS status = UuidCreateSequential(&uuid);
359 if (status != RPC_S_OK && status != RPC_S_UUID_LOCAL_ONLY) {
360 return status;
361 }
362 RPC_WSTR uuid_string;
363 status = UuidToStringW(&uuid, &uuid_string);
364 if (status != RPC_S_OK) {
365 return status;
366 }
367 for (int i = 0; i < Count; i++) {
368 static const wchar_t* prefix = L"\\\\.\\Pipe\\dart";
369 _snwprintf(pipe_names[i],
370 kMaxPipeNameSize,
371 L"%s_%s_%d", prefix, uuid_string, i + 1);
372 }
373 status = RpcStringFreeW(&uuid_string);
374 if (status != RPC_S_OK) {
375 return status;
376 }
377 return 0;
378 }
379
380
353 int Process::Start(const char* path, 381 int Process::Start(const char* path,
354 char* arguments[], 382 char* arguments[],
355 intptr_t arguments_length, 383 intptr_t arguments_length,
356 const char* working_directory, 384 const char* working_directory,
357 char* environment[], 385 char* environment[],
358 intptr_t environment_length, 386 intptr_t environment_length,
359 intptr_t* in, 387 intptr_t* in,
360 intptr_t* out, 388 intptr_t* out,
361 intptr_t* err, 389 intptr_t* err,
362 intptr_t* id, 390 intptr_t* id,
363 intptr_t* exit_handler, 391 intptr_t* exit_handler,
364 char** os_error_message) { 392 char** os_error_message) {
365 HANDLE stdin_handles[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE }; 393 HANDLE stdin_handles[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE };
366 HANDLE stdout_handles[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE }; 394 HANDLE stdout_handles[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE };
367 HANDLE stderr_handles[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE }; 395 HANDLE stderr_handles[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE };
368 HANDLE exit_handles[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE }; 396 HANDLE exit_handles[2] = { INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE };
369 397
370 // Generate unique pipe names for the four named pipes needed. 398 // Generate unique pipe names for the four named pipes needed.
371 static const int kMaxPipeNameSize = 80;
372 wchar_t pipe_names[4][kMaxPipeNameSize]; 399 wchar_t pipe_names[4][kMaxPipeNameSize];
373 UUID uuid; 400 int status = GenerateNames<4>(pipe_names);
374 RPC_STATUS status = UuidCreateSequential(&uuid); 401 if (status != 0) {
375 if (status != RPC_S_OK && status != RPC_S_UUID_LOCAL_ONLY) {
376 SetOsErrorMessage(os_error_message); 402 SetOsErrorMessage(os_error_message);
377 Log::PrintErr("UuidCreateSequential failed %d\n", status); 403 Log::PrintErr("UuidCreateSequential failed %d\n", status);
378 return status; 404 return status;
379 } 405 }
380 RPC_WSTR uuid_string;
381 status = UuidToStringW(&uuid, &uuid_string);
382 if (status != RPC_S_OK) {
383 SetOsErrorMessage(os_error_message);
384 Log::PrintErr("UuidToString failed %d\n", status);
385 return status;
386 }
387 for (int i = 0; i < 4; i++) {
388 static const wchar_t* prefix = L"\\\\.\\Pipe\\dart";
389 _snwprintf(pipe_names[i],
390 kMaxPipeNameSize,
391 L"%s_%s_%d", prefix, uuid_string, i + 1);
392 }
393 status = RpcStringFreeW(&uuid_string);
394 if (status != RPC_S_OK) {
395 SetOsErrorMessage(os_error_message);
396 Log::PrintErr("RpcStringFree failed %d\n", status);
397 return status;
398 }
399 406
400 if (!CreateProcessPipe(stdin_handles, pipe_names[0], kInheritRead)) { 407 if (!CreateProcessPipe(stdin_handles, pipe_names[0], kInheritRead)) {
401 int error_code = SetOsErrorMessage(os_error_message); 408 int error_code = SetOsErrorMessage(os_error_message);
402 CloseProcessPipes( 409 CloseProcessPipes(
403 stdin_handles, stdout_handles, stderr_handles, exit_handles); 410 stdin_handles, stdout_handles, stderr_handles, exit_handles);
404 return error_code; 411 return error_code;
405 } 412 }
406 if (!CreateProcessPipe(stdout_handles, pipe_names[1], kInheritWrite)) { 413 if (!CreateProcessPipe(stdout_handles, pipe_names[1], kInheritWrite)) {
407 int error_code = SetOsErrorMessage(os_error_message); 414 int error_code = SetOsErrorMessage(os_error_message);
408 CloseProcessPipes( 415 CloseProcessPipes(
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after
842 849
843 void Process::TerminateExitCodeHandler() { 850 void Process::TerminateExitCodeHandler() {
844 // Nothing needs to be done on Windows. 851 // Nothing needs to be done on Windows.
845 } 852 }
846 853
847 854
848 intptr_t Process::CurrentProcessId() { 855 intptr_t Process::CurrentProcessId() {
849 return static_cast<intptr_t>(GetCurrentProcessId()); 856 return static_cast<intptr_t>(GetCurrentProcessId());
850 } 857 }
851 858
859
860 static SignalInfo* signal_handlers = NULL;
861 static Mutex* signal_mutex = new Mutex();
862
863
864 SignalInfo::~SignalInfo() {
865 reinterpret_cast<FileHandle*>(fd_)->Close();
866 }
867
868
869 BOOL WINAPI SignalHandler(DWORD signal) {
870 MutexLocker lock(signal_mutex);
871 const SignalInfo* handler = signal_handlers;
872 bool handled = false;
873 while (handler != NULL) {
874 if (handler->signal() == signal) {
875 int value = 0;
876 Socket::Write(handler->fd(), &value, 1);
877 handled = true;
878 }
879 handler = handler->next();
880 }
881 return handled;
882 }
883
884
885 intptr_t GetWinSignal(intptr_t signal) {
886 switch (signal) {
887 case kSighup: return CTRL_CLOSE_EVENT;
888 case kSigint: return CTRL_C_EVENT;
889 default:
890 return -1;
891 }
892 }
893
894
895 intptr_t Process::SetSignalHandler(intptr_t signal) {
896 signal = GetWinSignal(signal);
897 if (signal == -1) return -1;
898
899 // Generate a unique pipe name for the named pipe.
900 wchar_t pipe_name[kMaxPipeNameSize];
901 int status = GenerateNames<1>(&pipe_name);
902 if (status != 0) return status;
903
904 HANDLE fds[2];
905 if (!CreateProcessPipe(fds, pipe_name, kInheritNone)) {
906 int error_code = GetLastError();
907 CloseProcessPipe(fds);
908 SetLastError(error_code);
909 return -1;
910 }
911 MutexLocker lock(signal_mutex);
912 FileHandle* write_handle = new FileHandle(fds[kWriteHandle]);
913 write_handle->EnsureInitialized(EventHandler::delegate());
914 intptr_t write_fd = reinterpret_cast<intptr_t>(write_handle);
915 if (signal_handlers == NULL) {
916 if (SetConsoleCtrlHandler(SignalHandler, true) == 0) {
917 int error_code = GetLastError();
918 delete write_handle;
919 CloseProcessPipe(fds);
920 SetLastError(error_code);
921 return -1;
922 }
923 signal_handlers = new SignalInfo(write_fd, signal);
924 } else {
925 new SignalInfo(write_fd, signal, signal_handlers);
926 }
927 return reinterpret_cast<intptr_t>(new FileHandle(fds[kReadHandle]));
928 }
929
930
931 void Process::ClearSignalHandler(intptr_t signal) {
932 signal = GetWinSignal(signal);
933 if (signal == -1) return;
934 MutexLocker lock(signal_mutex);
935 SignalInfo* handler = signal_handlers;
936 while (handler != NULL) {
937 if (handler->port() == Dart_GetMainPortId() &&
938 handler->signal() == signal) {
939 handler->Unlink();
940 break;
941 }
942 handler = handler->next();
943 }
944 if (handler != NULL) {
945 if (signal_handlers == handler) {
946 signal_handlers = handler->next();
947 }
948 if (signal_handlers == NULL) {
949 USE(SetConsoleCtrlHandler(SignalHandler, false));
950 }
951 }
952 delete handler;
953 }
954
852 } // namespace bin 955 } // namespace bin
853 } // namespace dart 956 } // namespace dart
854 957
855 #endif // defined(TARGET_OS_WINDOWS) 958 #endif // defined(TARGET_OS_WINDOWS)
OLDNEW
« no previous file with comments | « runtime/bin/process_patch.dart ('k') | runtime/bin/signal_blocker.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698