[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]