The `source` field in IO::Buffer can have a String or an IO::Buffer
object, if not nil.
- When the `source` is a String object. The `base` field points to the
memory location of the String content, which can be embedded in
RSTRING, and in that case, GC compaction can move the memory region
along with the String object.
Thus, IO::Buffer needs to pin the `source` object to prevent `base`
pointer from becoming invalid.
- When the `source` is an IO::Buffer, then `base` is a pointer to a
malloced or mmapped memory region, managed by the source IO::Buffer.
In this case, we don't need to pin the source IO::Buffer object,
since the referred memory region won't get moved by GC.
Closes: [Bug #21210]
The allocated buffers may be consecutive memory addresses. This will mean
that `b->base == a->base + a->size` even though `a` and `b` are separate
buffers.
Use PR_SET_VMA_ANON_NAME to set human-readable names for anonymous
virtual memory areas mapped by `mmap()` when compiled and run on Linux
5.17 or higher. This makes it convenient for developers to debug mmap.
The current implementation of `IO::Buffer#copy` and `#set_string` has
an undefined behavior when the source and destination memory overlaps,
due to the underlying use of the `memcpy` C function.
This patch guarantees the methods to be safe even when copying between
overlapping buffers by replacing `memcpy` with `memmove`,
Fixes: [Bug #20745]
This does not change any actual behaviour, but provides a choke point for blocking IO operations.
* Update `IO::Buffer` to use `rb_io_blocking_region`.
* Update `File` to use `rb_io_blocking_region`.
* Update `IO` to use `rb_io_blocking_region`.
* Restore experimental warnings.
* Documentation and code structure improvements.
* Improved validation of flags, clarified documentation of argument handling.
* Remove inconsistent use of `Example:` and add example to `null?`.
* Expose `IO::Buffer#private?` and add test.
* Fix `io_buffer_get_string` default length computation.
When an offset bigger than the size is given, the resulting length will be
computed incorrectly. Raise an argument error in this case.
* Validate all arguments.
* Documentation consistency.
* Improve consistency of `pread`/`pwrite` implementation when given length.
* Remove HAVE_PREAD / HAVE_PWRITE - it is no longer optional.
`#resize(0)` on an IO::Buffer with internal buffer allocated will
result in calling `realloc(data->base, 0)`. The behavior of `realloc`
with size = 0 is implementation-defined (glibc frees the object
and returns NULL, while BSDs return an inaccessible object). And
thus such usage is deprecated in standard C (upcoming C23 will make it
UB).
To avoid this problem, just `free`s the memory when the new size is zero.
`length` is a required argument for `IO::Buffer#read` and
`IO::Buffer#write` methods, and `argc` is already checked with
`rb_check_arity`. Also fix the call-seq of `IO::Buffer#read`.