From 307388ea19f5c9d1c8c417d1979c40d970b420a2 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Sun, 2 Aug 2020 14:26:40 -0700 Subject: [ruby/fiddle] Add a "pinning" reference (#44) * Add a "pinning" reference A `Fiddle::Pinned` objects will prevent the objects they point to from moving. This is useful in the case where you need to pass a reference to a C extension that keeps the address in a global and needs the address to be stable. For example: ```ruby class Foo A = "hi" # this is an embedded string some_c_function A # A might move! end ``` If `A` moves, then the underlying string buffer may also move. `Fiddle::Pinned` will prevent the object from moving: ```ruby class Foo A = "hi" # this is an embedded string A_pinner = Fiddle::Pinned.new(A) # :nodoc: some_c_function A # A can't move because of `Fiddle::Pinned` end ``` This is a similar strategy to what Graal uses: https://www.graalvm.org/sdk/javadoc/org/graalvm/nativeimage/PinnedObject.html#getObject-- * rename global to match exception name * Introduce generic Fiddle::Error and rearrange error classes Fiddle::Error is the generic exception base class for Fiddle exceptions. This commit introduces the class and rearranges Fiddle exceptions to inherit from it. https://github.com/ruby/fiddle/commit/ac52d00223 --- test/fiddle/test_pinned.rb | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 test/fiddle/test_pinned.rb (limited to 'test/fiddle') diff --git a/test/fiddle/test_pinned.rb b/test/fiddle/test_pinned.rb new file mode 100644 index 0000000000..5bfae2172a --- /dev/null +++ b/test/fiddle/test_pinned.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true +begin + require_relative 'helper' +rescue LoadError +end + +module Fiddle + class TestPinned < Fiddle::TestCase + def test_pin_object + x = Object.new + pinner = Pinned.new x + assert_same x, pinner.ref + end + + def test_clear + pinner = Pinned.new Object.new + refute pinner.cleared? + pinner.clear + assert pinner.cleared? + ex = assert_raise(Fiddle::ClearedReferenceError) do + pinner.ref + end + assert_match "called on", ex.message + end + end +end + -- cgit v1.2.3