| Index: dart/runtime/bin/process_win.cc
|
| ===================================================================
|
| --- dart/runtime/bin/process_win.cc (revision 16310)
|
| +++ dart/runtime/bin/process_win.cc (working copy)
|
| @@ -319,6 +319,44 @@
|
| }
|
|
|
|
|
| +typedef BOOL (WINAPI *InitProcThreadAttrListFn)(
|
| + LPPROC_THREAD_ATTRIBUTE_LIST, DWORD, DWORD, PSIZE_T);
|
| +
|
| +typedef BOOL (WINAPI *UpdateProcThreadAttrFn)(
|
| + LPPROC_THREAD_ATTRIBUTE_LIST, DWORD, DWORD_PTR,
|
| + PVOID, SIZE_T, PVOID, PSIZE_T);
|
| +
|
| +typedef VOID (WINAPI *DeleteProcThreadAttrListFn)(
|
| + LPPROC_THREAD_ATTRIBUTE_LIST);
|
| +
|
| +
|
| +static InitProcThreadAttrListFn init_proc_thread_attr_list = NULL;
|
| +static UpdateProcThreadAttrFn update_proc_thread_attr = NULL;
|
| +static DeleteProcThreadAttrListFn delete_proc_thread_attr_list = NULL;
|
| +
|
| +
|
| +static bool EnsureInitialized() {
|
| + static bool load_attempted = false;
|
| + static dart::Mutex mutex;
|
| + HMODULE kernel32_module = GetModuleHandle(L"kernel32.dll");
|
| + if (!load_attempted) {
|
| + MutexLocker locker(&mutex);
|
| + if (load_attempted) return delete_proc_thread_attr_list != NULL;
|
| + init_proc_thread_attr_list = reinterpret_cast<InitProcThreadAttrListFn>(
|
| + GetProcAddress(kernel32_module, "InitializeProcThreadAttributeList"));
|
| + update_proc_thread_attr =
|
| + reinterpret_cast<UpdateProcThreadAttrFn>(
|
| + GetProcAddress(kernel32_module, "UpdateProcThreadAttribute"));
|
| + delete_proc_thread_attr_list = reinterpret_cast<DeleteProcThreadAttrListFn>(
|
| + reinterpret_cast<DeleteProcThreadAttrListFn>(
|
| + GetProcAddress(kernel32_module, "DeleteProcThreadAttributeList")));
|
| + load_attempted = true;
|
| + return delete_proc_thread_attr_list != NULL;
|
| + }
|
| + return delete_proc_thread_attr_list != NULL;
|
| +}
|
| +
|
| +
|
| int Process::Start(const char* path,
|
| char* arguments[],
|
| intptr_t arguments_length,
|
| @@ -399,48 +437,53 @@
|
| startup_info.StartupInfo.hStdError = stderr_handles[kWriteHandle];
|
| startup_info.StartupInfo.dwFlags = STARTF_USESTDHANDLES;
|
|
|
| - // Setup the handles to inherit. We only want to inherit the three handles
|
| - // for stdin, stdout and stderr.
|
| - SIZE_T size = 0;
|
| - // The call to determine the size of an attribute list always fails with
|
| - // ERROR_INSUFFICIENT_BUFFER and that error should be ignored.
|
| - if (!InitializeProcThreadAttributeList(NULL, 1, 0, &size) &&
|
| - GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
|
| - int error_code = SetOsErrorMessage(os_error_message);
|
| - CloseProcessPipes(
|
| - stdin_handles, stdout_handles, stderr_handles, exit_handles);
|
| - return error_code;
|
| - }
|
| - LPPROC_THREAD_ATTRIBUTE_LIST attribute_list =
|
| - reinterpret_cast<LPPROC_THREAD_ATTRIBUTE_LIST>(malloc(size));
|
| - ZeroMemory(attribute_list, size);
|
| - if (!InitializeProcThreadAttributeList(attribute_list, 1, 0, &size)) {
|
| - int error_code = SetOsErrorMessage(os_error_message);
|
| - CloseProcessPipes(
|
| - stdin_handles, stdout_handles, stderr_handles, exit_handles);
|
| - free(attribute_list);
|
| - return error_code;
|
| - }
|
| - static const int kNumInheritedHandles = 3;
|
| - HANDLE inherited_handles[kNumInheritedHandles] =
|
| - { stdin_handles[kReadHandle],
|
| - stdout_handles[kWriteHandle],
|
| - stderr_handles[kWriteHandle] };
|
| - if (!UpdateProcThreadAttribute(attribute_list,
|
| + LPPROC_THREAD_ATTRIBUTE_LIST attribute_list = NULL;
|
| +
|
| + bool supports_proc_thread_attr_lists = EnsureInitialized();
|
| + if (supports_proc_thread_attr_lists) {
|
| + // Setup the handles to inherit. We only want to inherit the three handles
|
| + // for stdin, stdout and stderr.
|
| + SIZE_T size = 0;
|
| + // The call to determine the size of an attribute list always fails with
|
| + // ERROR_INSUFFICIENT_BUFFER and that error should be ignored.
|
| + if (!init_proc_thread_attr_list(NULL, 1, 0, &size) &&
|
| + GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
|
| + int error_code = SetOsErrorMessage(os_error_message);
|
| + CloseProcessPipes(
|
| + stdin_handles, stdout_handles, stderr_handles, exit_handles);
|
| + return error_code;
|
| + }
|
| + attribute_list =
|
| + reinterpret_cast<LPPROC_THREAD_ATTRIBUTE_LIST>(malloc(size));
|
| + ZeroMemory(attribute_list, size);
|
| + if (!init_proc_thread_attr_list(attribute_list, 1, 0, &size)) {
|
| + int error_code = SetOsErrorMessage(os_error_message);
|
| + CloseProcessPipes(
|
| + stdin_handles, stdout_handles, stderr_handles, exit_handles);
|
| + free(attribute_list);
|
| + return error_code;
|
| + }
|
| + static const int kNumInheritedHandles = 3;
|
| + HANDLE inherited_handles[kNumInheritedHandles] =
|
| + { stdin_handles[kReadHandle],
|
| + stdout_handles[kWriteHandle],
|
| + stderr_handles[kWriteHandle] };
|
| + if (!update_proc_thread_attr(attribute_list,
|
| 0,
|
| PROC_THREAD_ATTRIBUTE_HANDLE_LIST,
|
| inherited_handles,
|
| kNumInheritedHandles * sizeof(HANDLE),
|
| NULL,
|
| NULL)) {
|
| - DeleteProcThreadAttributeList(attribute_list);
|
| - int error_code = SetOsErrorMessage(os_error_message);
|
| - CloseProcessPipes(
|
| - stdin_handles, stdout_handles, stderr_handles, exit_handles);
|
| - free(attribute_list);
|
| - return error_code;
|
| + delete_proc_thread_attr_list(attribute_list);
|
| + int error_code = SetOsErrorMessage(os_error_message);
|
| + CloseProcessPipes(
|
| + stdin_handles, stdout_handles, stderr_handles, exit_handles);
|
| + free(attribute_list);
|
| + return error_code;
|
| + }
|
| + startup_info.lpAttributeList = attribute_list;
|
| }
|
| - startup_info.lpAttributeList = attribute_list;
|
|
|
| PROCESS_INFORMATION process_info;
|
| ZeroMemory(&process_info, sizeof(process_info));
|
| @@ -467,8 +510,10 @@
|
| free(const_cast<wchar_t*>(system_path));
|
| for (int i = 0; i < arguments_length; i++) free(system_arguments[i]);
|
| delete[] system_arguments;
|
| - DeleteProcThreadAttributeList(attribute_list);
|
| - free(attribute_list);
|
| + if (supports_proc_thread_attr_lists) {
|
| + delete_proc_thread_attr_list(attribute_list);
|
| + free(attribute_list);
|
| + }
|
| return error_code;
|
| }
|
|
|
| @@ -553,8 +598,10 @@
|
| free(const_cast<wchar_t*>(system_working_directory));
|
| }
|
|
|
| - DeleteProcThreadAttributeList(attribute_list);
|
| - free(attribute_list);
|
| + if (supports_proc_thread_attr_lists) {
|
| + delete_proc_thread_attr_list(attribute_list);
|
| + free(attribute_list);
|
| + }
|
|
|
| if (result == 0) {
|
| int error_code = SetOsErrorMessage(os_error_message);
|
|
|