Created
December 27, 2015 14:27
-
-
Save paddor/10e4142a480eea36c57e to your computer and use it in GitHub Desktop.
JRuby/Rubinius: doesn't abort C function when FFI::Function breaks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
typedef int (callback_fn) (void); | |
void | |
ten_times(callback_fn *callback) | |
{ | |
for (int i = 1; i <= 10; i++) { | |
printf("libcallback: call #%i ...\n", i); | |
int rc = (* callback)(); | |
if (rc == -1) { | |
printf("libcallback: early return because rc == -1\n"); | |
return; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
libcallback.dylib: callback.c | |
clang -dynamiclib -std=gnu99 callback.c -o $@ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'minitest/autorun' | |
require 'ffi' | |
module LibCallback | |
extend ::FFI::Library | |
lib_name = 'libcallback' | |
ffi_lib "#{lib_name}.#{::FFI::Platform::LIBSUFFIX}" | |
attach_function :ten_times, [:pointer], :void, blocking: true | |
end | |
def mk_callback | |
FFI::Function.new(:void, [], blocking: true) do | |
yield | |
end | |
end | |
describe FFI::Function do | |
def foo | |
callback = mk_callback do | |
yield | |
end | |
LibCallback.ten_times(callback) | |
end | |
describe "with non-breaking block" do | |
it "calls block 10 times" do | |
called = 0 | |
foo { called += 1 } | |
assert_equal 10, called | |
end | |
end | |
describe "with breaking block" do | |
it "doesn't call block anymore" do | |
called = 0 | |
foo { called += 1; break } | |
assert_equal 1, called | |
end | |
end | |
end | |
describe "pure Ruby block" do | |
def foo | |
10.times { yield } | |
end | |
describe "with non-breaking block" do | |
it "calls block 10 times" do | |
called = 0 | |
foo { called += 1 } | |
assert_equal 10, called | |
end | |
end | |
describe "with breaking block" do | |
it "doesn't call block anymore" do | |
called = 0 | |
foo { called += 1; break } | |
assert_equal 1, called | |
end | |
end | |
end | |
__END__ | |
## | |
# EXPECTED, as when run on Ruby 2.2.4 | |
# | |
Run options: --seed 41083 | |
# Running: | |
..libcallback: call #1 ... | |
libcallback: call #2 ... | |
libcallback: call #3 ... | |
libcallback: call #4 ... | |
libcallback: call #5 ... | |
libcallback: call #6 ... | |
libcallback: call #7 ... | |
libcallback: call #8 ... | |
libcallback: call #9 ... | |
libcallback: call #10 ... | |
.libcallback: call #1 ... | |
. | |
Finished in 0.002047s, 1954.3283 runs/s, 1954.3283 assertions/s. | |
4 runs, 4 assertions, 0 failures, 0 errors, 0 skips | |
## | |
# ACTUAL, when run on JRuby 9.0.4.0 | |
# | |
Run options: --seed 3230 | |
# Running: | |
.libcallback: call #1 ... | |
libcallback: call #2 ... | |
libcallback: call #3 ... | |
libcallback: call #4 ... | |
libcallback: call #5 ... | |
libcallback: call #6 ... | |
libcallback: call #7 ... | |
libcallback: call #8 ... | |
libcallback: call #9 ... | |
libcallback: call #10 ... | |
.libcallback: call #1 ... | |
libcallback: call #2 ... | |
libcallback: call #3 ... | |
libcallback: call #4 ... | |
libcallback: call #5 ... | |
libcallback: call #6 ... | |
libcallback: call #7 ... | |
libcallback: call #8 ... | |
libcallback: call #9 ... | |
libcallback: call #10 ... | |
F. | |
Finished in 0.023067s, 173.4047 runs/s, 173.4047 assertions/s. | |
1) Failure: | |
FFI::Function::with breaking block#test_0001_doesn't call block anymore [test.rb:40]: | |
Expected: 1 | |
Actual: 10 | |
4 runs, 4 assertions, 1 failures, 0 errors, 0 skips | |
ruby test.rb 6.48s user 0.29s system 330% cpu 2.048 total |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment