mirror of
https://github.com/Kitware/CMake.git
synced 2026-08-02 22:09:35 +00:00
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>
This commit is contained in:
@@ -102,6 +102,21 @@ static void uv__init_global_job_handle(void) {
|
|||||||
&info,
|
&info,
|
||||||
sizeof info))
|
sizeof info))
|
||||||
uv_fatal_error(GetLastError(), "SetInformationJobObject");
|
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.
|
* breakaway.
|
||||||
*/
|
*/
|
||||||
process_flags |= DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP;
|
process_flags |= DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP;
|
||||||
|
process_flags |= CREATE_SUSPENDED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options->cpumask != NULL) {
|
if (options->cpumask != NULL) {
|
||||||
@@ -1159,20 +1175,8 @@ int uv_spawn(uv_loop_t* loop,
|
|||||||
TerminateProcess(info.hProcess, 1);
|
TerminateProcess(info.hProcess, 1);
|
||||||
goto done;
|
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
|
/* If the process isn't spawned as detached, assign to the global job object
|
||||||
* so windows will kill it when the parent process dies. */
|
* so windows will kill it when the parent process dies. */
|
||||||
if (!(options->flags & UV_PROCESS_DETACHED)) {
|
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. */
|
/* Set IPC pid to all IPC pipes. */
|
||||||
for (i = 0; i < options->stdio_count; i++) {
|
for (i = 0; i < options->stdio_count; i++) {
|
||||||
const uv_stdio_container_t* fdopt = &options->stdio[i];
|
const uv_stdio_container_t* fdopt = &options->stdio[i];
|
||||||
|
|||||||
Reference in New Issue
Block a user