Skip to content

Commit 05bba82

Browse files
committed
Gather stats on uv_handler_t allocs in debug mode
1 parent 7b56550 commit 05bba82

File tree

4 files changed

+32
-0
lines changed

4 files changed

+32
-0
lines changed

uvloop/_testbase.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,11 @@ def tearDown(self):
8787
gc.collect()
8888
gc.collect()
8989

90+
self.assertEqual(
91+
self.loop._debug_uv_handles_total,
92+
self.loop._debug_uv_handles_freed,
93+
'not all uv_handle_t handles were freed')
94+
9095
self.assertEqual(
9196
self.loop._debug_cb_handles_count, 0,
9297
'not all callbacks (call_soon) are GCed')

uvloop/handles/handle.pyx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,12 @@ cdef class UVHandle:
6868
self._free()
6969

7070
cdef inline _free(self):
71+
if self._handle == NULL:
72+
return
73+
74+
IF DEBUG:
75+
self._loop._debug_uv_handles_freed += 1
76+
7177
PyMem_Free(self._handle)
7278
self._handle = NULL
7379

@@ -101,6 +107,8 @@ cdef class UVHandle:
101107
self._handle.data = <void*>self
102108
if self._loop._debug:
103109
self._source_traceback = tb_extract_stack(sys_getframe(0))
110+
IF DEBUG:
111+
self._loop._debug_uv_handles_total += 1
104112

105113
cdef inline _start_init(self, Loop loop):
106114
IF DEBUG:
@@ -303,6 +311,13 @@ cdef void __uv_close_handle_cb(uv.uv_handle_t* handle) with gil:
303311
if handle.data is NULL:
304312
# The original UVHandle is long dead. Just free the mem of
305313
# the uv_handle_t* handler.
314+
315+
IF DEBUG:
316+
if handle.loop == NULL or handle.loop.data == NULL:
317+
raise RuntimeError(
318+
'__uv_close_handle_cb: handle.loop is invalid')
319+
(<Loop>handle.loop.data)._debug_uv_handles_freed += 1
320+
306321
PyMem_Free(handle)
307322
else:
308323
h = <UVHandle>handle.data

uvloop/loop.pxd

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@ cdef class Loop:
8787
readonly object _debug_handles_closed
8888
readonly object _debug_handles_current
8989

90+
readonly uint64_t _debug_uv_handles_total
91+
readonly uint64_t _debug_uv_handles_freed
92+
9093
readonly uint64_t _debug_cb_handles_total
9194
readonly uint64_t _debug_cb_handles_count
9295
readonly uint64_t _debug_cb_timer_handles_total

uvloop/loop.pyx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@ cdef class Loop:
9898
self._debug_handles_closed = col_Counter()
9999
self._debug_handles_total = col_Counter()
100100

101+
self._debug_uv_handles_total = 0
102+
self._debug_uv_handles_freed = 0
103+
101104
self._debug_stream_read_cb_total = 0
102105
self._debug_stream_read_eof_total = 0
103106
self._debug_stream_read_errors_total = 0
@@ -871,6 +874,12 @@ cdef class Loop:
871874
self._debug_handles_total[name]))
872875
print()
873876

877+
print('uv_handle_t (current: {}; freed: {}; total: {})'.format(
878+
self._debug_uv_handles_total - self._debug_uv_handles_freed,
879+
self._debug_uv_handles_freed,
880+
self._debug_uv_handles_total))
881+
print()
882+
874883
print('--- Streams debug info: ---')
875884
print('Write errors: {}'.format(
876885
self._debug_stream_write_errors_total))

0 commit comments

Comments
 (0)