From 7b6a47a0788da1d906a01e6e84b0d2c083252289 Mon Sep 17 00:00:00 2001 From: Peter Amstutz Date: Tue, 12 Mar 2024 20:02:51 -0400 Subject: [PATCH 1/2] Wait for notify thread to end before llfuse.main() completes. When fuse_session_remove_chan is called, the _notify_loop thread _must not_ be running or it may try to use the deleted channel and cause a segfault. --- src/fuse_api.pxi | 1 + 1 file changed, 1 insertion(+) diff --git a/src/fuse_api.pxi b/src/fuse_api.pxi index a156f21..5606ad8 100644 --- a/src/fuse_api.pxi +++ b/src/fuse_api.pxi @@ -313,6 +313,7 @@ def main(workers=None, handle_signals=True): session_loop_single() else: session_loop_mt(workers) + t.join() if exc_info: # Re-raise expression from request handler From db9a16930e9c6240666d2aece8f3f5fe7deba2be Mon Sep 17 00:00:00 2001 From: Peter Amstutz Date: Thu, 14 Mar 2024 10:35:03 -0400 Subject: [PATCH 2/2] Use an event variable to tell the notify queue to drain Intended to speed up the notify queue shut down if there are pending events when running tests that repeatedly create and destroy llfuse sessions. --- src/fuse_api.pxi | 2 ++ src/llfuse.pyx | 3 +++ src/misc.pxi | 6 +++++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/fuse_api.pxi b/src/fuse_api.pxi index 5606ad8..7ebd08d 100644 --- a/src/fuse_api.pxi +++ b/src/fuse_api.pxi @@ -301,9 +301,11 @@ def main(workers=None, handle_signals=True): on_exit.callback(lambda: restore_signal_handlers()) # Start notification handling thread + _notify_queue_shutdown.clear() t = threading.Thread(target=_notify_loop) t.daemon = True t.start() + on_exit.callback(_notify_queue_shutdown.set) on_exit.callback(_notify_queue.put, None, block=True, timeout=5) on_exit.callback(lambda: fuse_session_reset(session)) diff --git a/src/llfuse.pyx b/src/llfuse.pyx index a8f5597..61dd46a 100644 --- a/src/llfuse.pyx +++ b/src/llfuse.pyx @@ -137,6 +137,9 @@ lock_released = NoLockManager.__new__(NoLockManager) cdef object _notify_queue _notify_queue = Queue(maxsize=1000) +cdef object _notify_queue_shutdown +_notify_queue_shutdown = threading.Event() + # Exported for access from Python code # (in the Cython source, we want ENOATTR to refer # to the C constant, not a Python object) diff --git a/src/misc.pxi b/src/misc.pxi index d93667c..04bbad3 100644 --- a/src/misc.pxi +++ b/src/misc.pxi @@ -267,7 +267,11 @@ def _notify_loop(): while True: req = _notify_queue.get() if req is None: - return + break + + if _notify_queue_shutdown.is_set(): + # Just drain the queue + continue if req.kind == NOTIFY_INVAL_INODE: if req.attr_only: