From 6d37e78406b6e002151cef3665665e810bb31529 Mon Sep 17 00:00:00 2001 From: Shizuo Fujita Date: Fri, 19 Dec 2025 17:38:51 +0900 Subject: [PATCH] Fix TypeError when processing a detached watcher This patch will fix a race condition where `Coolio_Loop_process_event` attempts to process an event for a watcher that has already been detached. When detach is called (e.g., from another thread or a preceding callback in the same loop cycle), the watcher's loop reference is cleared to nil. If an event for this watcher was already pending in the libev queue, the subsequent processing step causes an TypeError: ``` TypeError: wrong argument type nil (expected Coolio::Loop) ``` The patch will add a check to ensure the watcher is still enabled before accessing the loop data. If the watcher is detached (enabled == 0), the pending event is ignored. --- ext/cool.io/loop.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ext/cool.io/loop.c b/ext/cool.io/loop.c index 7bd1bbc..9e2e4fd 100644 --- a/ext/cool.io/loop.c +++ b/ext/cool.io/loop.c @@ -113,6 +113,12 @@ void Coolio_Loop_process_event(VALUE watcher, int revents) /* The Global VM lock isn't held right now, but hopefully * we can still do this safely */ watcher_data = Coolio_Watcher_ptr(watcher); + + if (watcher_data->enabled == 0) { + /* Ignore event because watcher was already detached. */ + return; + } + loop_data = Coolio_Loop_ptr(watcher_data->loop); /* Well, what better place to explain how this all works than