From 479765432391ecb62c95f82cef0b8db0ce00e288 Mon Sep 17 00:00:00 2001 From: John Vandenberg Date: Tue, 1 Jun 2021 16:27:34 +0800 Subject: [PATCH] remove_event_loop: Allow ignoring specific errors Replaces a bare except with Exception, and updates the test case to specify only a single exception that is allowed to occur. Related to https://github.com/capnproto/pycapnp/issues/254 --- capnp/lib/capnp.pyx | 18 ++++++++++++++---- test/test_threads.py | 17 ++++++++++++++--- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/capnp/lib/capnp.pyx b/capnp/lib/capnp.pyx index 93dd21a..1f60975 100644 --- a/capnp/lib/capnp.pyx +++ b/capnp/lib/capnp.pyx @@ -1843,16 +1843,26 @@ cpdef remove_event_loop(ignore_errors=False): if C_DEFAULT_EVENT_LOOP: try: C_DEFAULT_EVENT_LOOP._remove() - except: - if not ignore_errors: + except Exception as e: + if isinstance(ignore_errors, Exception): + if isinstance(e, ignore_errors): + ignore_errors = True + if ignore_errors is True: + pass + else: raise C_DEFAULT_EVENT_LOOP = None if len(_THREAD_LOCAL_EVENT_LOOPS) > 0: for loop in _THREAD_LOCAL_EVENT_LOOPS: try: loop._remove() - except: - if not ignore_errors: + except Exception as e: + if isinstance(ignore_errors, Exception): + if isinstance(e, ignore_errors): + ignore_errors = True + if ignore_errors is True: + pass + else: raise _THREAD_LOCAL_EVENT_LOOPS = [] _C_DEFAULT_EVENT_LOOP_LOCAL = None diff --git a/test/test_threads.py b/test/test_threads.py index 6aede31..be619b2 100644 --- a/test/test_threads.py +++ b/test/test_threads.py @@ -9,6 +9,9 @@ import threading import pytest import capnp + +from capnp.lib.capnp import KjException + import test_capability_capnp @@ -35,11 +38,19 @@ def test_making_threaded_event_loop(): ''' Threaded event loop test ''' - capnp.remove_event_loop(True) - capnp.create_event_loop(True) + # The following raises a KjException, and if not caught causes an SIGABRT: + # kj/async.c++:973: failed: expected head == nullptr; EventLoop destroyed with events still in the queue. + # Memory leak?; head->trace() = kj::_::ForkHub + # kj::_::AdapterPromiseNode > + # stack: ... + # python(..) malloc: *** error for object 0x...: pointer being freed was not allocated + # python(..) malloc: *** set a breakpoint in malloc_error_break to debug + # Fatal Python error: Aborted + capnp.remove_event_loop(KjException) + capnp.create_event_loop(KjException) capnp.remove_event_loop() - capnp.create_event_loop(True) + capnp.create_event_loop(KjException) class Server(test_capability_capnp.TestInterface.Server):