diff options
author | Samuel Williams <samuel.williams@oriontransfer.co.nz> | 2023-03-31 00:48:55 +1300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-31 00:48:55 +1300 |
commit | 648870b5c577239b3274b0b48c82fb74910dfabf (patch) | |
tree | f944e0a1919bcb46537e1f3bd522beee9e72288c /scheduler.c | |
parent | 6f122965cf8704f019445faead58040e9be2effb (diff) |
Support `IO#pread` / `IO#pwrite` using fiber scheduler. (#7594)
* Skip test if non-blocking file IO is not supported.
Notes
Notes:
Merged-By: ioquatix <samuel@codeotaku.com>
Diffstat (limited to 'scheduler.c')
-rw-r--r-- | scheduler.c | 76 |
1 files changed, 56 insertions, 20 deletions
diff --git a/scheduler.c b/scheduler.c index 477f11c03c..866e53993f 100644 --- a/scheduler.c +++ b/scheduler.c @@ -458,15 +458,15 @@ VALUE rb_fiber_scheduler_io_selectv(VALUE scheduler, int argc, VALUE *argv) /* * Document-method: Fiber::Scheduler#io_read - * call-seq: io_read(io, buffer, minimum_length) -> read length or -errno + * call-seq: io_read(io, buffer, length) -> read length or -errno * * Invoked by IO#read or IO#Buffer.read to read +length+ bytes from +io+ into a - * specified +buffer+ (see IO::Buffer). + * specified +buffer+ (see IO::Buffer) at the given +offset+. * - * The +minimum_length+ argument is the "minimum length to be read". If the IO - * buffer size is 8KiB, but the +length+ is +1024+ (1KiB), up to 8KiB might be - * read, but at least 1KiB will be. Generally, the only case where less data - * than +length+ will be read is if there is an error reading the data. + * The +length+ argument is the "minimum length to be read". If the IO buffer + * size is 8KiB, but the +length+ is +1024+ (1KiB), up to 8KiB might be read, + * but at least 1KiB will be. Generally, the only case where less data than + * +length+ will be read is if there is an error reading the data. * * Specifying a +length+ of 0 is valid and means try reading at least once and * return any available data. @@ -492,13 +492,19 @@ rb_fiber_scheduler_io_read(VALUE scheduler, VALUE io, VALUE buffer, size_t lengt return rb_check_funcall(scheduler, id_io_read, 4, arguments); } - /* * Document-method: Fiber::Scheduler#io_read * call-seq: io_pread(io, buffer, from, length, offset) -> read length or -errno * - * Invoked by IO::Buffer#pread. See that method for description of arguments. + * Invoked by IO#pread or IO::Buffer#pread to read +length+ bytes from +io+ + * at offset +from+ into a specified +buffer+ (see IO::Buffer) at the given + * +offset+. + * + * This method is semantically the same as #io_read, but it allows to specify + * the offset to read from and is often better for asynchronous IO on the same + * file. * + * The method should be considered _experimental_. */ VALUE rb_fiber_scheduler_io_pread(VALUE scheduler, VALUE io, rb_off_t from, VALUE buffer, size_t length, size_t offset) @@ -512,16 +518,16 @@ rb_fiber_scheduler_io_pread(VALUE scheduler, VALUE io, rb_off_t from, VALUE buff /* * Document-method: Scheduler#io_write - * call-seq: io_write(io, buffer, minimum_length) -> written length or -errno + * call-seq: io_write(io, buffer, length) -> written length or -errno * * Invoked by IO#write or IO::Buffer#write to write +length+ bytes to +io+ from - * from a specified +buffer+ (see IO::Buffer). + * from a specified +buffer+ (see IO::Buffer) at the given +offset+. * - * The +minimum_length+ argument is the "minimum length to be written". If the - * IO buffer size is 8KiB, but the +length+ specified is 1024 (1KiB), at most - * 8KiB will be written, but at least 1KiB will be. Generally, the only case - * where less data than +minimum_length+ will be written is if there is an - * error writing the data. + * The +length+ argument is the "minimum length to be written". If the IO + * buffer size is 8KiB, but the +length+ specified is 1024 (1KiB), at most 8KiB + * will be written, but at least 1KiB will be. Generally, the only case where + * less data than +length+ will be written is if there is an error writing the + * data. * * Specifying a +length+ of 0 is valid and means try writing at least once, as * much data as possible. @@ -552,7 +558,15 @@ rb_fiber_scheduler_io_write(VALUE scheduler, VALUE io, VALUE buffer, size_t leng * Document-method: Fiber::Scheduler#io_pwrite * call-seq: io_pwrite(io, buffer, from, length, offset) -> written length or -errno * - * Invoked by IO::Buffer#pwrite. See that method for description of arguments. + * Invoked by IO#pwrite or IO::Buffer#pwrite to write +length+ bytes to +io+ + * at offset +from+ into a specified +buffer+ (see IO::Buffer) at the given + * +offset+. + * + * This method is semantically the same as #io_write, but it allows to specify + * the offset to write to and is often better for asynchronous IO on the same + * file. + * + * The method should be considered _experimental_. * */ VALUE @@ -572,8 +586,7 @@ rb_fiber_scheduler_io_read_memory(VALUE scheduler, VALUE io, void *base, size_t VALUE result = rb_fiber_scheduler_io_read(scheduler, io, buffer, length, 0); - rb_io_buffer_unlock(buffer); - rb_io_buffer_free(buffer); + rb_io_buffer_free_locked(buffer); return result; } @@ -585,8 +598,31 @@ rb_fiber_scheduler_io_write_memory(VALUE scheduler, VALUE io, const void *base, VALUE result = rb_fiber_scheduler_io_write(scheduler, io, buffer, length, 0); - rb_io_buffer_unlock(buffer); - rb_io_buffer_free(buffer); + rb_io_buffer_free_locked(buffer); + + return result; +} + +VALUE +rb_fiber_scheduler_io_pread_memory(VALUE scheduler, VALUE io, rb_off_t from, void *base, size_t size, size_t length) +{ + VALUE buffer = rb_io_buffer_new(base, size, RB_IO_BUFFER_LOCKED); + + VALUE result = rb_fiber_scheduler_io_pread(scheduler, io, from, buffer, length, 0); + + rb_io_buffer_free_locked(buffer); + + return result; +} + +VALUE +rb_fiber_scheduler_io_pwrite_memory(VALUE scheduler, VALUE io, rb_off_t from, const void *base, size_t size, size_t length) +{ + VALUE buffer = rb_io_buffer_new((void*)base, size, RB_IO_BUFFER_LOCKED|RB_IO_BUFFER_READONLY); + + VALUE result = rb_fiber_scheduler_io_pwrite(scheduler, io, from, buffer, length, 0); + + rb_io_buffer_free_locked(buffer); return result; } |