diff options
author | Brad King <brad.king@kitware.com> | 2023-09-27 15:36:05 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2023-09-28 13:34:11 (GMT) |
commit | fe2ecf920fd3eefedf2d7a5b2a12dda3ac37d0ef (patch) | |
tree | 34767f4ea784cf8bccd0d723ca78a55a018a5484 /Utilities | |
parent | 6bb05172acc8519a174a4f6294dd96d82c846d4c (diff) | |
download | CMake-fe2ecf920fd3eefedf2d7a5b2a12dda3ac37d0ef.zip CMake-fe2ecf920fd3eefedf2d7a5b2a12dda3ac37d0ef.tar.gz CMake-fe2ecf920fd3eefedf2d7a5b2a12dda3ac37d0ef.tar.bz2 |
libuv: win,process: avoid kernel bug with starting Windows Store apps
Backport upstream libuv commit `93ca3f15` (win,process: avoid kernel bug
with starting Windows Store apps, 2023-09-27) from libuv PR 4152.
Fixes: #23029
Patch-by: Jameson Nash <vtjnash@gmail.com>
Diffstat (limited to 'Utilities')
-rw-r--r-- | Utilities/cmlibuv/src/win/process.c | 41 |
1 files changed, 29 insertions, 12 deletions
diff --git a/Utilities/cmlibuv/src/win/process.c b/Utilities/cmlibuv/src/win/process.c index 3b5b2800..14d7a69 100644 --- a/Utilities/cmlibuv/src/win/process.c +++ b/Utilities/cmlibuv/src/win/process.c @@ -102,6 +102,21 @@ static void uv__init_global_job_handle(void) { &info, sizeof info)) uv_fatal_error(GetLastError(), "SetInformationJobObject"); + + + if (!AssignProcessToJobObject(uv_global_job_handle_, GetCurrentProcess())) { + /* Make sure this handle is functional. The Windows kernel has a bug that + * if the first use of AssignProcessToJobObject is for a Windows Store + * program, subsequent attempts to use the handle with fail with + * INVALID_PARAMETER (87). This is possibly because all uses of the handle + * must be for the same Terminal Services session. We can ensure it is tied + * to our current session now by adding ourself to it. We could remove + * ourself afterwards, but there doesn't seem to be a reason to. + */ + DWORD err = GetLastError(); + if (err != ERROR_ACCESS_DENIED) + uv_fatal_error(err, "AssignProcessToJobObject"); + } } @@ -1101,6 +1116,7 @@ int uv_spawn(uv_loop_t* loop, * breakaway. */ process_flags |= DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP; + process_flags |= CREATE_SUSPENDED; } if (options->cpumask != NULL) { @@ -1159,20 +1175,8 @@ int uv_spawn(uv_loop_t* loop, TerminateProcess(info.hProcess, 1); goto done; } - - /* The process affinity of the child is set. Let it run. */ - if (ResumeThread(info.hThread) == ((DWORD)-1)) { - err = GetLastError(); - TerminateProcess(info.hProcess, 1); - goto done; - } } - /* Spawn succeeded. Beyond this point, failure is reported asynchronously. */ - - process->process_handle = info.hProcess; - process->pid = info.dwProcessId; - /* If the process isn't spawned as detached, assign to the global job object * so windows will kill it when the parent process dies. */ if (!(options->flags & UV_PROCESS_DETACHED)) { @@ -1195,6 +1199,19 @@ int uv_spawn(uv_loop_t* loop, } } + if (process_flags & CREATE_SUSPENDED) { + if (ResumeThread(info.hThread) == ((DWORD)-1)) { + err = GetLastError(); + TerminateProcess(info.hProcess, 1); + goto done; + } + } + + /* Spawn succeeded. Beyond this point, failure is reported asynchronously. */ + + process->process_handle = info.hProcess; + process->pid = info.dwProcessId; + /* Set IPC pid to all IPC pipes. */ for (i = 0; i < options->stdio_count; i++) { const uv_stdio_container_t* fdopt = &options->stdio[i]; |