Browse Source

chore: cherry-pick c03569f from libuv (#40125)

* chore: cherry-pick c03569f from libuv

Refs https://github.com/libuv/libuv/commit/c03569f0df3bb26e7e7bec9feabd9ae3c372568e

Co-authored-by: deepak1556 <[email protected]>

* chore: update .patches

* chore: update patches

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: deepak1556 <[email protected]>
Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
trop[bot] 1 year ago
parent
commit
fefe45e897

+ 1 - 0
patches/node/.patches

@@ -43,3 +43,4 @@ tls_ensure_tls_sockets_are_closed_if_the_underlying_wrap_closes.patch
 test_deflake_test-tls-socket-close.patch
 net_fix_crash_due_to_simultaneous_close_shutdown_on_js_stream.patch
 net_use_asserts_in_js_socket_stream_to_catch_races_in_future.patch
+win_process_avoid_assert_after_spawning_store_app_4152.patch

+ 85 - 0
patches/node/win_process_avoid_assert_after_spawning_store_app_4152.patch

@@ -0,0 +1,85 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Jameson Nash <[email protected]>
+Date: Mon, 2 Oct 2023 15:15:18 +0200
+Subject: win,process: avoid assert after spawning Store app (#4152)
+
+Make sure this handle is functional. The Windows kernel seems to have 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 possilby 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.
+
+Secondly, we start the process suspended so that we can make sure we
+added it to the job control object before it does anything itself (such
+as launch more jobs or exit).
+
+Fixes: https://github.com/JuliaLang/julia/issues/51461
+
+diff --git a/deps/uv/src/win/process.c b/deps/uv/src/win/process.c
+index 24c633393fd15dcf87726b174d6b027a969e0f0d..4ad9fec900fa66b0e8c6894701e94f420de903a8 100644
+--- a/deps/uv/src/win/process.c
++++ b/deps/uv/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");
++  }
+ }
+ 
+ 
+@@ -1098,6 +1113,7 @@ int uv_spawn(uv_loop_t* loop,
+      * breakaway.
+      */
+     process_flags |= DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP;
++    process_flags |= CREATE_SUSPENDED;
+   }
+ 
+   if (!CreateProcessW(application_path,
+@@ -1115,11 +1131,6 @@ int uv_spawn(uv_loop_t* loop,
+     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)) {
+@@ -1142,6 +1153,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];