mirror of https://github.com/python/cpython
Prevent handle leak if CreateProcess() fails in multiprocessing
This commit is contained in:
parent
86eb7e97ae
commit
bd7b5dd816
|
@ -209,6 +209,9 @@ else:
|
||||||
_tls = _thread._local()
|
_tls = _thread._local()
|
||||||
|
|
||||||
def __init__(self, process_obj):
|
def __init__(self, process_obj):
|
||||||
|
cmd = ' '.join('"%s"' % x for x in get_command_line())
|
||||||
|
prep_data = get_preparation_data(process_obj._name)
|
||||||
|
|
||||||
# create pipe for communication with child
|
# create pipe for communication with child
|
||||||
rfd, wfd = os.pipe()
|
rfd, wfd = os.pipe()
|
||||||
|
|
||||||
|
@ -216,31 +219,30 @@ else:
|
||||||
rhandle = duplicate(msvcrt.get_osfhandle(rfd), inheritable=True)
|
rhandle = duplicate(msvcrt.get_osfhandle(rfd), inheritable=True)
|
||||||
os.close(rfd)
|
os.close(rfd)
|
||||||
|
|
||||||
# start process
|
with open(wfd, 'wb', closefd=True) as to_child:
|
||||||
cmd = get_command_line() + [rhandle]
|
# start process
|
||||||
cmd = ' '.join('"%s"' % x for x in cmd)
|
try:
|
||||||
hp, ht, pid, tid = _winapi.CreateProcess(
|
hp, ht, pid, tid = _winapi.CreateProcess(
|
||||||
_python_exe, cmd, None, None, 1, 0, None, None, None
|
_python_exe, cmd + (' %s' % rhandle),
|
||||||
)
|
None, None, 1, 0, None, None, None
|
||||||
_winapi.CloseHandle(ht)
|
)
|
||||||
close(rhandle)
|
_winapi.CloseHandle(ht)
|
||||||
|
finally:
|
||||||
|
close(rhandle)
|
||||||
|
|
||||||
# set attributes of self
|
# set attributes of self
|
||||||
self.pid = pid
|
self.pid = pid
|
||||||
self.returncode = None
|
self.returncode = None
|
||||||
self._handle = hp
|
self._handle = hp
|
||||||
self.sentinel = int(hp)
|
self.sentinel = int(hp)
|
||||||
|
|
||||||
# send information to child
|
# send information to child
|
||||||
prep_data = get_preparation_data(process_obj._name)
|
Popen._tls.process_handle = int(hp)
|
||||||
to_child = os.fdopen(wfd, 'wb')
|
try:
|
||||||
Popen._tls.process_handle = int(hp)
|
dump(prep_data, to_child, HIGHEST_PROTOCOL)
|
||||||
try:
|
dump(process_obj, to_child, HIGHEST_PROTOCOL)
|
||||||
dump(prep_data, to_child, HIGHEST_PROTOCOL)
|
finally:
|
||||||
dump(process_obj, to_child, HIGHEST_PROTOCOL)
|
del Popen._tls.process_handle
|
||||||
finally:
|
|
||||||
del Popen._tls.process_handle
|
|
||||||
to_child.close()
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def thread_is_spawning():
|
def thread_is_spawning():
|
||||||
|
|
Loading…
Reference in New Issue