diff --git a/uvloop/cbhandles.pyx b/uvloop/cbhandles.pyx index 2914b42e..ad18fe94 100644 --- a/uvloop/cbhandles.pyx +++ b/uvloop/cbhandles.pyx @@ -1,3 +1,20 @@ +cdef inline void _debug_cb_handles_inc(Loop loop): + if _debug_cb_handles_lock != NULL: + PyThread_acquire_lock(_debug_cb_handles_lock, 1) + loop._debug_cb_handles_total += 1 + loop._debug_cb_handles_count += 1 + if _debug_cb_handles_lock != NULL: + PyThread_release_lock(_debug_cb_handles_lock) + + +cdef inline void _debug_cb_handles_dec(Loop loop): + if _debug_cb_handles_lock != NULL: + PyThread_acquire_lock(_debug_cb_handles_lock, 1) + loop._debug_cb_handles_count -= 1 + if _debug_cb_handles_lock != NULL: + PyThread_release_lock(_debug_cb_handles_lock) + + @cython.no_gc_clear @cython.freelist(DEFAULT_FREELIST_SIZE) cdef class Handle: @@ -9,8 +26,7 @@ cdef class Handle: cdef inline _set_loop(self, Loop loop): self.loop = loop if UVLOOP_DEBUG: - loop._debug_cb_handles_total += 1 - loop._debug_cb_handles_count += 1 + _debug_cb_handles_inc(loop) if loop._debug: self._source_traceback = extract_stack() @@ -21,7 +37,7 @@ cdef class Handle: def __dealloc__(self): if UVLOOP_DEBUG and self.loop is not None: - self.loop._debug_cb_handles_count -= 1 + _debug_cb_handles_dec(self.loop) if self.loop is None: raise RuntimeError('Handle.loop is None in Handle.__dealloc__') @@ -423,10 +439,14 @@ cdef extract_stack(): if f is None: return + if getattr(f, "f_lineno", None) is None or getattr(f, "f_code", None) is None: + return None try: stack = tb_StackSummary.extract(tb_walk_stack(f), limit=DEBUG_STACK_DEPTH, lookup_lines=False) + except (AttributeError, TypeError): + return None finally: f = None diff --git a/uvloop/loop.pyx b/uvloop/loop.pyx index 2ed1f272..4eb1495c 100644 --- a/uvloop/loop.pyx +++ b/uvloop/loop.pyx @@ -31,6 +31,12 @@ from libc cimport errno from cpython cimport PyObject from cpython cimport PyErr_CheckSignals, PyErr_Occurred from cpython cimport PyThread_get_thread_ident +from cpython.pythread cimport ( + PyThread_type_lock, + PyThread_allocate_lock, + PyThread_acquire_lock, + PyThread_release_lock, +) from cpython cimport Py_INCREF, Py_DECREF, Py_XDECREF, Py_XINCREF from cpython cimport ( PyObject_GetBuffer, PyBuffer_Release, PyBUF_SIMPLE, @@ -52,6 +58,7 @@ cdef: int PY311 = PY_VERSION_HEX >= 0x030b0000 int PY313 = PY_VERSION_HEX >= 0x030d0000 uint64_t MAX_SLEEP = 3600 * 24 * 365 * 100 + PyThread_type_lock _debug_cb_handles_lock = PyThread_allocate_lock() cdef _is_sock_stream(sock_type):