summaryrefslogtreecommitdiff
path: root/lib/ffi
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ffi')
-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
5 files changed, 32 insertions, 19 deletions
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}))