开发者

FFI blocks ruby thread and could not place FFI calls in any time out block

I have a SO file wrapped using FFI. I 开发者_如何学Goneed to time out a FFI call but unfortunately timeout was not happening in any of the popular methods as I mentioned in Timeout, System timeout & terminator not working for FFI based function. Is there some option to give a timeout for the call?

Thanks for your suggestions in advance.


I haven't tested this, but judging by the code in library.rb in the ffi repository, this should be a nicer alternative to the above:

require 'ffi'
module Sleep
  extend FFI::Library

  ffi_lib FFI::Library::LIBC

  attach_function :sleep, [:uint], :void, :blocking => true
end


The best solution is to use a ruby runtime that does not have a GIL (global interpreter lock) such as JRuby - it should handle interrupting blocked FFI calls correctly.

On other ruby runtimes, to make a native call interruptible, you need to mark the function as a 'blocking' function - FFI will unlock the GIL around calls to this function, and also set it up to be interrupted.

e.g.

require 'ffi'
module Sleep
  extend FFI::Library

  ffi_lib FFI::Library::LIBC

  # Tell FFI that this function may block
  @blocking = true
  attach_function :sleep, [:uint], :void
end

@blocking is not sticky - you need to set it before every 'attach_function' call that you want to mark as blocking.

And its not a 100% sure-fire solution. Interrupting a function which is blocked in native code will generally work for functions that are interruptible (e.g. sleep, read, write, etc), but won't for some native code (e.g. cpu intensive computations, possibly many other types as well).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜