ruby-changes:66771
From: Sutou <ko1@a...>
Date: Tue, 13 Jul 2021 19:38:26 +0900 (JST)
Subject: [ruby-changes:66771] 10e26cfa76 (master): [ruby/fiddle] Add MemoryView.export and MemoryView#release (https://github.com/ruby/fiddle/pull/80)
https://git.ruby-lang.org/ruby.git/commit/?id=10e26cfa76 From 10e26cfa76468dea6f828dbe8031b5ffcff543cb Mon Sep 17 00:00:00 2001 From: Sutou Kouhei <kou@c...> Date: Thu, 17 Jun 2021 13:36:18 +0900 Subject: [ruby/fiddle] Add MemoryView.export and MemoryView#release (https://github.com/ruby/fiddle/pull/80) fix https://github.com/ruby/fiddle/pull/79 Users can release memory views explicitly before process exit. Reported by xtkoba. Thanks!!! https://github.com/ruby/fiddle/commit/1de64b7e76 --- ext/fiddle/memory_view.c | 42 ++++++++++++++++++++++++++++++++++++++--- test/fiddle/test_memory_view.rb | 16 ++++++++++++++++ 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/ext/fiddle/memory_view.c b/ext/fiddle/memory_view.c index 2a9f45f..fb3ab08 100644 --- a/ext/fiddle/memory_view.c +++ b/ext/fiddle/memory_view.c @@ -36,12 +36,25 @@ fiddle_memview_mark(void *ptr) https://github.com/ruby/ruby/blob/trunk/ext/fiddle/memory_view.c#L36 } static void -fiddle_memview_free(void *ptr) +fiddle_memview_release(struct memview_data *data) { - struct memview_data *data = ptr; + if (NIL_P(data->view.obj)) return; + rb_memory_view_release(&data->view); - if (data->members) + data->view.obj = Qnil; + data->view.byte_size = 0; + if (data->members) { xfree(data->members); + data->members = NULL; + data->n_members = 0; + } +} + +static void +fiddle_memview_free(void *ptr) +{ + struct memview_data *data = ptr; + fiddle_memview_release(data); xfree(ptr); } @@ -63,12 +76,33 @@ rb_fiddle_memview_s_allocate(VALUE klass) https://github.com/ruby/ruby/blob/trunk/ext/fiddle/memory_view.c#L76 struct memview_data *data; VALUE obj = TypedData_Make_Struct(klass, struct memview_data, &fiddle_memview_data_type, data); data->view.obj = Qnil; + data->view.byte_size = 0; data->members = NULL; data->n_members = 0; return obj; } static VALUE +rb_fiddle_memview_release(VALUE obj) +{ + struct memview_data *data; + TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data); + + if (NIL_P(data->view.obj)) return Qnil; + fiddle_memview_release(data); + return Qnil; +} + +static VALUE +rb_fiddle_memview_s_export(VALUE klass, VALUE target) +{ + ID id_new; + CONST_ID(id_new, "new"); + VALUE memview = rb_funcall(klass, id_new, 1, target); + return rb_ensure(rb_yield, memview, rb_fiddle_memview_release, memview); +} + +static VALUE rb_fiddle_memview_initialize(VALUE obj, VALUE target) { struct memview_data *data; @@ -269,7 +303,9 @@ Init_fiddle_memory_view(void) https://github.com/ruby/ruby/blob/trunk/ext/fiddle/memory_view.c#L303 { rb_cMemoryView = rb_define_class_under(mFiddle, "MemoryView", rb_cObject); rb_define_alloc_func(rb_cMemoryView, rb_fiddle_memview_s_allocate); + rb_define_singleton_method(rb_cMemoryView, "export", rb_fiddle_memview_s_export, 1); rb_define_method(rb_cMemoryView, "initialize", rb_fiddle_memview_initialize, 1); + rb_define_method(rb_cMemoryView, "release", rb_fiddle_memview_release, 0); rb_define_method(rb_cMemoryView, "obj", rb_fiddle_memview_get_obj, 0); rb_define_method(rb_cMemoryView, "byte_size", rb_fiddle_memview_get_byte_size, 0); rb_define_method(rb_cMemoryView, "readonly?", rb_fiddle_memview_get_readonly, 0); diff --git a/test/fiddle/test_memory_view.rb b/test/fiddle/test_memory_view.rb index 6777a04..8130823 100644 --- a/test/fiddle/test_memory_view.rb +++ b/test/fiddle/test_memory_view.rb @@ -114,6 +114,22 @@ module Fiddle https://github.com/ruby/ruby/blob/trunk/test/fiddle/test_memory_view.rb#L114 assert_equal([-7, -8], mview[1, 3]) end + def test_export + str = "hello world" + mview_str = MemoryView.export(Pointer[str]) do |mview| + mview.to_s + end + assert_equal(str, mview_str) + end + + def test_release + ptr = Pointer["hello world"] + mview = MemoryView.new(ptr) + assert_same(ptr, mview.obj) + mview.release + assert_nil(mview.obj) + end + def test_to_s # U+3042 HIRAGANA LETTER A data = "\u{3042}" -- cgit v1.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/