aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/src/Modules/_posixsubprocess.c
diff options
context:
space:
mode:
authorshadchin <shadchin@yandex-team.com>2023-10-03 23:32:21 +0300
committershadchin <shadchin@yandex-team.com>2023-10-03 23:48:51 +0300
commit01ffd024041ac933854c367fb8d1b5682d19883f (patch)
treeb70aa497ba132a133ccece49f7763427dcd0743f /contrib/tools/python3/src/Modules/_posixsubprocess.c
parenta33fdb9a34581fd124e92535153b1f1fdeca6aaf (diff)
downloadydb-01ffd024041ac933854c367fb8d1b5682d19883f.tar.gz
Update Python 3 to 3.11.6
Diffstat (limited to 'contrib/tools/python3/src/Modules/_posixsubprocess.c')
-rw-r--r--contrib/tools/python3/src/Modules/_posixsubprocess.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/contrib/tools/python3/src/Modules/_posixsubprocess.c b/contrib/tools/python3/src/Modules/_posixsubprocess.c
index ad9daaede4..072519c91a 100644
--- a/contrib/tools/python3/src/Modules/_posixsubprocess.c
+++ b/contrib/tools/python3/src/Modules/_posixsubprocess.c
@@ -537,7 +537,7 @@ reset_signal_handlers(const sigset_t *child_sigmask)
* required by POSIX but not supported natively on Linux. Another reason to
* avoid this family of functions is that sharing an address space between
* processes running with different privileges is inherently insecure.
- * See bpo-35823 for further discussion and references.
+ * See https://bugs.python.org/issue35823 for discussion and references.
*
* In some C libraries, setrlimit() has the same thread list/signalling
* behavior since resource limits were per-thread attributes before
@@ -774,6 +774,7 @@ do_fork_exec(char *const exec_array[],
pid_t pid;
#ifdef VFORK_USABLE
+ PyThreadState *vfork_tstate_save;
if (child_sigmask) {
/* These are checked by our caller; verify them in debug builds. */
assert(!call_setuid);
@@ -781,8 +782,23 @@ do_fork_exec(char *const exec_array[],
assert(!call_setgroups);
assert(preexec_fn == Py_None);
+ /* Drop the GIL so that other threads can continue execution while this
+ * thread in the parent remains blocked per vfork-semantics on the
+ * child's exec syscall outcome. Exec does filesystem access which
+ * can take an arbitrarily long time. This addresses GH-104372.
+ *
+ * The vfork'ed child still runs in our address space. Per POSIX it
+ * must be limited to nothing but exec, but the Linux implementation
+ * is a little more usable. See the child_exec() comment - The child
+ * MUST NOT re-acquire the GIL.
+ */
+ vfork_tstate_save = PyEval_SaveThread();
pid = vfork();
- if (pid == -1) {
+ if (pid != 0) {
+ // Not in the child process, reacquire the GIL.
+ PyEval_RestoreThread(vfork_tstate_save);
+ }
+ if (pid == (pid_t)-1) {
/* If vfork() fails, fall back to using fork(). When it isn't
* allowed in a process by the kernel, vfork can return -1
* with errno EINVAL. https://bugs.python.org/issue47151. */
@@ -795,6 +811,7 @@ do_fork_exec(char *const exec_array[],
}
if (pid != 0) {
+ // Parent process.
return pid;
}