ffi 1.10.0 → 1.11.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/.gitmodules +2 -1
- data/.travis.yml +17 -18
- data/CHANGELOG.md +33 -0
- data/Gemfile +1 -1
- data/README.md +20 -17
- data/Rakefile +10 -83
- data/appveyor.yml +6 -1
- data/ext/ffi_c/Call.c +16 -33
- data/ext/ffi_c/Call.h +2 -5
- data/ext/ffi_c/Function.c +24 -108
- data/ext/ffi_c/Platform.c +0 -47
- data/ext/ffi_c/Thread.c +6 -222
- data/ext/ffi_c/Thread.h +2 -13
- data/ext/ffi_c/Type.c +0 -18
- data/ext/ffi_c/Type.h +0 -1
- data/ext/ffi_c/Variadic.c +9 -15
- data/ext/ffi_c/extconf.rb +34 -20
- data/ext/ffi_c/ffi.c +3 -8
- data/ext/ffi_c/libffi/configure.ac +5 -1
- data/ext/ffi_c/libffi/include/ffi_common.h +1 -1
- data/ext/ffi_c/libffi/src/aarch64/ffi.c +2 -2
- data/ext/ffi_c/libffi/src/frv/ffi.c +1 -1
- data/ext/ffi_c/libffi/src/metag/ffi.c +1 -1
- data/ext/ffi_c/libffi/src/moxie/ffi.c +1 -1
- data/ext/ffi_c/libffi/src/riscv/ffi.c +42 -6
- data/ext/ffi_c/libffi/src/riscv/ffitarget.h +1 -0
- data/ext/ffi_c/libffi/src/riscv/sysv.S +86 -7
- data/ext/ffi_c/libffi/src/x86/ffi.c +2 -1
- data/ext/ffi_c/libffi/src/x86/ffiw64.c +1 -1
- data/ext/ffi_c/libffi/src/x86/sysv.S +88 -2
- data/ext/ffi_c/libffi/src/x86/unix64.S +41 -0
- data/ext/ffi_c/rbffi.h +0 -2
- data/ffi.gemspec +11 -4
- data/lib/ffi/data_converter.rb +67 -0
- data/lib/ffi/ffi.rb +1 -0
- data/lib/ffi/platform.rb +2 -0
- data/lib/ffi/pointer.rb +1 -1
- data/lib/ffi/struct.rb +3 -63
- data/lib/ffi/struct_by_reference.rb +72 -0
- data/lib/ffi/struct_layout.rb +96 -0
- data/lib/ffi/tools/const_generator.rb +5 -4
- data/lib/ffi/tools/generator.rb +47 -2
- data/lib/ffi/tools/generator_task.rb +13 -17
- data/lib/ffi/tools/struct_generator.rb +4 -4
- data/lib/ffi/types.rb +1 -1
- data/lib/ffi/version.rb +1 -1
- metadata +18 -13
- data/ext/ffi_c/DataConverter.c +0 -91
- data/ext/ffi_c/StructByReference.c +0 -190
- data/ext/ffi_c/StructByReference.h +0 -50
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 041f37e7f1d2ed3857caabe7c68a68d3d8a9b403c5d03e8df59d0277a48f17e2
|
4
|
+
data.tar.gz: 4c9bcdce1d0ba85318109bb074a0e19c87f5c004440a491d5f532ac2ec20b82c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4ae610d83039e9edc3ce4fe3708319cc4c1fc0d8d6dbddc96b4f4b51eec5875fb9052adfce7620664707a73696f3d17c4c1c956037ac252e1924a36fde57ad4c
|
7
|
+
data.tar.gz: 3a745c80a61c816826ded2c3e29eb13746e1686edcd14f98d06d012d31352b7eaf30e15d9517e662a80beb65f48e1af6e0bceddbf23346d3268ccf6d6ea820ea
|
data/.gitignore
CHANGED
data/.gitmodules
CHANGED
data/.travis.yml
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
dist: trusty
|
2
|
-
sudo: false
|
3
2
|
group: beta
|
4
3
|
language: ruby
|
5
|
-
|
6
|
-
- gem install bundler
|
4
|
+
|
7
5
|
script:
|
8
6
|
- bundle exec rake compile || bundle exec rake compile
|
9
7
|
- bundle exec rake test
|
8
|
+
- ITER=10 bundle exec rake bench:all
|
10
9
|
os:
|
11
10
|
- linux
|
12
11
|
- osx
|
@@ -16,28 +15,28 @@ rvm:
|
|
16
15
|
- 2.5.3
|
17
16
|
- 2.6.0
|
18
17
|
- ruby-head
|
19
|
-
|
18
|
+
|
20
19
|
env:
|
21
20
|
- CC=gcc
|
22
21
|
- CC=clang
|
23
22
|
matrix:
|
24
23
|
allow_failures:
|
25
|
-
- rvm: system
|
26
24
|
- os: osx
|
27
25
|
rvm: ruby-head
|
28
|
-
exclude: # ruby 2.4.2 needs build with xcode9 or later on osx
|
29
|
-
- os: osx
|
30
|
-
rvm: 2.4.2
|
31
26
|
include:
|
32
|
-
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
27
|
+
- name: powerpc
|
28
|
+
language: generic
|
29
|
+
before_install: |
|
30
|
+
docker run --rm --privileged multiarch/qemu-user-static:register --reset &&
|
31
|
+
docker build --rm -t ffi-powerpc -f spec/env/Dockerfile.powerpc .
|
32
|
+
script: |
|
33
|
+
docker run --rm -t -v `pwd`:/ffi ffi-powerpc
|
34
|
+
- name: armhf
|
35
|
+
language: generic
|
36
|
+
before_install: |
|
37
|
+
docker run --rm --privileged multiarch/qemu-user-static:register --reset &&
|
38
|
+
docker build --rm -t ffi-armhf -f spec/env/Dockerfile.armhf .
|
39
|
+
script: |
|
40
|
+
docker run --rm -t -v `pwd`:/ffi ffi-armhf
|
42
41
|
after_failure:
|
43
42
|
- "find build -name mkmf.log | xargs cat"
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,36 @@
|
|
1
|
+
1.11.1 / 2019-05-20
|
2
|
+
-------------------
|
3
|
+
|
4
|
+
Changed:
|
5
|
+
* Raise required ruby version to >=2.0. #699, #700
|
6
|
+
* Fix a possible linker error on ruby < 2.3 on Linux.
|
7
|
+
|
8
|
+
|
9
|
+
1.11.0 / 2019-05-17
|
10
|
+
-------------------
|
11
|
+
|
12
|
+
Added:
|
13
|
+
* Add ability to disable or force use of system libffi. #669
|
14
|
+
Use like `gem inst ffi -- --enable-system-libffi` .
|
15
|
+
* Add ability to call FFI callbacks from outside of FFI call frame. #584
|
16
|
+
* Add proper documentation to FFI::Generator and ::Task
|
17
|
+
* Add gemspec metadata. #696, #698
|
18
|
+
|
19
|
+
Changed:
|
20
|
+
* Fix stdcall on Win32. #649, #669
|
21
|
+
* Fix load paths for FFI::Generator::Task
|
22
|
+
* Fix FFI::Pointer#read_string(0) to return a binary String. #692
|
23
|
+
* Fix benchmark suite so that it runs on ruby-2.x
|
24
|
+
* Move FFI::Platform::CPU from C to Ruby. #663
|
25
|
+
* Move FFI::StructByReference to Ruby. #681
|
26
|
+
* Move FFI::DataConverter to Ruby (#661)
|
27
|
+
* Various cleanups and improvements of specs and benchmarks
|
28
|
+
|
29
|
+
Removed:
|
30
|
+
* Remove ruby-1.8 and 1.9 compatibility code. #683
|
31
|
+
* Remove unused spec files. #684
|
32
|
+
|
33
|
+
|
1
34
|
1.10.0 / 2019-01-06
|
2
35
|
-------------------
|
3
36
|
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,19 +1,19 @@
|
|
1
|
-
#
|
1
|
+
# Ruby-FFI https://github.com/ffi/ffi/wiki [![Build Status](https://travis-ci.org/ffi/ffi.svg?branch=master)](https://travis-ci.org/ffi/ffi) [![Build status Windows](https://ci.appveyor.com/api/projects/status/r8wxn1sd4s794gg1/branch/master?svg=true)](https://ci.appveyor.com/project/larskanis/ffi-aofqa/branch/master)
|
2
2
|
|
3
3
|
## Description
|
4
4
|
|
5
|
-
Ruby-FFI is a
|
5
|
+
Ruby-FFI is a gem for programmatically loading dynamically-linked native
|
6
6
|
libraries, binding functions within them, and calling those functions
|
7
7
|
from Ruby code. Moreover, a Ruby-FFI extension works without changes
|
8
|
-
on
|
9
|
-
using Ruby-FFI](https://
|
8
|
+
on CRuby (MRI), JRuby, Rubinius and TruffleRuby. [Discover why you should write your next extension
|
9
|
+
using Ruby-FFI](https://github.com/ffi/ffi/wiki/why-use-ffi).
|
10
10
|
|
11
|
-
## Features
|
11
|
+
## Features
|
12
12
|
|
13
13
|
* Intuitive DSL
|
14
14
|
* Supports all C native types
|
15
15
|
* C structs (also nested), enums and global variables
|
16
|
-
* Callbacks from C to
|
16
|
+
* Callbacks from C to Ruby
|
17
17
|
* Automatic garbage collection of native memory
|
18
18
|
|
19
19
|
## Synopsis
|
@@ -30,20 +30,23 @@ end
|
|
30
30
|
MyLib.puts 'Hello, World using libc!'
|
31
31
|
```
|
32
32
|
|
33
|
-
For less minimalistic and more
|
33
|
+
For less minimalistic and more examples you may look at:
|
34
34
|
|
35
|
-
* the samples
|
36
|
-
* the examples on the [wiki](https://
|
37
|
-
* the projects using FFI listed on
|
35
|
+
* the `samples/` folder
|
36
|
+
* the examples on the [wiki](https://github.com/ffi/ffi/wiki)
|
37
|
+
* the projects using FFI listed on the wiki: https://github.com/ffi/ffi/wiki/projects-using-ffi
|
38
38
|
|
39
39
|
## Requirements
|
40
40
|
|
41
|
-
|
42
|
-
|
43
|
-
*
|
44
|
-
* libffi development library - this is commonly in the libffi-dev or libffi-devel
|
41
|
+
When installing the gem on CRuby (MRI) or Rubinius, you will need:
|
42
|
+
* A C compiler (e.g., Xcode on macOS, `gcc` or `clang` on everything else)
|
43
|
+
* The `libffi` library and development headers - this is commonly in the `libffi-dev` or `libffi-devel` packages
|
45
44
|
|
46
|
-
On Linux systems running with [PaX](https://en.wikipedia.org/wiki/PaX) (Gentoo, Alpine, etc.) FFI may trigger `mprotect` errors. You may need to disable [mprotect](https://en.wikibooks.org/wiki/Grsecurity/Appendix/Grsecurity_and_PaX_Configuration_Options#Restrict_mprotect.28.29) for ruby (`paxctl -m [/path/to/ruby]`) for the time being until a solution is found.
|
45
|
+
On Linux systems running with [PaX](https://en.wikipedia.org/wiki/PaX) (Gentoo, Alpine, etc.), FFI may trigger `mprotect` errors. You may need to disable [mprotect](https://en.wikibooks.org/wiki/Grsecurity/Appendix/Grsecurity_and_PaX_Configuration_Options#Restrict_mprotect.28.29) for ruby (`paxctl -m [/path/to/ruby]`) for the time being until a solution is found.
|
46
|
+
|
47
|
+
On FreeBSD systems pkgconf must be installed for the gem to be able to compile using clang. Install either via packages `pkg install pkgconf` or from ports via `devel/pkgconf`.
|
48
|
+
|
49
|
+
On JRuby and TruffleRuby, there are no requirements to install the FFI gem, and `require 'ffi'` works even without installing the gem (i.e., the gem is preinstalled on these implementations).
|
47
50
|
|
48
51
|
## Installation
|
49
52
|
|
@@ -61,8 +64,7 @@ or from the git repository on github:
|
|
61
64
|
## License
|
62
65
|
|
63
66
|
The ffi library is covered by the BSD license, also see the LICENSE file.
|
64
|
-
The specs are
|
65
|
-
as Rubyspec, see the LICENSE.SPECS file.
|
67
|
+
The specs are covered by the same license as [ruby/spec](https://github.com/ruby/spec), the MIT license.
|
66
68
|
|
67
69
|
## Credits
|
68
70
|
|
@@ -74,6 +76,7 @@ The following people have submitted code, bug reports, or otherwise contributed
|
|
74
76
|
* Andreas Niederl <rico32@gmx.net>
|
75
77
|
* Andrew Cholakian <andrew@andrewvc.com>
|
76
78
|
* Antonio Terceiro <terceiro@softwarelivre.org>
|
79
|
+
* Benoit Daloze <eregontp@gmail.com>
|
77
80
|
* Brian Candler <B.Candler@pobox.com>
|
78
81
|
* Brian D. Burns <burns180@gmail.com>
|
79
82
|
* Bryan Kearney <bkearney@redhat.com>
|
data/Rakefile
CHANGED
@@ -3,82 +3,16 @@ require 'rbconfig'
|
|
3
3
|
require 'rake/clean'
|
4
4
|
require File.expand_path("./lib/ffi/version")
|
5
5
|
|
6
|
-
USE_RAKE_COMPILER = (RUBY_PLATFORM =~ /java/) ? false : true
|
7
|
-
if USE_RAKE_COMPILER
|
8
|
-
require 'rake/extensiontask'
|
9
|
-
end
|
10
|
-
|
11
6
|
require 'date'
|
12
7
|
require 'fileutils'
|
13
8
|
require 'rbconfig'
|
14
9
|
require 'rspec/core/rake_task'
|
15
10
|
require 'rubygems/package_task'
|
16
11
|
|
17
|
-
|
18
|
-
|
19
|
-
"dylib"
|
20
|
-
when /mswin|mingw/
|
21
|
-
"dll"
|
22
|
-
else
|
23
|
-
RbConfig::CONFIG['DLEXT']
|
24
|
-
end
|
25
|
-
|
26
|
-
CPU = case RbConfig::CONFIG['host_cpu'].downcase
|
27
|
-
when /i[3456]86/
|
28
|
-
# Darwin always reports i686, even when running in 64bit mode
|
29
|
-
if RbConfig::CONFIG['host_os'] =~ /darwin/ && 0xfee1deadbeef.is_a?(Fixnum)
|
30
|
-
"x86_64"
|
31
|
-
else
|
32
|
-
"i386"
|
33
|
-
end
|
34
|
-
|
35
|
-
when /amd64|x86_64/
|
36
|
-
"x86_64"
|
37
|
-
|
38
|
-
when /ppc64|powerpc64/
|
39
|
-
"powerpc64"
|
40
|
-
|
41
|
-
when /ppc|powerpc/
|
42
|
-
"powerpc"
|
43
|
-
|
44
|
-
when /^arm/
|
45
|
-
"arm"
|
46
|
-
|
47
|
-
else
|
48
|
-
RbConfig::CONFIG['host_cpu']
|
49
|
-
end
|
50
|
-
|
51
|
-
OS = case RbConfig::CONFIG['host_os'].downcase
|
52
|
-
when /linux/
|
53
|
-
"linux"
|
54
|
-
when /darwin/
|
55
|
-
"darwin"
|
56
|
-
when /freebsd/
|
57
|
-
"freebsd"
|
58
|
-
when /openbsd/
|
59
|
-
"openbsd"
|
60
|
-
when /sunos|solaris/
|
61
|
-
"solaris"
|
62
|
-
when /mswin|mingw/
|
63
|
-
"win32"
|
64
|
-
else
|
65
|
-
RbConfig::CONFIG['host_os'].downcase
|
66
|
-
end
|
67
|
-
|
68
|
-
def which(name)
|
69
|
-
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
70
|
-
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
71
|
-
exts.each do |ext|
|
72
|
-
app = File.join(path, name+ext)
|
73
|
-
return app if File.executable? app
|
74
|
-
end
|
75
|
-
end
|
76
|
-
nil
|
12
|
+
def java?
|
13
|
+
/java/ === RUBY_PLATFORM
|
77
14
|
end
|
78
15
|
|
79
|
-
GMAKE = which('gmake').nil? ? 'make' : 'gmake'
|
80
|
-
|
81
|
-
LIBTEST = "build/libtest.#{LIBEXT}"
|
82
16
|
BUILD_DIR = "build"
|
83
17
|
BUILD_EXT_DIR = File.join(BUILD_DIR, "#{RbConfig::CONFIG['arch']}", 'ffi_c', RUBY_VERSION)
|
84
18
|
|
@@ -86,7 +20,7 @@ def gem_spec
|
|
86
20
|
@gem_spec ||= Gem::Specification.load('ffi.gemspec')
|
87
21
|
end
|
88
22
|
|
89
|
-
TEST_DEPS = [
|
23
|
+
TEST_DEPS = []
|
90
24
|
if RUBY_PLATFORM == "java"
|
91
25
|
RSpec::Core::RakeTask.new(:spec) do |config|
|
92
26
|
config.rspec_opts = YAML.load_file 'spec/spec.opts'
|
@@ -110,30 +44,22 @@ CLEAN.include 'build'
|
|
110
44
|
CLEAN.include 'conftest.dSYM'
|
111
45
|
CLEAN.include 'spec/ffi/fixtures/libtest.{dylib,so,dll}'
|
112
46
|
CLEAN.include 'spec/ffi/fixtures/*.o'
|
47
|
+
CLEAN.include 'spec/ffi/embed-test/ext/*.{o,def}'
|
48
|
+
CLEAN.include 'spec/ffi/embed-test/ext/Makefile'
|
113
49
|
CLEAN.include "pkg/ffi-*-{mingw32,java}"
|
114
50
|
CLEAN.include 'lib/1.*'
|
115
51
|
CLEAN.include 'lib/2.*'
|
116
|
-
CLEAN.include 'bin'
|
117
52
|
|
118
53
|
task :distclean => :clobber
|
119
54
|
|
120
|
-
desc "Build the native test lib"
|
121
|
-
file "build/libtest.#{LIBEXT}" => FileList['libtest/**/*.[ch]'] do
|
122
|
-
sh %{#{GMAKE} -f libtest/GNUmakefile CPU=#{CPU} OS=#{OS} }
|
123
|
-
end
|
124
|
-
|
125
|
-
|
126
|
-
desc "Build test helper lib"
|
127
|
-
task :libtest => "build/libtest.#{LIBEXT}"
|
128
|
-
|
129
55
|
desc "Test the extension"
|
130
56
|
task :test => [ :spec ]
|
131
57
|
|
132
58
|
|
133
59
|
namespace :bench do
|
134
60
|
ITER = ENV['ITER'] ? ENV['ITER'].to_i : 100000
|
135
|
-
bench_libs = "-Ilib
|
136
|
-
bench_files = Dir["bench/bench_*.rb"].reject { |f| f == "bench_helper.rb" }
|
61
|
+
bench_libs = "-Ilib" unless RUBY_PLATFORM == "java"
|
62
|
+
bench_files = Dir["bench/bench_*.rb"].reject { |f| f == "bench/bench_helper.rb" }
|
137
63
|
bench_files.each do |bench|
|
138
64
|
task File.basename(bench, ".rb")[6..-1] => TEST_DEPS do
|
139
65
|
sh %{#{Gem.ruby} #{bench_libs} #{bench} #{ITER}}
|
@@ -175,8 +101,8 @@ end
|
|
175
101
|
|
176
102
|
task 'gem:java' => 'java:gem'
|
177
103
|
|
178
|
-
|
179
|
-
|
104
|
+
unless java?
|
105
|
+
require 'rake/extensiontask'
|
180
106
|
Rake::ExtensionTask.new('ffi_c', gem_spec) do |ext|
|
181
107
|
ext.name = 'ffi_c' # indicate the name of the extension.
|
182
108
|
# ext.lib_dir = BUILD_DIR # put binaries into this folder.
|
@@ -212,6 +138,7 @@ file "ext/ffi_c/libffi/autogen.sh" => "ext/ffi_c/libffi" do
|
|
212
138
|
warn "Downloading libffi ..."
|
213
139
|
sh "git submodule update --init --recursive"
|
214
140
|
end
|
141
|
+
task :libffi => "ext/ffi_c/libffi/autogen.sh"
|
215
142
|
|
216
143
|
LIBFFI_GIT_FILES = `git --git-dir ext/ffi_c/libffi/.git ls-files -z`.split("\x0")
|
217
144
|
|
data/appveyor.yml
CHANGED
@@ -12,11 +12,16 @@ install:
|
|
12
12
|
- bundle install
|
13
13
|
build: off
|
14
14
|
build_script:
|
15
|
-
- bundle exec rake compile || bundle exec rake compile
|
15
|
+
- bundle exec rake libffi compile -- %EXTCONFOPTS% || bundle exec rake compile -- %EXTCONFOPTS%
|
16
16
|
test_script:
|
17
17
|
- bundle exec rake test
|
18
18
|
environment:
|
19
19
|
matrix:
|
20
20
|
- RUBYVER: "head-x64"
|
21
|
+
EXTCONFOPTS: "--disable-system-libffi"
|
21
22
|
- RUBYVER: 24
|
23
|
+
EXTCONFOPTS: "--disable-system-libffi"
|
22
24
|
- RUBYVER: 25-x64
|
25
|
+
EXTCONFOPTS: "--enable-system-libffi"
|
26
|
+
- RUBYVER: 25
|
27
|
+
EXTCONFOPTS: "--enable-system-libffi"
|
data/ext/ffi_c/Call.c
CHANGED
@@ -43,10 +43,8 @@
|
|
43
43
|
#endif
|
44
44
|
#include <errno.h>
|
45
45
|
#include <ruby.h>
|
46
|
-
#if defined(HAVE_RUBY_THREAD_H)
|
47
46
|
#include <ruby/thread.h>
|
48
|
-
#
|
49
|
-
#if defined(HAVE_NATIVETHREAD) && (defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)) && !defined(_WIN32)
|
47
|
+
#if defined(HAVE_NATIVETHREAD) && !defined(_WIN32)
|
50
48
|
# include <signal.h>
|
51
49
|
# include <pthread.h>
|
52
50
|
#endif
|
@@ -116,7 +114,7 @@ rbffi_SetupCallParams(int argc, VALUE* argv, int paramCount, Type** paramTypes,
|
|
116
114
|
Type* paramType = paramTypes[i];
|
117
115
|
int type;
|
118
116
|
|
119
|
-
|
117
|
+
|
120
118
|
if (unlikely(paramType->nativeType == NATIVE_MAPPED)) {
|
121
119
|
VALUE values[] = { argv[argidx], Qnil };
|
122
120
|
argv[argidx] = rb_funcall2(((MappedType *) paramType)->rbConverter, id_to_native, 2, values);
|
@@ -297,8 +295,8 @@ rbffi_SetupCallParams(int argc, VALUE* argv, int paramCount, Type** paramTypes,
|
|
297
295
|
|
298
296
|
case NATIVE_STRING:
|
299
297
|
if (type == T_NIL) {
|
300
|
-
param->ptr = NULL;
|
301
|
-
|
298
|
+
param->ptr = NULL;
|
299
|
+
|
302
300
|
} else {
|
303
301
|
if (rb_safe_level() >= 1 && OBJ_TAINTED(argv[argidx])) {
|
304
302
|
rb_raise(rb_eSecurityError, "Unsafe string parameter");
|
@@ -345,9 +343,13 @@ static void *
|
|
345
343
|
call_blocking_function(void* data)
|
346
344
|
{
|
347
345
|
rbffi_blocking_call_t* b = (rbffi_blocking_call_t *) data;
|
346
|
+
#ifndef HAVE_RUBY_THREAD_HAS_GVL_P
|
348
347
|
b->frame->has_gvl = false;
|
348
|
+
#endif
|
349
349
|
ffi_call(&b->cif, FFI_FN(b->function), b->retval, b->ffiValues);
|
350
|
+
#ifndef HAVE_RUBY_THREAD_HAS_GVL_P
|
350
351
|
b->frame->has_gvl = true;
|
352
|
+
#endif
|
351
353
|
|
352
354
|
return NULL;
|
353
355
|
}
|
@@ -355,7 +357,7 @@ call_blocking_function(void* data)
|
|
355
357
|
VALUE
|
356
358
|
rbffi_do_blocking_call(void *data)
|
357
359
|
{
|
358
|
-
|
360
|
+
rb_thread_call_without_gvl(call_blocking_function, data, (void *) -1, NULL);
|
359
361
|
|
360
362
|
return Qnil;
|
361
363
|
}
|
@@ -376,28 +378,17 @@ rbffi_CallFunction(int argc, VALUE* argv, void* function, FunctionType* fnInfo)
|
|
376
378
|
FFIStorage* params;
|
377
379
|
VALUE rbReturnValue;
|
378
380
|
rbffi_frame_t frame = { 0 };
|
379
|
-
|
381
|
+
|
380
382
|
retval = alloca(MAX(fnInfo->ffi_cif.rtype->size, FFI_SIZEOF_ARG));
|
381
|
-
|
383
|
+
|
382
384
|
if (unlikely(fnInfo->blocking)) {
|
383
385
|
rbffi_blocking_call_t* bc;
|
384
386
|
|
385
|
-
/*
|
386
|
-
* due to the way thread switching works on older ruby variants, we
|
387
|
-
* cannot allocate anything passed to the blocking function on the stack
|
388
|
-
*/
|
389
|
-
#if defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL)
|
387
|
+
/* allocate information passed to the blocking function on the stack */
|
390
388
|
ffiValues = ALLOCA_N(void *, fnInfo->parameterCount);
|
391
389
|
params = ALLOCA_N(FFIStorage, fnInfo->parameterCount);
|
392
390
|
bc = ALLOCA_N(rbffi_blocking_call_t, 1);
|
393
391
|
bc->retval = retval;
|
394
|
-
#else
|
395
|
-
ffiValues = ALLOC_N(void *, fnInfo->parameterCount);
|
396
|
-
params = ALLOC_N(FFIStorage, fnInfo->parameterCount);
|
397
|
-
bc = ALLOC_N(rbffi_blocking_call_t, 1);
|
398
|
-
bc->retval = xmalloc(MAX(fnInfo->ffi_cif.rtype->size, FFI_SIZEOF_ARG));
|
399
|
-
bc->stkretval = retval;
|
400
|
-
#endif
|
401
392
|
bc->cif = fnInfo->ffi_cif;
|
402
393
|
bc->function = function;
|
403
394
|
bc->ffiValues = ffiValues;
|
@@ -408,18 +399,10 @@ rbffi_CallFunction(int argc, VALUE* argv, void* function, FunctionType* fnInfo)
|
|
408
399
|
fnInfo->parameterCount, fnInfo->parameterTypes, params, ffiValues,
|
409
400
|
fnInfo->callbackParameters, fnInfo->callbackCount, fnInfo->rbEnums);
|
410
401
|
|
411
|
-
rbffi_frame_push(&frame);
|
402
|
+
rbffi_frame_push(&frame);
|
412
403
|
rb_rescue2(rbffi_do_blocking_call, (VALUE) bc, rbffi_save_frame_exception, (VALUE) &frame, rb_eException, (VALUE) 0);
|
413
404
|
rbffi_frame_pop(&frame);
|
414
405
|
|
415
|
-
#if !(defined(HAVE_RB_THREAD_BLOCKING_REGION) || defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL))
|
416
|
-
memcpy(bc->stkretval, bc->retval, MAX(bc->cif.rtype->size, FFI_SIZEOF_ARG));
|
417
|
-
xfree(bc->params);
|
418
|
-
xfree(bc->ffiValues);
|
419
|
-
xfree(bc->retval);
|
420
|
-
xfree(bc);
|
421
|
-
#endif
|
422
|
-
|
423
406
|
} else {
|
424
407
|
|
425
408
|
ffiValues = ALLOCA_N(void *, fnInfo->parameterCount);
|
@@ -436,7 +419,7 @@ rbffi_CallFunction(int argc, VALUE* argv, void* function, FunctionType* fnInfo)
|
|
436
419
|
|
437
420
|
if (unlikely(!fnInfo->ignoreErrno)) {
|
438
421
|
rbffi_save_errno();
|
439
|
-
}
|
422
|
+
}
|
440
423
|
|
441
424
|
if (RTEST(frame.exc) && frame.exc != Qnil) {
|
442
425
|
rb_exc_raise(frame.exc);
|
@@ -444,7 +427,7 @@ rbffi_CallFunction(int argc, VALUE* argv, void* function, FunctionType* fnInfo)
|
|
444
427
|
|
445
428
|
RB_GC_GUARD(rbReturnValue) = rbffi_NativeValue_ToRuby(fnInfo->returnType, fnInfo->rbReturnType, retval);
|
446
429
|
RB_GC_GUARD(fnInfo->rbReturnType);
|
447
|
-
|
430
|
+
|
448
431
|
return rbReturnValue;
|
449
432
|
}
|
450
433
|
|
@@ -461,7 +444,7 @@ getPointer(VALUE value, int type)
|
|
461
444
|
return memory != NULL ? memory->address : NULL;
|
462
445
|
|
463
446
|
} else if (type == T_STRING) {
|
464
|
-
|
447
|
+
|
465
448
|
return StringValuePtr(value);
|
466
449
|
|
467
450
|
} else if (type == T_NIL) {
|