Skip to content

Commit 1de64b7

Browse files
authored
Add MemoryView.export and MemoryView#release (#80)
fix#79 Users can release memory views explicitly before process exit. Reported by xtkoba. Thanks!!!
1 parent 418f381 commit 1de64b7

2 files changed

Lines changed: 55 additions & 3 deletions

File tree

‎ext/fiddle/memory_view.c‎

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,25 @@ fiddle_memview_mark(void *ptr)
3636
}
3737

3838
staticvoid
39-
fiddle_memview_free(void*ptr)
39+
fiddle_memview_release(structmemview_data*data)
4040
{
41-
structmemview_data*data=ptr;
41+
if (NIL_P(data->view.obj)) return;
42+
4243
rb_memory_view_release(&data->view);
43-
if (data->members)
44+
data->view.obj=Qnil;
45+
data->view.byte_size=0;
46+
if (data->members) {
4447
xfree(data->members);
48+
data->members=NULL;
49+
data->n_members=0;
50+
}
51+
}
52+
53+
staticvoid
54+
fiddle_memview_free(void*ptr)
55+
{
56+
structmemview_data*data=ptr;
57+
fiddle_memview_release(data);
4558
xfree(ptr);
4659
}
4760

@@ -63,11 +76,32 @@ rb_fiddle_memview_s_allocate(VALUE klass)
6376
structmemview_data*data;
6477
VALUEobj=TypedData_Make_Struct(klass, structmemview_data, &fiddle_memview_data_type, data);
6578
data->view.obj=Qnil;
79+
data->view.byte_size=0;
6680
data->members=NULL;
6781
data->n_members=0;
6882
returnobj;
6983
}
7084

85+
staticVALUE
86+
rb_fiddle_memview_release(VALUEobj)
87+
{
88+
structmemview_data*data;
89+
TypedData_Get_Struct(obj, structmemview_data, &fiddle_memview_data_type, data);
90+
91+
if (NIL_P(data->view.obj)) returnQnil;
92+
fiddle_memview_release(data);
93+
returnQnil;
94+
}
95+
96+
staticVALUE
97+
rb_fiddle_memview_s_export(VALUEklass, VALUEtarget)
98+
{
99+
IDid_new;
100+
CONST_ID(id_new, "new");
101+
VALUEmemview=rb_funcall(klass, id_new, 1, target);
102+
returnrb_ensure(rb_yield, memview, rb_fiddle_memview_release, memview);
103+
}
104+
71105
staticVALUE
72106
rb_fiddle_memview_initialize(VALUEobj, VALUEtarget)
73107
{
@@ -269,7 +303,9 @@ Init_fiddle_memory_view(void)
269303
{
270304
rb_cMemoryView=rb_define_class_under(mFiddle, "MemoryView", rb_cObject);
271305
rb_define_alloc_func(rb_cMemoryView, rb_fiddle_memview_s_allocate);
306+
rb_define_singleton_method(rb_cMemoryView, "export", rb_fiddle_memview_s_export, 1);
272307
rb_define_method(rb_cMemoryView, "initialize", rb_fiddle_memview_initialize, 1);
308+
rb_define_method(rb_cMemoryView, "release", rb_fiddle_memview_release, 0);
273309
rb_define_method(rb_cMemoryView, "obj", rb_fiddle_memview_get_obj, 0);
274310
rb_define_method(rb_cMemoryView, "byte_size", rb_fiddle_memview_get_byte_size, 0);
275311
rb_define_method(rb_cMemoryView, "readonly?", rb_fiddle_memview_get_readonly, 0);

‎test/fiddle/test_memory_view.rb‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,22 @@ def test_memory_view_multi_dimensional_with_multiple_members
112112
assert_equal([-7, -8],mview[1,3])
113113
end
114114

115+
deftest_export
116+
str="hello world"
117+
mview_str=MemoryView.export(Pointer[str])do |mview|
118+
mview.to_s
119+
end
120+
assert_equal(str,mview_str)
121+
end
122+
123+
deftest_release
124+
ptr=Pointer["hello world"]
125+
mview=MemoryView.new(ptr)
126+
assert_same(ptr,mview.obj)
127+
mview.release
128+
assert_nil(mview.obj)
129+
end
130+
115131
deftest_to_s
116132
# U+3042 HIRAGANA LETTER A
117133
data="\u{3042}"

0 commit comments

Comments
 (0)