Skip to content

Commit 31f39d7

Browse files
committed
Fix: make Crystal::EventLoop#remove(io) a class method
The method is called from IO::FileDescriptor and Socket finalizers, which means they can be run from any thread during GC collections, yet calling an instance method means accessing the current event loop, which may have not been instantiated yet for the thread.
1 parent 46459d6 commit 31f39d7

File tree

10 files changed

+11
-27
lines changed

10 files changed

+11
-27
lines changed

src/crystal/event_loop/file_descriptor.cr

+2-1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ abstract class Crystal::EventLoop
2626
#
2727
# Called by `::IO::FileDescriptor#finalize` before closing the file
2828
# descriptor. Errors shall be silently ignored.
29-
abstract def remove(file_descriptor : Crystal::System::FileDescriptor) : Nil
29+
def self.remove(file_descriptor : Crystal::System::FileDescriptor) : Nil
30+
end
3031
end
3132
end

src/crystal/event_loop/iocp.cr

-6
Original file line numberDiff line numberDiff line change
@@ -201,9 +201,6 @@ class Crystal::EventLoop::IOCP < Crystal::EventLoop
201201
LibC.CancelIoEx(file_descriptor.windows_handle, nil) unless file_descriptor.system_blocking?
202202
end
203203

204-
def remove(file_descriptor : Crystal::System::FileDescriptor) : Nil
205-
end
206-
207204
private def wsa_buffer(bytes)
208205
wsabuf = LibC::WSABUF.new
209206
wsabuf.len = bytes.size
@@ -314,7 +311,4 @@ class Crystal::EventLoop::IOCP < Crystal::EventLoop
314311

315312
def close(socket : ::Socket) : Nil
316313
end
317-
318-
def remove(socket : ::Socket) : Nil
319-
end
320314
end

src/crystal/event_loop/libevent.cr

-6
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,6 @@ class Crystal::EventLoop::LibEvent < Crystal::EventLoop
9898
file_descriptor.evented_close
9999
end
100100

101-
def remove(file_descriptor : Crystal::System::FileDescriptor) : Nil
102-
end
103-
104101
def read(socket : ::Socket, slice : Bytes) : Int32
105102
evented_read(socket, "Error reading socket") do
106103
LibC.recv(socket.fd, slice, slice.size, 0).to_i32
@@ -194,9 +191,6 @@ class Crystal::EventLoop::LibEvent < Crystal::EventLoop
194191
socket.evented_close
195192
end
196193

197-
def remove(socket : ::Socket) : Nil
198-
end
199-
200194
def evented_read(target, errno_msg : String, &) : Int32
201195
loop do
202196
bytes_read = yield

src/crystal/event_loop/polling.cr

+3-3
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ abstract class Crystal::EventLoop::Polling < Crystal::EventLoop
164164
evented_close(file_descriptor)
165165
end
166166

167-
def remove(file_descriptor : System::FileDescriptor) : Nil
167+
def self.remove(file_descriptor : System::FileDescriptor) : Nil
168168
internal_remove(file_descriptor)
169169
end
170170

@@ -267,7 +267,7 @@ abstract class Crystal::EventLoop::Polling < Crystal::EventLoop
267267
evented_close(socket)
268268
end
269269

270-
def remove(socket : ::Socket) : Nil
270+
def self.remove(socket : ::Socket) : Nil
271271
internal_remove(socket)
272272
end
273273

@@ -317,7 +317,7 @@ abstract class Crystal::EventLoop::Polling < Crystal::EventLoop
317317
end
318318
end
319319

320-
private def internal_remove(io)
320+
private def self.internal_remove(io)
321321
return unless (index = io.__evloop_data).valid?
322322

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

src/crystal/event_loop/socket.cr

+2-1
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ abstract class Crystal::EventLoop
6969
#
7070
# Called by `::Socket#finalize` before closing the socket. Errors shall be
7171
# silently ignored.
72-
abstract def remove(socket : ::Socket) : Nil
72+
def self.remove(socket : ::Socket) : Nil
73+
end
7374
end
7475
end

src/crystal/event_loop/wasi.cr

-6
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,6 @@ class Crystal::EventLoop::Wasi < Crystal::EventLoop
5353
file_descriptor.evented_close
5454
end
5555

56-
def remove(file_descriptor : Crystal::System::FileDescriptor) : Nil
57-
end
58-
5956
def read(socket : ::Socket, slice : Bytes) : Int32
6057
evented_read(socket, "Error reading socket") do
6158
LibC.recv(socket.fd, slice, slice.size, 0).to_i32
@@ -88,9 +85,6 @@ class Crystal::EventLoop::Wasi < Crystal::EventLoop
8885
socket.evented_close
8986
end
9087

91-
def remove(socket : ::Socket) : Nil
92-
end
93-
9488
def evented_read(target, errno_msg : String, &) : Int32
9589
loop do
9690
bytes_read = yield

src/crystal/system/unix/process.cr

+1-1
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ struct Crystal::System::Process
352352

353353
private def self.reopen_io(src_io : IO::FileDescriptor, dst_io : IO::FileDescriptor)
354354
if src_io.closed?
355-
Crystal::EventLoop.current.remove(dst_io)
355+
typeof(Crystal::EventLoop.current).remove(dst_io)
356356
dst_io.file_descriptor_close
357357
else
358358
src_io = to_real_fd(src_io)

src/crystal/system/unix/signal.cr

+1-1
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ module Crystal::System::Signal
111111
# descriptors of the parent process and send it received signals.
112112
def self.after_fork
113113
@@pipe.each do |pipe_io|
114-
Crystal::EventLoop.current.remove(pipe_io)
114+
typeof(Crystal::EventLoop.current).remove(pipe_io)
115115
pipe_io.file_descriptor_close { }
116116
end
117117
ensure

src/io/file_descriptor.cr

+1-1
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ class IO::FileDescriptor < IO
255255
def finalize
256256
return if closed? || !close_on_finalize?
257257

258-
event_loop?.try(&.remove(self))
258+
typeof(Crystal::EventLoop.current).remove(self)
259259
file_descriptor_close { } # ignore error
260260
end
261261

src/socket.cr

+1-1
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ class Socket < IO
430430
def finalize
431431
return if closed?
432432

433-
event_loop?.try(&.remove(self))
433+
typeof(Crystal::EventLoop.current).remove(self)
434434
socket_close { } # ignore error
435435
end
436436

0 commit comments

Comments
 (0)