From 648870b5c577239b3274b0b48c82fb74910dfabf Mon Sep 17 00:00:00 2001 From: Samuel Williams Date: Fri, 31 Mar 2023 00:48:55 +1300 Subject: Support `IO#pread` / `IO#pwrite` using fiber scheduler. (#7594) * Skip test if non-blocking file IO is not supported. --- include/ruby/fiber/scheduler.h | 78 ++++++++++++++++++++++++++++-------------- include/ruby/io/buffer.h | 2 ++ 2 files changed, 55 insertions(+), 25 deletions(-) (limited to 'include') diff --git a/include/ruby/fiber/scheduler.h b/include/ruby/fiber/scheduler.h index 250b39b6df..ad3d2d7483 100644 --- a/include/ruby/fiber/scheduler.h +++ b/include/ruby/fiber/scheduler.h @@ -267,10 +267,10 @@ VALUE rb_fiber_scheduler_io_selectv(VALUE scheduler, int argc, VALUE *argv); * Non-blocking read from the passed IO. * * @param[in] scheduler Target scheduler. - * @param[out] io An io object to read from. - * @param[out] buffer Return buffer. - * @param[in] length Requested number of bytes to read. - * @param[in] offset The offset in the buffer to read to. + * @param[in] io An io object to read from. + * @param[in] buffer The buffer to read to. + * @param[in] length The minimum number of bytes to read. + * @param[in] offset The offset in the buffer to read from. * @retval RUBY_Qundef `scheduler` doesn't have `#io_read`. * @return otherwise What `scheduler.io_read` returns `[-errno, size]`. */ @@ -280,9 +280,9 @@ VALUE rb_fiber_scheduler_io_read(VALUE scheduler, VALUE io, VALUE buffer, size_t * Non-blocking write to the passed IO. * * @param[in] scheduler Target scheduler. - * @param[out] io An io object to write to. - * @param[in] buffer What to write. - * @param[in] length Number of bytes to write. + * @param[in] io An io object to write to. + * @param[in] buffer The buffer to write from. + * @param[in] length The minimum number of bytes to write. * @param[in] offset The offset in the buffer to write from. * @retval RUBY_Qundef `scheduler` doesn't have `#io_write`. * @return otherwise What `scheduler.io_write` returns `[-errno, size]`. @@ -293,10 +293,10 @@ VALUE rb_fiber_scheduler_io_write(VALUE scheduler, VALUE io, VALUE buffer, size_ * Non-blocking read from the passed IO at the specified offset. * * @param[in] scheduler Target scheduler. - * @param[out] io An io object to read from. - * @param[in] from The offset in the given IO to read the data from. - * @param[out] buffer The buffer to read the data to. - * @param[in] length Requested number of bytes to read. + * @param[in] io An io object to read from. + * @param[in] from The offset to read from. + * @param[in] buffer The buffer to read to. + * @param[in] length The minimum number of bytes to read. * @param[in] offset The offset in the buffer to read to. * @retval RUBY_Qundef `scheduler` doesn't have `#io_read`. * @return otherwise What `scheduler.io_read` returns. @@ -307,10 +307,10 @@ VALUE rb_fiber_scheduler_io_pread(VALUE scheduler, VALUE io, rb_off_t from, VALU * Non-blocking write to the passed IO at the specified offset. * * @param[in] scheduler Target scheduler. - * @param[out] io An io object to write to. - * @param[in] from The offset in the given IO to write the data to. - * @param[in] buffer The buffer to write the data from. - * @param[in] length Number of bytes to write. + * @param[in] io An io object to write to. + * @param[in] from The offset to write to. + * @param[in] buffer The buffer to write from. + * @param[in] length The minimum number of bytes to write. * @param[in] offset The offset in the buffer to write from. * @retval RUBY_Qundef `scheduler` doesn't have `#io_write`. * @return otherwise What `scheduler.io_write` returns. @@ -321,27 +321,55 @@ VALUE rb_fiber_scheduler_io_pwrite(VALUE scheduler, VALUE io, rb_off_t from, VAL * Non-blocking read from the passed IO using a native buffer. * * @param[in] scheduler Target scheduler. - * @param[out] io An io object to read from. - * @param[out] buffer Return buffer. - * @param[in] size Size of the return buffer. - * @param[in] length Requested number of bytes to read. + * @param[in] io An io object to read from. + * @param[in] base The memory to read to. + * @param[in] size Size of the memory. + * @param[in] length The minimum number of bytes to read. * @retval RUBY_Qundef `scheduler` doesn't have `#io_read`. * @return otherwise What `scheduler.io_read` returns. */ -VALUE rb_fiber_scheduler_io_read_memory(VALUE scheduler, VALUE io, void *buffer, size_t size, size_t length); +VALUE rb_fiber_scheduler_io_read_memory(VALUE scheduler, VALUE io, void *base, size_t size, size_t length); /** * Non-blocking write to the passed IO using a native buffer. * * @param[in] scheduler Target scheduler. - * @param[out] io An io object to write to. - * @param[in] buffer What to write. - * @param[in] size Size of the buffer. - * @param[in] length Number of bytes to write. + * @param[in] io An io object to write to. + * @param[in] base The memory to write from. + * @param[in] size Size of the memory. + * @param[in] length The minimum number of bytes to write. + * @retval RUBY_Qundef `scheduler` doesn't have `#io_write`. + * @return otherwise What `scheduler.io_write` returns. + */ +VALUE rb_fiber_scheduler_io_write_memory(VALUE scheduler, VALUE io, const void *base, size_t size, size_t length); + +/** + * Non-blocking pread from the passed IO using a native buffer. + * + * @param[in] scheduler Target scheduler. + * @param[in] io An io object to read from. + * @param[in] from The offset to read from. + * @param[in] base The memory to read to. + * @param[in] size Size of the memory. + * @param[in] length The minimum number of bytes to read. + * @retval RUBY_Qundef `scheduler` doesn't have `#io_read`. + * @return otherwise What `scheduler.io_read` returns. + */ +VALUE rb_fiber_scheduler_io_pread_memory(VALUE scheduler, VALUE io, rb_off_t from, void *base, size_t size, size_t length); + +/** + * Non-blocking pwrite to the passed IO using a native buffer. + * + * @param[in] scheduler Target scheduler. + * @param[in] io An io object to write to. + * @param[in] from The offset to write from. + * @param[in] base The memory to write from. + * @param[in] size Size of the memory. + * @param[in] length The minimum number of bytes to write. * @retval RUBY_Qundef `scheduler` doesn't have `#io_write`. * @return otherwise What `scheduler.io_write` returns. */ -VALUE rb_fiber_scheduler_io_write_memory(VALUE scheduler, VALUE io, const void *buffer, size_t size, size_t length); +VALUE rb_fiber_scheduler_io_pwrite_memory(VALUE scheduler, VALUE io, rb_off_t from, const void *base, size_t size, size_t length); /** * Non-blocking close the given IO. diff --git a/include/ruby/io/buffer.h b/include/ruby/io/buffer.h index 88e5598066..737fafe518 100644 --- a/include/ruby/io/buffer.h +++ b/include/ruby/io/buffer.h @@ -75,7 +75,9 @@ VALUE rb_io_buffer_map(VALUE io, size_t size, rb_off_t offset, enum rb_io_buffer VALUE rb_io_buffer_lock(VALUE self); VALUE rb_io_buffer_unlock(VALUE self); int rb_io_buffer_try_unlock(VALUE self); + VALUE rb_io_buffer_free(VALUE self); +VALUE rb_io_buffer_free_locked(VALUE self); int rb_io_buffer_get_bytes(VALUE self, void **base, size_t *size); void rb_io_buffer_get_bytes_for_reading(VALUE self, const void **base, size_t *size); -- cgit v1.2.1