mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
[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!!!
1de64b7e76
This commit is contained in:
parent
9988f6ac4e
commit
10e26cfa76
2 changed files with 55 additions and 3 deletions
|
@ -35,13 +35,26 @@ fiddle_memview_mark(void *ptr)
|
|||
rb_gc_mark(data->view.obj);
|
||||
}
|
||||
|
||||
static void
|
||||
fiddle_memview_release(struct memview_data *data)
|
||||
{
|
||||
if (NIL_P(data->view.obj)) return;
|
||||
|
||||
rb_memory_view_release(&data->view);
|
||||
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;
|
||||
rb_memory_view_release(&data->view);
|
||||
if (data->members)
|
||||
xfree(data->members);
|
||||
fiddle_memview_release(data);
|
||||
xfree(ptr);
|
||||
}
|
||||
|
||||
|
@ -63,11 +76,32 @@ rb_fiddle_memview_s_allocate(VALUE klass)
|
|||
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)
|
||||
{
|
||||
|
@ -269,7 +303,9 @@ Init_fiddle_memory_view(void)
|
|||
{
|
||||
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);
|
||||
|
|
|
@ -114,6 +114,22 @@ module Fiddle
|
|||
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}"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue