From 4b8903421828cb9d4de139180563ae8d8f04e1ab Mon Sep 17 00:00:00 2001 From: Samuel Williams Date: Fri, 2 Jul 2021 22:41:16 +1200 Subject: IO::Buffer for scheduler interface. --- include/ruby/fiber/scheduler.h | 40 ++++++++++++++++++--- include/ruby/internal/intern/file.h | 2 ++ include/ruby/io.h | 9 +++++ include/ruby/io/buffer.h | 71 +++++++++++++++++++++++++++++++++++++ 4 files changed, 118 insertions(+), 4 deletions(-) create mode 100644 include/ruby/io/buffer.h (limited to 'include') diff --git a/include/ruby/fiber/scheduler.h b/include/ruby/fiber/scheduler.h index 093b936475..8294442216 100644 --- a/include/ruby/fiber/scheduler.h +++ b/include/ruby/fiber/scheduler.h @@ -193,12 +193,11 @@ VALUE rb_fiber_scheduler_io_wait_writable(VALUE scheduler, VALUE io); * @param[in] scheduler Target scheduler. * @param[out] io An io object to read from. * @param[out] buffer Return buffer. - * @param[in] offset Offset inside of `buffer`. * @param[in] length Requested 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(VALUE scheduler, VALUE io, VALUE buffer, size_t offset, size_t length); +VALUE rb_fiber_scheduler_io_read(VALUE scheduler, VALUE io, VALUE buffer, size_t length); /** * Nonblocking write to the passed IO. @@ -206,12 +205,45 @@ VALUE rb_fiber_scheduler_io_read(VALUE scheduler, VALUE io, VALUE buffer, size_t * @param[in] scheduler Target scheduler. * @param[out] io An io object to write to. * @param[in] buffer What to write. - * @param[in] offset Offset inside of `buffer`. * @param[in] length 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(VALUE scheduler, VALUE io, VALUE buffer, size_t offset, size_t length); +VALUE rb_fiber_scheduler_io_write(VALUE scheduler, VALUE io, VALUE buffer, size_t length); + +/** + * Nonblocking 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] length Requested 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); + +/** + * Nonblocking 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] length 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); + +/** + * Nonblocking close the given IO. + * + * @param[in] scheduler Target scheduler. + * @param[in] io An io object to close. + * @retval RUBY_Qundef `scheduler` doesn't have `#io_close`. + * @return otherwise What `scheduler.io_close` returns. + */ +VALUE rb_fiber_scheduler_io_close(VALUE scheduler, VALUE io); /** * Nonblocking DNS lookup. diff --git a/include/ruby/internal/intern/file.h b/include/ruby/internal/intern/file.h index 8e98ba08f8..ce676bfd09 100644 --- a/include/ruby/internal/intern/file.h +++ b/include/ruby/internal/intern/file.h @@ -187,6 +187,8 @@ RBIMPL_ATTR_PURE() */ int rb_is_absolute_path(const char *path); +size_t rb_file_size(VALUE file); + RBIMPL_SYMBOL_EXPORT_END() #endif /* RBIMPL_INTERN_FILE_H */ diff --git a/include/ruby/io.h b/include/ruby/io.h index aac7846537..3e035c114d 100644 --- a/include/ruby/io.h +++ b/include/ruby/io.h @@ -670,6 +670,15 @@ VALUE rb_io_set_write_io(VALUE io, VALUE w); */ void rb_io_set_nonblock(rb_io_t *fptr); +/** + * Returns an integer representing the numeric file descriptor for + * io. + * + * @param[in] io An IO. + * @retval int A file descriptor. + */ +int rb_io_descriptor(VALUE io); + /** * This function breaks down the option hash that `IO#initialize` takes into * components. This is an implementation detail of rb_io_extract_modeenc() diff --git a/include/ruby/io/buffer.h b/include/ruby/io/buffer.h new file mode 100644 index 0000000000..073215186c --- /dev/null +++ b/include/ruby/io/buffer.h @@ -0,0 +1,71 @@ +/** + * @file + * @author Samuel Williams + * @date Fri 2 Jul 2021 16:29:01 NZST + * @copyright Copyright (C) 2021 Samuel Williams + * @copyright This file is a part of the programming language Ruby. + * Permission is hereby granted, to either redistribute and/or + * modify this file, provided that the conditions mentioned in the + * file COPYING are met. Consult the file for details. + */ + +#pragma once + +#include "ruby/ruby.h" +#include "ruby/internal/config.h" + +RUBY_SYMBOL_EXPORT_BEGIN + +RUBY_EXTERN VALUE rb_cIOBuffer; +RUBY_EXTERN size_t RUBY_IO_BUFFER_PAGE_SIZE; + +enum rb_io_buffer_flags { + // The memory in the buffer is owned by someone else. + RB_IO_BUFFER_EXTERNAL = 0, + // The memory in the buffer is allocated internally. + RB_IO_BUFFER_INTERNAL = 1, + // The memory in the buffer is mapped. + RB_IO_BUFFER_MAPPED = 2, + + // The buffer is locked and cannot be resized. + RB_IO_BUFFER_LOCKED = 16, + + // The buffer mapping is private and will not impact other processes or the underlying file. + RB_IO_BUFFER_PRIVATE = 32, + + // The buffer is read-only and cannot be modified. + RB_IO_BUFFER_IMMUTABLE = 64 +}; + +enum rb_io_buffer_endian { + RB_IO_BUFFER_LITTLE_ENDIAN = 4, + RB_IO_BUFFER_BIG_ENDIAN = 8, + +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + RB_IO_BUFFER_HOST_ENDIAN = RB_IO_BUFFER_LITTLE_ENDIAN, +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + RB_IO_BUFFER_HOST_ENDIAN = RB_IO_BUFFER_BIG_ENDIAN, +#elif REG_DWORD == REG_DWORD_LITTLE_ENDIAN + RB_IO_BUFFER_HOST_ENDIAN = RB_IO_BUFFER_LITTLE_ENDIAN, +#elif REG_DWORD == REG_DWORD_BIG_ENDIAN + RB_IO_BUFFER_HOST_ENDIAN = RB_IO_BUFFER_BIG_ENDIAN, +#endif + + RB_IO_BUFFER_NETWORK_ENDIAN = RB_IO_BUFFER_BIG_ENDIAN, +}; + +VALUE rb_io_buffer_new(void *base, size_t size, enum rb_io_buffer_flags flags); +VALUE rb_io_buffer_map(VALUE io, size_t size, off_t offset, enum rb_io_buffer_flags flags); + +VALUE rb_io_buffer_lock(VALUE self); +VALUE rb_io_buffer_unlock(VALUE self); +VALUE rb_io_buffer_free(VALUE self); + +void rb_io_buffer_get_mutable(VALUE self, void **base, size_t *size); +void rb_io_buffer_get_immutable(VALUE self, const void **base, size_t *size); + +size_t rb_io_buffer_copy(VALUE self, VALUE source, size_t offset); +void rb_io_buffer_resize(VALUE self, size_t size, size_t preserve); +void rb_io_buffer_clear(VALUE self, uint8_t value, size_t offset, size_t length); + +RUBY_SYMBOL_EXPORT_END -- cgit v1.2.3