Skip to content

Commit 055ee41

Browse files
committed
Add Crystal::EventLoop#resume_all that replaces #reopened
Allows to distinguish the "resume all waiters" from the actual "close" actions. Optional and only meaningful for poll based event loops. It replaces the now obsolete `#reopened` hook.
1 parent 2f752d0 commit 055ee41

File tree

8 files changed

+31
-29
lines changed

8 files changed

+31
-29
lines changed

src/crystal/event_loop/file_descriptor.cr

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,12 @@ abstract class Crystal::EventLoop
4141
# Blocks the current fiber until the file descriptor is ready for write.
4242
abstract def wait_writable(file_descriptor : Crystal::System::FileDescriptor) : Nil
4343

44-
# Hook to react on the file descriptor after it has been reopened. For
45-
# example we might want to resume all pending operations to act on the new
46-
# file descriptor.
47-
abstract def reopened(file_descriptor : Crystal::System::FileDescriptor) : Nil
44+
# Resumes fibers waiting on the file descriptor.
45+
#
46+
# Optional. Only called on UNIX targets and only meant for poll event loops.
47+
def resume_all(file_descriptor : Crystal::System::FileDescriptor) : Nil
48+
raise NotImplementedError.new("#{self.class.name}#resume_all(Crystal::System::FileDescriptor)")
49+
end
4850

4951
# Closes the file descriptor resource.
5052
abstract def close(file_descriptor : Crystal::System::FileDescriptor) : Nil

src/crystal/event_loop/iocp.cr

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -303,10 +303,6 @@ class Crystal::EventLoop::IOCP < Crystal::EventLoop
303303
raise NotImplementedError.new("Crystal::System::IOCP#wait_writable(FileDescriptor)")
304304
end
305305

306-
def reopened(file_descriptor : Crystal::System::FileDescriptor) : Nil
307-
raise NotImplementedError.new("Crystal::System::IOCP#reopened(FileDescriptor)")
308-
end
309-
310306
def close(file_descriptor : Crystal::System::FileDescriptor) : Nil
311307
LibC.CancelIoEx(file_descriptor.windows_handle, nil) unless file_descriptor.system_blocking?
312308
file_descriptor.file_descriptor_close

src/crystal/event_loop/libevent.cr

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -174,14 +174,11 @@ class Crystal::EventLoop::LibEvent < Crystal::EventLoop
174174
end
175175
end
176176

177-
def reopened(file_descriptor : Crystal::System::FileDescriptor) : Nil
177+
def resume_all(file_descriptor : Crystal::System::FileDescriptor) : Nil
178178
file_descriptor.evented_close
179179
end
180180

181181
def close(file_descriptor : Crystal::System::FileDescriptor) : Nil
182-
# perform cleanup before LibC.close. Using a file descriptor after it has
183-
# been closed is never defined and can always lead to undefined results
184-
file_descriptor.evented_close
185182
file_descriptor.file_descriptor_close
186183
end
187184

@@ -299,10 +296,11 @@ class Crystal::EventLoop::LibEvent < Crystal::EventLoop
299296
end
300297
end
301298

302-
def close(socket : ::Socket) : Nil
303-
# perform cleanup before LibC.close. Using a file descriptor after it has
304-
# been closed is never defined and can always lead to undefined results
299+
def resume_all(socket : ::Socket) : Nil
305300
socket.evented_close
301+
end
302+
303+
def close(socket : ::Socket) : Nil
306304
socket.socket_close
307305
end
308306

src/crystal/event_loop/polling.cr

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -228,14 +228,11 @@ abstract class Crystal::EventLoop::Polling < Crystal::EventLoop
228228
end
229229
end
230230

231-
def reopened(file_descriptor : System::FileDescriptor) : Nil
232-
resume_all(file_descriptor)
231+
def resume_all(file_descriptor : System::FileDescriptor) : Nil
232+
resume_all_impl(file_descriptor)
233233
end
234234

235235
def close(file_descriptor : System::FileDescriptor) : Nil
236-
# perform cleanup before LibC.close. Using a file descriptor after it has
237-
# been closed is never defined and can always lead to undefined results
238-
resume_all(file_descriptor)
239236
file_descriptor.file_descriptor_close
240237
end
241238

@@ -363,10 +360,11 @@ abstract class Crystal::EventLoop::Polling < Crystal::EventLoop
363360
end
364361
end
365362

363+
def resume_all(socket : ::Socket) : Nil
364+
resume_all_impl(socket)
365+
end
366+
366367
def close(socket : ::Socket) : Nil
367-
# perform cleanup before LibC.close. Using a file descriptor after it has
368-
# been closed is never defined and can always lead to undefined results
369-
resume_all(socket)
370368
socket.socket_close
371369
end
372370

@@ -400,7 +398,7 @@ abstract class Crystal::EventLoop::Polling < Crystal::EventLoop
400398
end
401399
end
402400

403-
private def resume_all(io)
401+
private def resume_all_impl(io)
404402
return unless (index = io.__evloop_data).valid?
405403

406404
Polling.arena.free(index) do |pd|

src/crystal/event_loop/socket.cr

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,13 @@ abstract class Crystal::EventLoop
7474
# and the source address.
7575
abstract def receive_from(socket : ::Socket, slice : Bytes) : Tuple(Int32, ::Socket::Address)
7676

77+
# Resumes fibers waiting on the socket.
78+
#
79+
# Optional. Only called on UNIX targets and only meant for poll event loops.
80+
def resume_all(file_descriptor : Crystal::System::FileDescriptor) : Nil
81+
raise NotImplementedError.new("#{self.class.name}#resume_all(Crystal::System::FileDescriptor)")
82+
end
83+
7784
# Closes the socket.
7885
abstract def close(socket : ::Socket) : Nil
7986
end

src/crystal/event_loop/wasi.cr

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,6 @@ class Crystal::EventLoop::Wasi < Crystal::EventLoop
7676
end
7777
end
7878

79-
def reopened(file_descriptor : Crystal::System::FileDescriptor) : Nil
80-
raise NotImplementedError.new("Crystal::EventLoop#reopened(FileDescriptor)")
81-
end
82-
8379
def close(file_descriptor : Crystal::System::FileDescriptor) : Nil
8480
file_descriptor.evented_close
8581
file_descriptor.file_descriptor_close

src/crystal/system/unix/file_descriptor.cr

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,13 @@ module Crystal::System::FileDescriptor
126126
# Mark the handle open, since we had to have dup'd a live handle.
127127
@closed = false
128128

129-
event_loop.reopened(self)
129+
# resume all pending waiters so they can start waiting on the new fd
130+
event_loop.resume_all(self)
130131
end
131132

132133
private def system_close
134+
# resume pending fibers before closing the fd
135+
event_loop.resume_all(self)
133136
event_loop.close(self)
134137
end
135138

src/crystal/system/unix/socket.cr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,8 @@ module Crystal::System::Socket
224224
end
225225

226226
private def system_close
227+
# resume pending fibers before closing the fd
228+
event_loop.resume_all(self)
227229
event_loop.close(self)
228230
end
229231

0 commit comments

Comments
 (0)