aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/Lib/multiprocessing/popen_fork.py
diff options
context:
space:
mode:
authorthegeorg <thegeorg@yandex-team.com>2024-02-19 02:38:52 +0300
committerthegeorg <thegeorg@yandex-team.com>2024-02-19 02:50:43 +0300
commitd96fa07134c06472bfee6718b5cfd1679196fc99 (patch)
tree31ec344fa9d3ff8dc038692516b6438dfbdb8a2d /contrib/tools/python3/Lib/multiprocessing/popen_fork.py
parent452cf9e068aef7110e35e654c5d47eb80111ef89 (diff)
downloadydb-d96fa07134c06472bfee6718b5cfd1679196fc99.tar.gz
Sync contrib/tools/python3 layout with upstream
* Move src/ subdir contents to the top of the layout * Rename self-written lib -> lib2 to avoid CaseFolding warning from the VCS * Regenerate contrib/libs/python proxy-headers accordingly 4ccc62ac1511abcf0fed14ccade38e984e088f1e
Diffstat (limited to 'contrib/tools/python3/Lib/multiprocessing/popen_fork.py')
-rw-r--r--contrib/tools/python3/Lib/multiprocessing/popen_fork.py83
1 files changed, 83 insertions, 0 deletions
diff --git a/contrib/tools/python3/Lib/multiprocessing/popen_fork.py b/contrib/tools/python3/Lib/multiprocessing/popen_fork.py
new file mode 100644
index 00000000000..625981cf476
--- /dev/null
+++ b/contrib/tools/python3/Lib/multiprocessing/popen_fork.py
@@ -0,0 +1,83 @@
+import os
+import signal
+
+from . import util
+
+__all__ = ['Popen']
+
+#
+# Start child process using fork
+#
+
+class Popen(object):
+ method = 'fork'
+
+ def __init__(self, process_obj):
+ util._flush_std_streams()
+ self.returncode = None
+ self.finalizer = None
+ self._launch(process_obj)
+
+ def duplicate_for_child(self, fd):
+ return fd
+
+ def poll(self, flag=os.WNOHANG):
+ if self.returncode is None:
+ try:
+ pid, sts = os.waitpid(self.pid, flag)
+ except OSError:
+ # Child process not yet created. See #1731717
+ # e.errno == errno.ECHILD == 10
+ return None
+ if pid == self.pid:
+ self.returncode = os.waitstatus_to_exitcode(sts)
+ return self.returncode
+
+ def wait(self, timeout=None):
+ if self.returncode is None:
+ if timeout is not None:
+ from multiprocessing.connection import wait
+ if not wait([self.sentinel], timeout):
+ return None
+ # This shouldn't block if wait() returned successfully.
+ return self.poll(os.WNOHANG if timeout == 0.0 else 0)
+ return self.returncode
+
+ def _send_signal(self, sig):
+ if self.returncode is None:
+ try:
+ os.kill(self.pid, sig)
+ except ProcessLookupError:
+ pass
+ except OSError:
+ if self.wait(timeout=0.1) is None:
+ raise
+
+ def terminate(self):
+ self._send_signal(signal.SIGTERM)
+
+ def kill(self):
+ self._send_signal(signal.SIGKILL)
+
+ def _launch(self, process_obj):
+ code = 1
+ parent_r, child_w = os.pipe()
+ child_r, parent_w = os.pipe()
+ self.pid = os.fork()
+ if self.pid == 0:
+ try:
+ os.close(parent_r)
+ os.close(parent_w)
+ code = process_obj._bootstrap(parent_sentinel=child_r)
+ finally:
+ os._exit(code)
+ else:
+ os.close(child_w)
+ os.close(child_r)
+ self.finalizer = util.Finalize(self, util.close_fds,
+ (parent_r, parent_w,))
+ self.sentinel = parent_r
+
+ def close(self):
+ if self.finalizer is not None:
+ self.finalizer()