ruby-changes:69714
From: Samuel <ko1@a...>
Date: Fri, 12 Nov 2021 12:46:23 +0900 (JST)
Subject: [ruby-changes:69714] c833ece5f7 (master): Rework implementation of `IO::Buffer.for(string)` to use string locking.
https://git.ruby-lang.org/ruby.git/commit/?id=c833ece5f7 From c833ece5f78b8c2e43263e08ccbd3ce1628bf610 Mon Sep 17 00:00:00 2001 From: Samuel Williams <samuel.williams@o...> Date: Fri, 22 Oct 2021 15:05:00 +1300 Subject: Rework implementation of `IO::Buffer.for(string)` to use string locking. --- io_buffer.c | 20 ++++++++++++++++++++ test/ruby/test_io_buffer.rb | 19 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/io_buffer.c b/io_buffer.c index 1acc942987f..9b8f85ed4cc 100644 --- a/io_buffer.c +++ b/io_buffer.c @@ -182,6 +182,10 @@ io_buffer_free(struct rb_io_buffer *data) https://github.com/ruby/ruby/blob/trunk/io_buffer.c#L182 io_buffer_unmap(data->base, data->size); } + if (RB_TYPE_P(data->source, T_STRING)) { + rb_str_unlocktmp(data->source); + } + data->base = NULL; #if defined(_WIN32) @@ -252,6 +256,21 @@ rb_io_buffer_type_allocate(VALUE self) https://github.com/ruby/ruby/blob/trunk/io_buffer.c#L256 return instance; } +VALUE +rb_io_buffer_type_for(VALUE klass, VALUE string) +{ + VALUE instance = rb_io_buffer_type_allocate(klass); + + struct rb_io_buffer *data = NULL; + TypedData_Get_Struct(instance, struct rb_io_buffer, &rb_io_buffer_type, data); + + rb_str_locktmp(string); + + io_buffer_initialize(data, RSTRING_PTR(string), RSTRING_LEN(string), RB_IO_BUFFER_EXTERNAL, string); + + return instance; +} + VALUE rb_io_buffer_new(void *base, size_t size, enum rb_io_buffer_flags flags) { @@ -1029,6 +1048,7 @@ Init_IO_Buffer(void) https://github.com/ruby/ruby/blob/trunk/io_buffer.c#L1048 rb_cIOBuffer = rb_define_class_under(rb_cIO, "Buffer", rb_cObject); rb_define_alloc_func(rb_cIOBuffer, rb_io_buffer_type_allocate); + rb_define_singleton_method(rb_cIOBuffer, "for", rb_io_buffer_type_for, 1); #ifdef _WIN32 SYSTEM_INFO info; diff --git a/test/ruby/test_io_buffer.rb b/test/ruby/test_io_buffer.rb index 1bd839e1632..12937729f4e 100644 --- a/test/ruby/test_io_buffer.rb +++ b/test/ruby/test_io_buffer.rb @@ -62,6 +62,25 @@ class TestIOBuffer < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_io_buffer.rb#L62 assert_include buffer.to_str, "Hello World" end + def test_string_mapped + string = "Hello World" + buffer = IO::Buffer.for(string) + + # Cannot modify string as it's locked by the buffer: + assert_raise RuntimeError do + string[0] = "h" + end + + buffer.set(:U8, 0, "h".ord) + + # Buffer releases it's ownership of the string: + buffer.free + + assert_equal "hello World", string + string[0] = "H" + assert_equal "Hello World", string + end + def test_resize buffer = IO::Buffer.new(1024, IO::Buffer::MAPPED) buffer.resize(2048, 0) -- cgit v1.2.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/