@@ -11,6 +11,16 @@ cdef class UVProcess(UVHandle):
11
11
self ._preexec_fn = None
12
12
self ._restore_signals = True
13
13
14
+ cdef _close_process_handle(self ):
15
+ # XXX: This is a workaround for a libuv bug:
16
+ # - https://github.com/libuv/libuv/issues/1933
17
+ # - https://github.com/libuv/libuv/pull/551
18
+ if self ._handle is NULL :
19
+ return
20
+ self ._handle.data = NULL
21
+ uv.uv_close(self ._handle, __uv_close_process_handle_cb)
22
+ self ._handle = NULL # close callback will free() the memory
23
+
14
24
cdef _init(self , Loop loop, list args, dict env,
15
25
cwd, start_new_session,
16
26
_stdin, _stdout, _stderr, # std* can be defined as macros in C
@@ -79,16 +89,15 @@ cdef class UVProcess(UVHandle):
79
89
80
90
if _PyImport_ReleaseLock() < 0 :
81
91
# See CPython/posixmodule.c for details
92
+ self ._close_process_handle()
82
93
if err < 0 :
83
94
self ._abort_init()
84
95
else :
85
96
self ._close()
86
97
raise RuntimeError (' not holding the import lock' )
87
98
88
99
if err < 0 :
89
- if UVLOOP_DEBUG and uv.uv_is_active(self ._handle):
90
- raise RuntimeError (
91
- ' active uv_process_t handle after failed uv_spawn' )
100
+ self ._close_process_handle()
92
101
self ._abort_init()
93
102
raise convert_error(err)
94
103
@@ -754,3 +763,7 @@ cdef __socketpair():
754
763
os_set_inheritable(fds[1 ], False )
755
764
756
765
return fds[0 ], fds[1 ]
766
+
767
+
768
+ cdef void __uv_close_process_handle_cb(uv.uv_handle_t* handle) with gil:
769
+ PyMem_RawFree(handle)
0 commit comments