@@ -37,33 +37,47 @@ cdef class UVHandle:
37
37
' {} without @no_gc_clear; loop was set to None by GC'
38
38
.format(self .__class__.__name__ ))
39
39
40
- if self ._handle is NULL or self ._closed :
40
+ if self ._handle is NULL :
41
41
return
42
42
43
43
# -> When we're at this point, something is wrong <-
44
44
45
45
if self ._handle.loop is NULL :
46
46
# The handle wasn't initialized with "uv_{handle}_init"
47
- self ._handle = NULL
47
+ self ._closed = 1
48
+ self ._free()
48
49
raise RuntimeError (
49
50
' {} is open in __dealloc__ with loop set to NULL'
50
51
.format(self .__class__.__name__ ))
51
52
53
+ if self ._closed == 1 :
54
+ # So _handle is not NULL and self._closed == 1?
55
+ raise RuntimeError (
56
+ ' {}.__dealloc__: _handle is NULL, _closed == 1' .format(
57
+ self .__class__.__name__ ))
58
+
52
59
# The handle is dealloced while open. Let's try to close it.
53
60
# Situations when this is possible include unhandled exceptions,
54
61
# errors during Handle.__cinit__/__init__ etc.
55
62
if self ._inited:
56
63
self ._handle.data = < void * > __NOHANDLE__
57
64
uv.uv_close(self ._handle, __uv_close_handle_cb) # void; no errors
65
+ self ._handle = NULL
58
66
warnings_warn(" unclosed resource {!r}" .format(self ),
59
67
ResourceWarning)
68
+ else :
69
+ # The handle was allocated, but not initialized
70
+ self ._closed = 1
71
+ self ._free()
60
72
61
- # The handle was allocated, but not initialized
62
- self ._closed = 1
73
+
74
+ cdef _free(self ):
75
+ PyMem_Free(self ._handle)
63
76
self ._handle = NULL
64
77
65
78
cdef inline _abort_init(self ):
66
- self ._handle = NULL
79
+ if self ._handle is not NULL :
80
+ self ._free()
67
81
68
82
IF DEBUG:
69
83
name = self .__class__.__name__
@@ -278,19 +292,29 @@ cdef inline bint __ensure_handle_data(uv.uv_handle_t* handle,
278
292
cdef void __uv_close_handle_cb(uv.uv_handle_t* handle) with gil:
279
293
cdef:
280
294
UVHandle h
295
+ Loop loop
281
296
282
297
if handle.data is NULL :
283
298
# Shouldn't happen.
284
- raise RuntimeError (' uv_handle_t.data is NULL in close callback' )
299
+ loop = < Loop> handle.loop.data
300
+ loop.call_exception_handler({
301
+ ' message' : ' uv_handle_t.data is NULL in close callback'
302
+ })
303
+ PyMem_Free(handle)
304
+ return
285
305
286
306
if < object > handle.data is not __NOHANDLE__:
287
307
h = < UVHandle> handle.data
308
+ h._handle = NULL
288
309
IF DEBUG:
289
310
h._loop._debug_handles_closed.update([
290
311
h.__class__ .__name__ ])
312
+ h._free()
291
313
Py_DECREF(h) # Was INCREFed in UVHandle._close
292
314
return
293
315
316
+ PyMem_Free(handle)
317
+
294
318
295
319
cdef void __close_all_handles(Loop loop):
296
320
uv.uv_walk(loop.uvloop, __uv_walk_close_all_handles_cb, < void * > loop) # void
0 commit comments