[ruby/fiddle] Ractor support

(https://github.com/ruby/fiddle/pull/139)

https://github.com/ruby/fiddle/commit/91d0ea9849

Co-authored-by: Sutou Kouhei <kou@clear-code.com>
This commit is contained in:
Nobuyoshi Nakada 2024-10-11 14:59:09 +09:00 committed by Hiroshi SHIBATA
parent a0ecdbfbfe
commit bbd5b8ddae
No known key found for this signature in database
GPG Key ID: F9CF13417264FAC2
15 changed files with 89 additions and 10 deletions

View File

@ -61,7 +61,7 @@ const rb_data_type_t closure_data_type = {
.dfree = dealloc,
.dsize = closure_memsize
},
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
.flags = FIDDLE_DEFAULT_TYPED_DATA_FLAGS,
};
struct callback_args {
@ -300,6 +300,7 @@ initialize_body(VALUE user_data)
cl->argv[i] = rb_fiddle_int_to_ffi_type(NUM2INT(arg));
}
cl->argv[argc] = NULL;
OBJ_FREEZE_RAW(normalized_args);
ret = rb_fiddle_type_ensure(ret);
rb_iv_set(data->self, "@ctype", ret);

View File

@ -223,6 +223,8 @@ if libffi
$LOCAL_LIBS.prepend("#{libffi.a} ").strip! # to exts.mk
$INCFLAGS.gsub!(/-I#{libffi.dir}/, '-I$(LIBFFI_DIR)')
end
have_func("rb_str_to_interned_str")
create_makefile 'fiddle' do |conf|
if !libffi
next conf << "LIBFFI_CLEAN = none\n"

View File

@ -236,4 +236,14 @@ VALUE rb_fiddle_new_function(VALUE address, VALUE arg_types, VALUE ret_type);
typedef void (*rb_fiddle_freefunc_t)(void*);
VALUE rb_fiddle_ptr_new_wrap(void *ptr, long size, rb_fiddle_freefunc_t func, VALUE wrap0, VALUE wrap1);
enum {
FIDDLE_DEFAULT_TYPED_DATA_FLAGS = (
RUBY_TYPED_FREE_IMMEDIATELY |
RUBY_TYPED_WB_PROTECTED |
#ifdef RUBY_TYPED_FROZEN_SHAREABLE
RUBY_TYPED_FROZEN_SHAREABLE |
#endif
0)
};
#endif

View File

@ -59,7 +59,7 @@ const rb_data_type_t function_data_type = {
.dfree = deallocate,
.dsize = function_memsize
},
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
.flags = FIDDLE_DEFAULT_TYPED_DATA_FLAGS,
};
static VALUE
@ -153,6 +153,9 @@ initialize(int argc, VALUE argv[], VALUE self)
rb_get_kwargs(kwargs, kw, 0, kw_max_, args);
if (args[kw_name] != Qundef) {
name = args[kw_name];
#ifdef HAVE_RB_STR_TO_INTERNED_STR
name = rb_str_to_interned_str(name);
#endif
}
if (args[kw_need_gvl] != Qundef) {
need_gvl = args[kw_need_gvl];

View File

@ -56,7 +56,8 @@ static const rb_data_type_t fiddle_handle_data_type = {
.dfree = fiddle_handle_free,
.dsize = fiddle_handle_memsize
},
.flags = RUBY_TYPED_WB_PROTECTED,
.flags = FIDDLE_DEFAULT_TYPED_DATA_FLAGS & ~RUBY_TYPED_FREE_IMMEDIATELY,
/* keeping while its symbols are referred. */
};
/*

View File

@ -64,8 +64,13 @@ fiddle_memview_memsize(const void *ptr)
}
static const rb_data_type_t fiddle_memview_data_type = {
"fiddle/memory_view",
{fiddle_memview_mark, fiddle_memview_free, fiddle_memview_memsize,},
.wrap_struct_name = "fiddle/memory_view",
.function = {
.dmark = fiddle_memview_mark,
.dfree = fiddle_memview_free,
.dsize = fiddle_memview_memsize,
},
.flags = FIDDLE_DEFAULT_TYPED_DATA_FLAGS,
};
static VALUE

View File

@ -24,9 +24,13 @@ pinned_memsize(const void *ptr)
}
static const rb_data_type_t pinned_data_type = {
"fiddle/pinned",
{pinned_mark, xfree, pinned_memsize, },
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
.wrap_struct_name = "fiddle/pinned",
.function = {
.dmark = pinned_mark,
.dfree = RUBY_TYPED_DEFAULT_FREE,
.dsize = pinned_memsize,
},
.flags = FIDDLE_DEFAULT_TYPED_DATA_FLAGS,
};
static VALUE

View File

@ -94,7 +94,7 @@ static const rb_data_type_t fiddle_ptr_data_type = {
.dfree = fiddle_ptr_free,
.dsize = fiddle_ptr_memsize,
},
.flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
.flags = FIDDLE_DEFAULT_TYPED_DATA_FLAGS,
};
#ifdef HAVE_RUBY_MEMORY_VIEW_H

View File

@ -189,5 +189,10 @@ module Fiddle
ensure
GC.stress = stress
end
def assert_ractor_shareable(object)
Ractor.make_shareable(object)
assert_operator(Ractor, :shareable?, object)
end
end
end

View File

@ -152,5 +152,17 @@ module Fiddle
end
end
end
def test_ractor_shareable
omit("Need Ractor") unless defined?(Ractor)
closure_class = Class.new(Closure) do
def call
0
end
end
closure_class.create(:int, [:void]) do |c|
assert_ractor_shareable(c)
end
end
end
end if defined?(Fiddle)

View File

@ -253,6 +253,11 @@ module Fiddle
end
end
def test_ractor_shareable
omit("Need Ractor") unless defined?(Ractor)
assert_ractor_shareable(Function.new(@libm['sin'], [TYPE_DOUBLE], TYPE_DOUBLE))
end
private
def perror(m)

View File

@ -226,5 +226,10 @@ module Fiddle
assert_equal(ansi, k["GetFileAttributes"], "should fallback to ANSI version")
end
end
def test_ractor_shareable
omit("Need Ractor") unless defined?(Ractor)
assert_ractor_shareable(Fiddle::Handle.new(LIBC_SO))
end
end
end if defined?(Fiddle)

View File

@ -159,5 +159,17 @@ module Fiddle
mview.release
end
end
def test_ractor_shareable
omit("Need Ractor") unless defined?(Ractor)
ptr = Pointer["hello world"]
mview = MemoryView.new(ptr)
begin
assert_ractor_shareable(mview)
assert_predicate(ptr, :frozen?)
ensure
mview.release
end
end
end
end

View File

@ -23,6 +23,12 @@ module Fiddle
end
assert_match "called on", ex.message
end
def test_ractor_shareable
omit("Need Ractor") unless defined?(Ractor)
obj = Object.new
assert_ractor_shareable(Pinned.new(obj))
assert_predicate(obj, :frozen?)
end
end
end

View File

@ -305,5 +305,13 @@ module Fiddle
assert_raise(DLError) {nullpo[0]}
assert_raise(DLError) {nullpo[0] = 1}
end
def test_ractor_shareable
omit("Need Ractor") unless defined?(Ractor)
assert_ractor_shareable(Fiddle::NULL)
ary = [0, 1, 2, 4, 5]
addr = Pointer.new(dlwrap(ary))
assert_ractor_shareable(addr)
end
end
end if defined?(Fiddle)