summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/ffi_c/DynamicLibrary.c7
-rw-r--r--ext/ffi_c/Function.c12
-rw-r--r--ext/ffi_c/FunctionInfo.c2
-rw-r--r--ext/ffi_c/MappedType.c2
-rw-r--r--ext/ffi_c/StructLayout.c7
-rw-r--r--ext/ffi_c/Type.c4
-rw-r--r--ext/ffi_c/Variadic.c5
-rw-r--r--ext/ffi_c/rbffi.h2
-rw-r--r--lib/ffi/library.rb36
-rw-r--r--lib/ffi/struct.rb2
-rw-r--r--lib/ffi/struct_layout.rb2
-rw-r--r--lib/ffi/struct_layout_builder.rb4
-rw-r--r--lib/ffi/variadic.rb7
-rw-r--r--spec/ffi/dynamic_library_spec.rb6
-rw-r--r--spec/ffi/enum_spec.rb24
-rw-r--r--spec/ffi/function_spec.rb2
-rw-r--r--spec/ffi/library_spec.rb57
-rw-r--r--spec/ffi/struct_by_ref_spec.rb2
-rw-r--r--spec/ffi/struct_spec.rb16
-rw-r--r--spec/ffi/type_spec.rb35
-rw-r--r--spec/ffi/variadic_spec.rb2
21 files changed, 175 insertions, 61 deletions
diff --git a/ext/ffi_c/DynamicLibrary.c b/ext/ffi_c/DynamicLibrary.c
index 9abafc7..1d83940 100644
--- a/ext/ffi_c/DynamicLibrary.c
+++ b/ext/ffi_c/DynamicLibrary.c
@@ -161,7 +161,9 @@ library_initialize(VALUE self, VALUE libname, VALUE libflags)
library->handle = RTLD_DEFAULT;
}
#endif
- rb_iv_set(self, "@name", libname != Qnil ? libname : rb_str_new2("[current process]"));
+ rb_iv_set(self, "@name", libname != Qnil ? rb_str_new_frozen(libname) : rb_str_new2("[current process]"));
+
+ rb_obj_freeze(self);
return self;
}
@@ -266,8 +268,9 @@ symbol_new(VALUE library, void* address, VALUE name)
sym->base.memory.typeSize = 1;
sym->base.memory.flags = MEM_RD | MEM_WR;
RB_OBJ_WRITE(obj, &sym->base.rbParent, library);
- RB_OBJ_WRITE(obj, &sym->name, name);
+ RB_OBJ_WRITE(obj, &sym->name, rb_str_new_frozen(name));
+ rb_obj_freeze(obj);
return obj;
}
diff --git a/ext/ffi_c/Function.c b/ext/ffi_c/Function.c
index 9da6b37..d0b65fb 100644
--- a/ext/ffi_c/Function.c
+++ b/ext/ffi_c/Function.c
@@ -492,7 +492,7 @@ static VALUE
function_attach(VALUE self, VALUE module, VALUE name)
{
Function* fn;
- char var[1024];
+ VALUE funcs;
StringValue(name);
TypedData_Get_Struct(self, Function, &function_data_type, fn);
@@ -514,9 +514,13 @@ function_attach(VALUE self, VALUE module, VALUE name)
/*
* Stash the Function in a module variable so it does not get garbage collected and can be inspected by attached_functions
*/
- snprintf(var, sizeof(var), "@ffi_function_%s", StringValueCStr(name));
- rb_ractor_make_shareable(self);
- rb_iv_set(module, var, self);
+
+ funcs = rb_iv_get(module, "@ffi_functions");
+ if (RB_NIL_P(funcs)) {
+ funcs = rb_hash_new();
+ rb_iv_set(module, "@ffi_functions", funcs);
+ }
+ rb_hash_aset(funcs, rb_str_intern(name), self);
rb_define_singleton_method(module, StringValueCStr(name),
rbffi_MethodHandle_CodeAddress(fn->methodHandle), -1);
diff --git a/ext/ffi_c/FunctionInfo.c b/ext/ffi_c/FunctionInfo.c
index 7495215..b5150d8 100644
--- a/ext/ffi_c/FunctionInfo.c
+++ b/ext/ffi_c/FunctionInfo.c
@@ -251,6 +251,8 @@ fntype_initialize(int argc, VALUE* argv, VALUE self)
fnInfo->invoke = rbffi_GetInvoker(fnInfo);
+ rb_obj_freeze(fnInfo->rbParameterTypes);
+ rb_obj_freeze(self);
return self;
}
diff --git a/ext/ffi_c/MappedType.c b/ext/ffi_c/MappedType.c
index 20b14e9..2e506f2 100644
--- a/ext/ffi_c/MappedType.c
+++ b/ext/ffi_c/MappedType.c
@@ -110,6 +110,8 @@ mapped_initialize(VALUE self, VALUE rbConverter)
TypedData_Get_Struct(m->rbType, Type, &rbffi_type_data_type, m->type);
m->base.ffiType = m->type->ffiType;
+ rb_obj_freeze(self);
+
return self;
}
diff --git a/ext/ffi_c/StructLayout.c b/ext/ffi_c/StructLayout.c
index 613394a..a56d48f 100644
--- a/ext/ffi_c/StructLayout.c
+++ b/ext/ffi_c/StructLayout.c
@@ -181,6 +181,8 @@ struct_field_initialize(int argc, VALUE* argv, VALUE self)
break;
}
+ rb_obj_freeze(self);
+
return self;
}
@@ -538,6 +540,11 @@ struct_layout_initialize(VALUE self, VALUE fields, VALUE size, VALUE align)
rb_raise(rb_eRuntimeError, "Struct size is zero");
}
+ rb_obj_freeze(layout->rbFieldMap);
+ rb_obj_freeze(layout->rbFields);
+ rb_obj_freeze(layout->rbFieldNames);
+ rb_obj_freeze(self);
+
return self;
}
diff --git a/ext/ffi_c/Type.c b/ext/ffi_c/Type.c
index 9bf5681..a94c009 100644
--- a/ext/ffi_c/Type.c
+++ b/ext/ffi_c/Type.c
@@ -128,6 +128,8 @@ type_initialize(VALUE self, VALUE value)
rb_raise(rb_eArgError, "wrong type");
}
+ rb_obj_freeze(self);
+
return self;
}
@@ -192,6 +194,8 @@ builtin_type_new(VALUE klass, int nativeType, ffi_type* ffiType, const char* nam
type->type.nativeType = nativeType;
type->type.ffiType = ffiType;
+ rb_obj_freeze(obj);
+
return obj;
}
diff --git a/ext/ffi_c/Variadic.c b/ext/ffi_c/Variadic.c
index 0f321d9..09d7ce8 100644
--- a/ext/ffi_c/Variadic.c
+++ b/ext/ffi_c/Variadic.c
@@ -183,9 +183,8 @@ variadic_initialize(VALUE self, VALUE rbFunction, VALUE rbParameterTypes, VALUE
/*
* @fixed and @type_map are used by the parameter mangling ruby code
*/
- rb_iv_set(self, "@fixed", fixed);
- rb_iv_set(self, "@type_map", rb_obj_dup(rb_hash_aref(options, ID2SYM(rb_intern("type_map")))));
- rb_ractor_make_shareable(self);
+ rb_iv_set(self, "@fixed", rb_obj_freeze(fixed));
+ rb_iv_set(self, "@type_map", rb_hash_aref(options, ID2SYM(rb_intern("type_map"))));
return retval;
}
diff --git a/ext/ffi_c/rbffi.h b/ext/ffi_c/rbffi.h
index 89b3e32..0e4e91a 100644
--- a/ext/ffi_c/rbffi.h
+++ b/ext/ffi_c/rbffi.h
@@ -39,7 +39,7 @@ extern "C" {
#define MAX_PARAMETERS (32)
extern VALUE rbffi_FFIModule;
-
+
extern void rbffi_Type_Init(VALUE ffiModule);
extern void rbffi_Buffer_Init(VALUE ffiModule);
extern void rbffi_Invoker_Init(VALUE ffiModule);
diff --git a/lib/ffi/library.rb b/lib/ffi/library.rb
index e681b3e..8af457d 100644
--- a/lib/ffi/library.rb
+++ b/lib/ffi/library.rb
@@ -295,9 +295,10 @@ module FFI
# If it is a global struct, just attach directly to the pointer
s = s = type.new(address) # Assigning twice to suppress unused variable warning
self.module_eval <<-code, __FILE__, __LINE__
- @ffi_gsvar_#{mname} = s
+ @ffi_gsvars = {} unless defined?(@ffi_gsvars)
+ @ffi_gsvars[#{mname.inspect}] = s
def self.#{mname}
- @ffi_gsvar_#{mname}
+ @ffi_gsvars[#{mname.inspect}]
end
code
@@ -309,12 +310,13 @@ module FFI
# Attach to this module as mname/mname=
#
self.module_eval <<-code, __FILE__, __LINE__
- @ffi_gvar_#{mname} = s
+ @ffi_gvars = {} unless defined?(@ffi_gvars)
+ @ffi_gvars[#{mname.inspect}] = s
def self.#{mname}
- @ffi_gvar_#{mname}[:gvar]
+ @ffi_gvars[#{mname.inspect}][:gvar]
end
def self.#{mname}=(value)
- @ffi_gvar_#{mname}[:gvar] = value
+ @ffi_gvars[#{mname.inspect}][:gvar] = value
end
code
@@ -541,20 +543,30 @@ module FFI
end
def attached_functions
- instance_variables.grep(/\A@ffi_function_(.*)/) do |m|
- [$1, instance_variable_get(m)]
- end.to_h
+ @ffi_functions || {}
end
def attached_variables
(
- instance_variables.grep(/\A@ffi_gsvar_(.*)/) do |m|
- [$1, instance_variable_get(m).class]
+ (@ffi_gsvars || {}).map do |name, gvar|
+ [name, gvar.class]
end +
- instance_variables.grep(/\A@ffi_gvar_(.*)/) do |m|
- [$1, instance_variable_get(m).layout[:gvar].type]
+ (@ffi_gvars || {}).map do |name, gvar|
+ [name, gvar.layout[:gvar].type]
end
).to_h
end
+
+ # Freeze all definitions of the module
+ #
+ # This freezes the module's definitions, so that it can be used in a Ractor.
+ # No further methods or variables can be attached and no further enums or typedefs can be created in this module afterwards.
+ def freeze
+ instance_variables.each do |name|
+ var = instance_variable_get(name)
+ FFI.make_shareable(var)
+ end
+ nil
+ end
end
end
diff --git a/lib/ffi/struct.rb b/lib/ffi/struct.rb
index 1283d63..725b9cb 100644
--- a/lib/ffi/struct.rb
+++ b/lib/ffi/struct.rb
@@ -219,7 +219,7 @@ module FFI
end
builder.size = @size if defined?(@size) && @size > builder.size
cspec = builder.build
- @layout = FFI.make_shareable(cspec) unless self == Struct
+ @layout = cspec unless self == Struct
@size = cspec.size
return cspec
end
diff --git a/lib/ffi/struct_layout.rb b/lib/ffi/struct_layout.rb
index d5a78a7..3fd68cb 100644
--- a/lib/ffi/struct_layout.rb
+++ b/lib/ffi/struct_layout.rb
@@ -80,8 +80,8 @@ module FFI
class Mapped < Field
def initialize(name, offset, type, orig_field)
- super(name, offset, type)
@orig_field = orig_field
+ super(name, offset, type)
end
def get(ptr)
diff --git a/lib/ffi/struct_layout_builder.rb b/lib/ffi/struct_layout_builder.rb
index 5488033..d7d26a2 100644
--- a/lib/ffi/struct_layout_builder.rb
+++ b/lib/ffi/struct_layout_builder.rb
@@ -97,7 +97,7 @@ module FFI
# List of number types
- NUMBER_TYPES = FFI.make_shareable([
+ NUMBER_TYPES = [
Type::INT8,
Type::UINT8,
Type::INT16,
@@ -112,7 +112,7 @@ module FFI
Type::FLOAT64,
Type::LONGDOUBLE,
Type::BOOL,
- ])
+ ].freeze
# @param [String, Symbol] name name of the field
# @param [Array, DataConverter, Struct, StructLayout::Field, Symbol, Type] type type of the field
diff --git a/lib/ffi/variadic.rb b/lib/ffi/variadic.rb
index 800d121..246b52f 100644
--- a/lib/ffi/variadic.rb
+++ b/lib/ffi/variadic.rb
@@ -54,11 +54,12 @@ module FFI
invoker = self
params = "*args"
call = "call"
- mod.module_eval <<-code
- @ffi_function_#{mname} = invoker
+ mod.module_eval <<-code, __FILE__, __LINE__
+ @ffi_functions = {} unless defined?(@ffi_functions)
+ @ffi_functions[#{mname.inspect}] = invoker
def self.#{mname}(#{params})
- @ffi_function_#{mname}.#{call}(#{params})
+ @ffi_functions[#{mname.inspect}].#{call}(#{params})
end
define_method(#{mname.inspect}, &method(:#{mname}))
diff --git a/spec/ffi/dynamic_library_spec.rb b/spec/ffi/dynamic_library_spec.rb
index a6ea2a9..088a822 100644
--- a/spec/ffi/dynamic_library_spec.rb
+++ b/spec/ffi/dynamic_library_spec.rb
@@ -9,7 +9,6 @@ describe FFI::DynamicLibrary do
it "should be shareable for Ractor", :ractor do
libtest = FFI::DynamicLibrary.open(TestLibrary::PATH,
FFI::DynamicLibrary::RTLD_LAZY | FFI::DynamicLibrary::RTLD_GLOBAL)
- Ractor.make_shareable(libtest)
res = Ractor.new(libtest) do |libtest2|
libtest2.find_symbol("testClosureVrV").address
@@ -52,5 +51,10 @@ describe FFI::DynamicLibrary do
size = ObjectSpace.memsize_of(symbol)
expect(size).to be > base_size
end
+
+ it "should be shareable for Ractor", :ractor do
+ symbol = @libtest.find_symbol("gvar_gstruct_set")
+ expect(Ractor.shareable?(symbol)).to be true
+ end
end
end
diff --git a/spec/ffi/enum_spec.rb b/spec/ffi/enum_spec.rb
index 1fba2cb..7a55b07 100644
--- a/spec/ffi/enum_spec.rb
+++ b/spec/ffi/enum_spec.rb
@@ -26,14 +26,18 @@ module TestEnum3
ffi_lib TestLibrary::PATH
enum :enum_type1, [:c1, :c2, :c3, :c4]
- enum :enum_type2, [:c5, 42, :c6, :c7, :c8]
- enum :enum_type3, [:c9, 42, :c10, :c11, 4242, :c12]
- enum :enum_type4, [:c13, 42, :c14, 4242, :c15, 424242, :c16, 42424242]
-
attach_function :test_tagged_typedef_enum1, [:enum_type1], :enum_type1
+
+ enum :enum_type2, [:c5, 42, :c6, :c7, :c8]
attach_function :test_tagged_typedef_enum2, [:enum_type2], :enum_type2
+
+ enum :enum_type3, [:c9, 42, :c10, :c11, 4242, :c12]
attach_function :test_tagged_typedef_enum3, [:enum_type3], :enum_type3
+
+ enum :enum_type4, [:c13, 42, :c14, 4242, :c15, 424242, :c16, 42424242]
attach_function :test_tagged_typedef_enum4, [:enum_type4], :enum_type4
+
+ freeze
end
module TestEnum4
@@ -44,18 +48,22 @@ module TestEnum4
enum :enum_type1, [:c5, 0x42, :c6, :c7, :c8]
enum :enum_type2, [:c9, 0x42, :c10, :c11, 0x4242, :c12]
enum :enum_type3, [:c13, 0x42, :c14, 0x4242, :c15, 0x42424242, :c16, 0x4242424242424242]
- enum FFI::Type::UINT16, :enum_type4, [:c17, 0x42, :c18, :c19, :c20]
- enum FFI::Type::UINT32, :enum_type5, [:c21, 0x42, :c22, :c23, 0x4242, :c24]
- enum FFI::Type::UINT64, :enum_type6, [:c25, 0x42, :c26, 0x4242, :c27, 0x42424242, :c28, 0x4242424242424242]
- enum FFI::Type::UINT64, [:c29, 0x4242424242424242, :c30, :c31, :c32]
attach_function :test_untagged_nonint_enum, [:uint8], :uint8
attach_function :test_tagged_nonint_enum1, [:uint16], :uint16
attach_function :test_tagged_nonint_enum2, [:uint32], :uint32
attach_function :test_tagged_nonint_enum3, [:uint64], :uint64
+
+ enum FFI::Type::UINT16, :enum_type4, [:c17, 0x42, :c18, :c19, :c20]
+ enum FFI::Type::UINT32, :enum_type5, [:c21, 0x42, :c22, :c23, 0x4242, :c24]
+ enum FFI::Type::UINT64, :enum_type6, [:c25, 0x42, :c26, 0x4242, :c27, 0x42424242, :c28, 0x4242424242424242]
+ enum FFI::Type::UINT64, [:c29, 0x4242424242424242, :c30, :c31, :c32]
+
attach_function :test_tagged_nonint_enum4, :test_tagged_nonint_enum1, [:enum_type4], :enum_type4
attach_function :test_tagged_nonint_enum5, :test_tagged_nonint_enum2, [:enum_type5], :enum_type5
attach_function :test_tagged_nonint_enum6, :test_tagged_nonint_enum3, [:enum_type6], :enum_type6
+
+ freeze
end
describe "A library with no enum defined" do
diff --git a/spec/ffi/function_spec.rb b/spec/ffi/function_spec.rb
index badd240..77d09d8 100644
--- a/spec/ffi/function_spec.rb
+++ b/spec/ffi/function_spec.rb
@@ -52,7 +52,7 @@ describe FFI::Function do
a + b
end
- it "should be shareable for Ractor", :ractor do
+ it "can be made shareable for Ractor", :ractor do
add = FFI::Function.new(:int, [:int, :int], &method(:adder))
Ractor.make_shareable(add)
diff --git a/spec/ffi/library_spec.rb b/spec/ffi/library_spec.rb
index 52a961f..1b8e8c1 100644
--- a/spec/ffi/library_spec.rb
+++ b/spec/ffi/library_spec.rb
@@ -8,6 +8,7 @@ require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
module TestEnumValueRactor
extend FFI::Library
enum :something, [:one, :two]
+ freeze
end
describe "Library" do
@@ -197,28 +198,46 @@ describe "Library" do
end.getpid).to eq(Process.pid)
}.to raise_error(LoadError)
end
+ end
- it "attach_function :bool_return_true from [ File.expand_path(#{TestLibrary::PATH.inspect}) ]" do
- mod = Module.new do |m|
- m.extend FFI::Library
- ffi_lib File.expand_path(TestLibrary::PATH)
- attach_function :bool_return_true, [ ], :bool
- end
- expect(mod.bool_return_true).to be true
+ it "attach_function :bool_return_true from [ File.expand_path(#{TestLibrary::PATH.inspect}) ]" do
+ mod = Module.new do |m|
+ m.extend FFI::Library
+ ffi_lib File.expand_path(TestLibrary::PATH)
+ attach_function :bool_return_true, [ ], :bool
end
+ expect(mod.bool_return_true).to be true
+ end
- it "can reveal the function type" do
- mod = Module.new do |m|
- m.extend FFI::Library
- ffi_lib File.expand_path(TestLibrary::PATH)
- attach_function :bool_return_true, [ :string ], :bool
- end
+ it "can define a foo! function" do
+ mod = Module.new do |m|
+ m.extend FFI::Library
+ ffi_lib File.expand_path(TestLibrary::PATH)
+ attach_function :foo!, :bool_return_true, [], :bool
+ end
+ expect(mod.foo!).to be true
+ end
+
+ it "can define a foo? function" do
+ mod = Module.new do |m|
+ m.extend FFI::Library
+ ffi_lib File.expand_path(TestLibrary::PATH)
+ attach_function :foo?, :bool_return_true, [], :bool
+ end
+ expect(mod.foo?).to be true
+ end
- fun = mod.attached_functions
- expect(fun.keys).to eq(["bool_return_true"])
- expect(fun["bool_return_true"].param_types).to eq([FFI::Type::STRING])
- expect(fun["bool_return_true"].return_type).to eq(FFI::Type::BOOL)
+ it "can reveal the function type" do
+ mod = Module.new do |m|
+ m.extend FFI::Library
+ ffi_lib File.expand_path(TestLibrary::PATH)
+ attach_function :bool_return_true, [ :string ], :bool
end
+
+ fun = mod.attached_functions
+ expect(fun.keys).to eq([:bool_return_true])
+ expect(fun[:bool_return_true].param_types).to eq([FFI::Type::STRING])
+ expect(fun[:bool_return_true].return_type).to eq(FFI::Type::BOOL)
end
def gvar_lib(name, type)
@@ -355,7 +374,7 @@ describe "Library" do
ffi_lib TestLibrary::PATH
attach_variable :gvari, "gvar_gstruct", GlobalStruct
end
- expect(lib.attached_variables).to eq({ "gvari" => GlobalStruct })
+ expect(lib.attached_variables).to eq({ gvari: GlobalStruct })
end
it "can reveal its attached global variables" do
@@ -364,7 +383,7 @@ describe "Library" do
ffi_lib TestLibrary::PATH
attach_variable :gvaro, "gvar_u32", :uint32
end
- expect(lib.attached_variables).to eq({ "gvaro" => FFI::Type::UINT32 })
+ expect(lib.attached_variables).to eq({ gvaro: FFI::Type::UINT32 })
end
it "should have shareable constants for Ractor", :ractor do
diff --git a/spec/ffi/struct_by_ref_spec.rb b/spec/ffi/struct_by_ref_spec.rb
index 0c01137..f664937 100644
--- a/spec/ffi/struct_by_ref_spec.rb
+++ b/spec/ffi/struct_by_ref_spec.rb
@@ -41,7 +41,7 @@ describe FFI::Struct, ' by_ref' do
end
it "can reveal the mapped type converter" do
- param_type = @api.attached_functions["struct_test"].param_types[0]
+ param_type = @api.attached_functions[:struct_test].param_types[0]
expect(param_type).to be_a(FFI::Type::Mapped)
expect(param_type.converter).to be_a(FFI::StructByReference)
end
diff --git a/spec/ffi/struct_spec.rb b/spec/ffi/struct_spec.rb
index d09b7b6..ab62da1 100644
--- a/spec/ffi/struct_spec.rb
+++ b/spec/ffi/struct_spec.rb
@@ -545,7 +545,7 @@ module StructSpecsStructTests
expect(b.members).to eq([:a, :b])
end
- it "should be shareable for Ractor", :ractor do
+ it "can be made shareable for Ractor", :ractor do
a = Class.new(FFI::Struct) do
layout :a, :char
end.new
@@ -1109,6 +1109,20 @@ describe "Struct memsize functions", skip: RUBY_ENGINE != "ruby" do
size = ObjectSpace.memsize_of(layout[:pointer])
expect(size).to be > base_size
end
+
+ it "StructLayout should be shareable with Ractor", :ractor do
+ kl = Class.new(FFI::Struct) do
+ layout :ptr, :pointer
+ end
+ expect(Ractor.shareable?(kl.layout)).to eq(true)
+ end
+
+ it "StructField should be shareable with Ractor", :ractor do
+ kl = Class.new(FFI::Struct) do
+ layout :ptr, :pointer
+ end
+ expect(Ractor.shareable?(kl.layout[:ptr])).to eq(true)
+ end
end
diff --git a/spec/ffi/type_spec.rb b/spec/ffi/type_spec.rb
index eb48a43..e880c83 100644
--- a/spec/ffi/type_spec.rb
+++ b/spec/ffi/type_spec.rb
@@ -5,7 +5,7 @@
require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
-describe "FFI::Type" do
+describe FFI::Type do
it 'has a memsize function', skip: RUBY_ENGINE != "ruby" do
base_size = ObjectSpace.memsize_of(Object.new)
@@ -40,4 +40,37 @@ describe "FFI::Type" do
size = ObjectSpace.memsize_of(FFI::Type::Builtin::CHAR)
expect(size).to be > base_size
end
+
+ it "should be shareable with Ractor", :ractor do
+ expect(Ractor.shareable?(FFI::Type.new(5))).to eq(true)
+ end
+
+ describe :Builtin do
+ it "should be shareable with Ractor", :ractor do
+ expect(Ractor.shareable?(FFI::Type::INT32)).to eq(true)
+ end
+ end
+
+ describe :Mapped do
+ it "should be shareable with Ractor", :ractor do
+ converter = Module.new do
+ extend FFI::DataConverter
+
+ def self.native_type
+ FFI::Type::INT32
+ end
+
+ def self.to_native(val, ctx)
+ ToNativeMap[val]
+ end
+
+ def self.from_native(val, ctx)
+ FromNativeMap[val]
+ end
+ end
+ expect(Ractor.shareable?(converter)).to eq(true)
+ type = FFI::Type::Mapped.new(converter)
+ expect(Ractor.shareable?(type)).to eq(true)
+ end
+ end
end
diff --git a/spec/ffi/variadic_spec.rb b/spec/ffi/variadic_spec.rb
index 917212a..21a803f 100644
--- a/spec/ffi/variadic_spec.rb
+++ b/spec/ffi/variadic_spec.rb
@@ -23,6 +23,8 @@ describe "Function with variadic arguments" do
attach_function :testBlockingClose, [ :pointer ], :void
attach_function :testCallbackVrDva, :testClosureVrDva, [ :double, :varargs ], :double
attach_function :testCallbackVrILva, :testClosureVrILva, [ :int, :long, :varargs ], :long
+
+ freeze
end
it "takes enum arguments" do