diff --git a/src/crystal/event_loop/polling.cr b/src/crystal/event_loop/polling.cr index 75dc17702746..106a8a0d55b2 100644 --- a/src/crystal/event_loop/polling.cr +++ b/src/crystal/event_loop/polling.cr @@ -409,6 +409,9 @@ abstract class Crystal::EventLoop::Polling < Crystal::EventLoop event = Event.new(type, Fiber.current, index, timeout) return false unless Polling.arena.get?(index) do |pd| + unless pd.value.owned_by?(self) + pd.value.take_ownership(self, io.fd, index) + end yield pd, pointerof(event) end else diff --git a/src/crystal/event_loop/polling/poll_descriptor.cr b/src/crystal/event_loop/polling/poll_descriptor.cr index 801d1b148d89..d4fac2f04565 100644 --- a/src/crystal/event_loop/polling/poll_descriptor.cr +++ b/src/crystal/event_loop/polling/poll_descriptor.cr @@ -7,6 +7,10 @@ struct Crystal::EventLoop::Polling::PollDescriptor @readers = Waiters.new @writers = Waiters.new + def owned_by?(event_loop) : Bool + @event_loop == event_loop + end + # Makes *event_loop* the new owner of *fd*. # Removes *fd* from the current event loop (if any). def take_ownership(event_loop : EventLoop, fd : Int32, index : Arena::Index) : Nil