Skip to content

Commit cde1fa9

Browse files
committed
Extract Crystal::EventLoop#before_close from #close (crystal-lang#16288)
1 parent 5d3faa0 commit cde1fa9

File tree

9 files changed

+47
-8
lines changed

9 files changed

+47
-8
lines changed

src/crystal/event_loop/file_descriptor.cr

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,16 @@ abstract class Crystal::EventLoop
4646
# file descriptor.
4747
abstract def reopened(file_descriptor : Crystal::System::FileDescriptor) : Nil
4848

49-
# Closes the file descriptor resource.
49+
# Hook to react on the file descriptor after the IO object has been marked
50+
# closed but before calling `#close` to actually close the system fd or
51+
# handle.
52+
#
53+
# On UNIX targets the event loop must resume pending waiters and let them
54+
# fail because the IO object is closed.
55+
def before_close(file_descriptor : Crystal::System::FileDescriptor) : Nil
56+
end
57+
58+
# Closes the system fd or handle.
5059
abstract def close(file_descriptor : Crystal::System::FileDescriptor) : Nil
5160
end
5261

src/crystal/event_loop/libevent.cr

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,10 +178,13 @@ class Crystal::EventLoop::LibEvent < Crystal::EventLoop
178178
file_descriptor.evented_close
179179
end
180180

181-
def close(file_descriptor : Crystal::System::FileDescriptor) : Nil
181+
def before_close(file_descriptor : Crystal::System::FileDescriptor) : Nil
182182
# perform cleanup before LibC.close. Using a file descriptor after it has
183183
# been closed is never defined and can always lead to undefined results
184184
file_descriptor.evented_close
185+
end
186+
187+
def close(file_descriptor : Crystal::System::FileDescriptor) : Nil
185188
file_descriptor.file_descriptor_close
186189
end
187190

@@ -299,10 +302,13 @@ class Crystal::EventLoop::LibEvent < Crystal::EventLoop
299302
end
300303
end
301304

302-
def close(socket : ::Socket) : Nil
305+
def before_close(socket : ::Socket) : Nil
303306
# perform cleanup before LibC.close. Using a file descriptor after it has
304307
# been closed is never defined and can always lead to undefined results
305308
socket.evented_close
309+
end
310+
311+
def close(socket : ::Socket) : Nil
306312
socket.socket_close
307313
end
308314

src/crystal/event_loop/polling.cr

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,10 +232,13 @@ abstract class Crystal::EventLoop::Polling < Crystal::EventLoop
232232
resume_all(file_descriptor)
233233
end
234234

235-
def close(file_descriptor : System::FileDescriptor) : Nil
235+
def before_close(file_descriptor : System::FileDescriptor) : Nil
236236
# perform cleanup before LibC.close. Using a file descriptor after it has
237237
# been closed is never defined and can always lead to undefined results
238238
resume_all(file_descriptor)
239+
end
240+
241+
def close(file_descriptor : System::FileDescriptor) : Nil
239242
file_descriptor.file_descriptor_close
240243
end
241244

@@ -363,10 +366,13 @@ abstract class Crystal::EventLoop::Polling < Crystal::EventLoop
363366
end
364367
end
365368

366-
def close(socket : ::Socket) : Nil
369+
def before_close(socket : ::Socket) : Nil
367370
# perform cleanup before LibC.close. Using a file descriptor after it has
368371
# been closed is never defined and can always lead to undefined results
369372
resume_all(socket)
373+
end
374+
375+
def close(socket : ::Socket) : Nil
370376
socket.socket_close
371377
end
372378

src/crystal/event_loop/socket.cr

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

77-
# Closes the socket.
77+
# Hook to react on the socket after the IO object has been marked closed but
78+
# before calling `#close` to actually close the system socket fd or handle.
79+
#
80+
# On UNIX targets the event loop must resume pending waiters and let them
81+
# fail because the IO object is closed.
82+
def before_close(socket : ::Socket) : Nil
83+
end
84+
85+
# Closes the system socket fd or handle.
7886
abstract def close(socket : ::Socket) : Nil
7987
end
8088

src/crystal/event_loop/wasi.cr

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,11 @@ class Crystal::EventLoop::Wasi < Crystal::EventLoop
8080
raise NotImplementedError.new("Crystal::EventLoop#reopened(FileDescriptor)")
8181
end
8282

83-
def close(file_descriptor : Crystal::System::FileDescriptor) : Nil
83+
def before_close(file_descriptor : Crystal::System::FileDescriptor) : Nil
8484
file_descriptor.evented_close
85+
end
86+
87+
def close(file_descriptor : Crystal::System::FileDescriptor) : Nil
8588
file_descriptor.file_descriptor_close
8689
end
8790

@@ -133,8 +136,11 @@ class Crystal::EventLoop::Wasi < Crystal::EventLoop
133136
raise NotImplementedError.new "Crystal::Wasi::EventLoop#accept"
134137
end
135138

136-
def close(socket : ::Socket) : Nil
139+
def before_close(socket : ::Socket) : Nil
137140
socket.evented_close
141+
end
142+
143+
def close(socket : ::Socket) : Nil
138144
socket.socket_close
139145
end
140146

src/crystal/system/unix/file_descriptor.cr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ module Crystal::System::FileDescriptor
134134
end
135135

136136
private def system_close
137+
event_loop.before_close(self)
137138
event_loop.close(self)
138139
end
139140

src/crystal/system/unix/socket.cr

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

226226
private def system_close
227+
event_loop.before_close(self)
227228
event_loop.close(self)
228229
end
229230

src/crystal/system/wasi/socket.cr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ module Crystal::System::Socket
152152
end
153153

154154
private def system_close
155+
event_loop.before_close(self)
155156
event_loop.close(self)
156157
end
157158

src/crystal/system/win32/file_descriptor.cr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ module Crystal::System::FileDescriptor
216216
end
217217

218218
private def system_close
219+
event_loop.before_close(self)
219220
event_loop.close(self)
220221
end
221222

0 commit comments

Comments
 (0)