summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorSamuel Williams <samuel.williams@oriontransfer.co.nz>2021-07-02 22:41:16 +1200
committerSamuel Williams <samuel.williams@oriontransfer.co.nz>2021-11-10 19:21:05 +1300
commit4b8903421828cb9d4de139180563ae8d8f04e1ab (patch)
tree21a0d02ba22afad6a4ce1c042acf6d74767dc5a2 /include
parent56b90cf94465ce347a3d9a779363c78ce3deb180 (diff)
IO::Buffer for scheduler interface.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/4621
Diffstat (limited to 'include')
-rw-r--r--include/ruby/fiber/scheduler.h40
-rw-r--r--include/ruby/internal/intern/file.h2
-rw-r--r--include/ruby/io.h9
-rw-r--r--include/ruby/io/buffer.h71
4 files changed, 118 insertions, 4 deletions
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
@@ -671,6 +671,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
+ * <em>io</em>.
+ *
+ * @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()
* today. People prefer that API instead.
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