From 255e617bc38f714c943c932e7df2b709313fd6bf Mon Sep 17 00:00:00 2001 From: Sutou Kouhei Date: Wed, 14 Sep 2022 12:59:13 +0900 Subject: [ruby/fiddle] Add Fiddle::Closure.create and Fiddle::Closure.free MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GitHub: fix GH-102 It's for freeing a closure explicitly. We can't use Fiddle::Closure before we fork the process. If we do it, the process may be crashed with SELinux. See https://github.com/ruby/fiddle/issues/102#issuecomment-1241763091 for details. Reported by Vít Ondruch. Thanks!!! https://github.com/ruby/fiddle/commit/a0ccc6bb1b --- ext/fiddle/lib/fiddle/closure.rb | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'ext/fiddle/lib') diff --git a/ext/fiddle/lib/fiddle/closure.rb b/ext/fiddle/lib/fiddle/closure.rb index c865a63c20..7e0077ea52 100644 --- a/ext/fiddle/lib/fiddle/closure.rb +++ b/ext/fiddle/lib/fiddle/closure.rb @@ -1,6 +1,31 @@ # frozen_string_literal: true module Fiddle class Closure + class << self + # Create a new closure. If a block is given, the created closure + # is automatically freed after the given block is executed. + # + # The all given arguments are passed to Fiddle::Closure.new. So + # using this method without block equals to Fiddle::Closure.new. + # + # == Example + # + # Fiddle::Closure.create(TYPE_INT, [TYPE_INT]) do |closure| + # # closure is freed automatically when this block is finished. + # end + def create(*args) + if block_given? + closure = new(*args) + begin + yield(closure) + ensure + closure.free + end + else + new(*args) + end + end + end # the C type of the return of the FFI closure attr_reader :ctype -- cgit v1.2.3