From: "ioquatix (Samuel Williams) via ruby-core" Date: 2026-09-09T23:12:15+00:00 Subject: [ruby-core:126626] [Ruby Feature#22274] Make `IO::Buffer` no longer experimental. Issue #22274 has been updated by ioquatix (Samuel Williams). Thanks - a few thoughts - For stability, I'm not thinking of bug free, but just "won't change [much] in the future". Also, I'd be okay with defining a subset of the Ruby and C interfaces as stable and leaving others as experimental if that's an easier bar to get over. Regarding the order of arguments change, that's only the surface - we also changed the semantics of the scheduler hooks and most major schedulers have now adopted that change so I'm not planning on reverting it. Yes, it was all marked as experimental - and yes it's painful, but it's the right way forward as the previous design was bad on multiple levels. That's all on me. I'd rather fix it now as we did than have to live with it forever. Regarding `set_string` - some operations are missing locking since it was only recently introduced, but that will hopefully fix the `set_string` issue. Also, I don't think we expect `IO::Buffer` mutations to be thread safe so the only goal is to not crash but we don't guarantee anything about the behaviour if used on different threads without coordination (as I'm sure you'd agree with). It might be nice if we can share frozen `IO::Buffer` instances between ractors though - or perhaps establish some semantics like this. Re slices, I don't have a strong opinion about how they work. I think the expectation is that `IO::Buffer` instances have stable addresses, because this is a primitive for use with system calls and operating system interfaces like `io_uring` registered buffers. So having a GC move the internal backing memory around is a non-starter IMHO. Slicing is based on that design - stable addressing - slices usually won't outlive their backing store being resized. It would probably be more work to invalidate all slices than to allow them to remain valid (if they still land in the source allocation). So, to be more specific, if you can't model slices as absolute addresses + validation, an offset is probably okay. I think that if a slice became invalid after any source buffer resize or re-allocation, that would be acceptable. Leaving this unspecified is probably acceptable so that different implementations can do it efficiently. For the sake of the JVM, you might be better off with the following design: ```ruby # -> represents a full size allocation (base + size) IO::Buffer::Allocation = Struct.new(:base, :size) IO::Buffer = Struct.new(:allocation, :offset, :size) ``` Then every `IO::Buffer` is effectively a slice, with the root slice having offset = 0. Probably the biggest challenge is that we are trying to expose enough of the underlying system to be efficient, including POSIX semantics, without trying to be overly prescriptive about how it actually works, so that implementation on, e.g. JVM, Wasm, etc is possible. As you said, now is the time to figure out if there are any semantics that won't work nicely. ---------------------------------------- Feature #22274: Make `IO::Buffer` no longer experimental. https://bugs.ruby-lang.org/issues/22274#change-118865 * Author: ioquatix (Samuel Williams) * Status: Open * Assignee: ioquatix (Samuel Williams) ---------------------------------------- `IO::Buffer` was introduced in Ruby 3.1 by Feature #18020 as an experimental API. It provides an efficient buffer abstraction for fiber scheduler I/O, zero-copy operations, binary protocol implementations, and access from native extensions. Since then, the API has seen several Ruby releases of real-world use and substantial development. Ruby 4.1 now has cohesive semantics for buffer ownership and lifecycle, slicing, locking, string and file mappings, MemoryView integration, and single-transfer I/O operations. I propose making both the Ruby and public C interfaces of `IO::Buffer` non-experimental in Ruby 4.1. This would involve: * Removing the allocation-time experimental warning. * Removing the experimental status from the class documentation. * Removing `RB_IO_BUFFER_EXPERIMENTAL` from the public C header. * Removing warning suppression that is only required because `IO::Buffer` is experimental. * Updating NEWS to describe `IO::Buffer` as stable. `RUBY_IO_BUFFER_VERSION` would remain available for compile-time feature detection as the interface continues to evolve. Before stabilizing the interface, I would particularly appreciate feedback from JRuby and TruffleRuby maintainers. Related work: * Original proposal: https://bugs.ruby-lang.org/issues/18020 * CRuby implementation PR: https://github.com/ruby/ruby/pull/18486 * TruffleRuby implementation: https://github.com/truffleruby/truffleruby/pull/4248 * JRuby implementation: https://github.com/jruby/jruby/blob/master/core/src/main/java/org/jruby/RubyIOBuffer.java * JRuby file-mapping issue: https://github.com/jruby/jruby/issues/8714 -- https://bugs.ruby-lang.org/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/