I think @alanwu means the mutable buffer path (IO::Buffer.for w/ block) uses rb_str_locktmp to pin the String's malloc'ed content memory (not RString), while the immutable buffer path (IO::Buffer.for w/o block) utilizes CoW to obtain a f...hanazuki (Kasumi Hanazuki)
Applied in changeset commit:git|8aac19d5987150cf5c45fee73c7a949ca472f488. ---------- io_buffer: Reimplement dcompact for IO::Buffer The `source` field in IO::Buffer can have a String or an IO::Buffer object, if not nil. - When the `so...hanazuki (Kasumi Hanazuki)
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, ...hanazuki (Kasumi Hanazuki)
FYI: IO::Buffer is now broken (by a recent change) because the embedded Strings are not pinned, and I'm proposing a fix at #21210hanazuki (Kasumi Hanazuki)
I think the problem is that each IO::Buffer slice manages the lock state independently, and so the root IO::Buffer cannot know whether the memory is locked by one of its slices. If the memory is being accessed by a native function lik...hanazuki (Kasumi Hanazuki)
```ruby buffer = IO::Buffer.new(100) slice = buffer.slice buffer.locked do buffer.free rescue p $! #=> IO::Buffer::LockedError (expected) end slice.locked do p slice.locked? #=> true (expected) p buffer.locked? #=> f...hanazuki (Kasumi Hanazuki)
alanwu (Alan Wu) wrote in #note-5: > Another option that maintains validity across movement (untested): > ... So this will copy the embedded String content to a malloc'ed memory, right? The default GC embeds up to 640 bytes minus RS...hanazuki (Kasumi Hanazuki)
eightbitraptor (Matt V-H) wrote in #note-4: > Instead of pinning the source string, did you consider allowing the string to move by calculating the `base` offset, then moving the `source` string and updating the `base` pointer using `rb_...hanazuki (Kasumi Hanazuki)