diff --git a/src/crystal/system/file_descriptor.cr b/src/crystal/system/file_descriptor.cr index 03868bc07034..5aa0003962fc 100644 --- a/src/crystal/system/file_descriptor.cr +++ b/src/crystal/system/file_descriptor.cr @@ -39,6 +39,14 @@ module Crystal::System::FileDescriptor event_loop.write(self, slice) end + private def system_wait_readable : Nil + event_loop.wait_readable(self) + end + + private def system_wait_writable : Nil + event_loop.wait_writable(self) + end + private def event_loop? : Crystal::EventLoop::FileDescriptor? Crystal::EventLoop.current? end diff --git a/src/crystal/system/socket.cr b/src/crystal/system/socket.cr index 54648f17f7db..ce52e288e5cd 100644 --- a/src/crystal/system/socket.cr +++ b/src/crystal/system/socket.cr @@ -89,6 +89,14 @@ module Crystal::System::Socket event_loop.write(self, slice) end + private def system_wait_readable : Nil + event_loop.wait_readable(self) + end + + private def system_wait_writable : Nil + event_loop.wait_writable(self) + end + # private def system_close # Closes the internal handle without notifying the event loop. diff --git a/src/io/file_descriptor.cr b/src/io/file_descriptor.cr index 82c2b8ac232f..4494dffec0fa 100644 --- a/src/io/file_descriptor.cr +++ b/src/io/file_descriptor.cr @@ -315,4 +315,18 @@ class IO::FileDescriptor < IO private def unbuffered_flush : Nil # Nothing end + + # Blocks the current fiber until the file descriptor is ready for read. + # Raises `TimeoutError` when the configured `#read_timeout` has elapsed, + # otherwise returns normally. + def wait_readable : Nil + system_wait_readable + end + + # Blocks the current fiber until the file descriptor is ready for write. + # Raises `TimeoutError` when the configured `#write_timeout` has elapsed, + # otherwise returns normally. + def wait_writable : Nil + system_wait_writable + end end diff --git a/src/socket.cr b/src/socket.cr index b862c30e2f9e..b053ccff0db1 100644 --- a/src/socket.cr +++ b/src/socket.cr @@ -467,6 +467,20 @@ class Socket < IO private def unbuffered_flush : Nil # Nothing end + + # Blocks the current fiber until the socket is ready for read. Raises + # `TimeoutError` when the configured `#read_timeout` has elapsed, otherwise + # returns normally. + def wait_readable : Nil + system_wait_readable + end + + # Blocks the current fiber until the socket is ready for write. Raises + # `TimeoutError` when the configured `#write_timeout` has elapsed, otherwise + # returns normally. + def wait_writable : Nil + system_wait_writable + end end require "./socket/*"