Created
December 24, 2015 18:01
-
-
Save paddor/3cb70f285552ba65a620 to your computer and use it in GitHub Desktop.
This file contains 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 "callback_bug.h" | |
#include <pthread.h> | |
#include <assert.h> | |
#include <stdlib.h> | |
typedef struct { | |
callback_fn *callback; | |
void *args; // Application arguments | |
} shim_t; | |
static void * | |
s_thread_shim (void *args) | |
{ | |
assert (args); | |
shim_t *shim = (shim_t *) args; | |
char *name = (char *) shim->args; | |
printf("%s: calling callback ...\n", name); | |
shim->callback(); | |
printf("%s: callback has returned.\n", name); | |
return NULL; | |
} | |
void | |
call_callback(callback_fn *callback, void *args) | |
{ | |
shim_t *shim = (shim_t *) malloc (sizeof (shim_t)); | |
if (!shim) { | |
printf("shim allocation failed\n"); | |
return; | |
} | |
shim->callback = callback; | |
shim->args = args; | |
pthread_t thread; | |
pthread_create (&thread, NULL, s_thread_shim, shim); | |
pthread_detach (thread); | |
} |
This file contains 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
#ifndef __CALLBACK_BUG_H_INCLUDED__ | |
#define __CALLBACK_BUG_H_INCLUDED__ | |
#include <stdio.h> | |
typedef void (callback_fn) (void); | |
void | |
call_callback(callback_fn *callback, void *args); | |
#endif |
This file contains 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 'ffi' | |
module CallbackBug | |
extend ::FFI::Library | |
lib_name = 'libcallback_bug' | |
ffi_lib "#{lib_name}.#{::FFI::Platform::LIBSUFFIX}" | |
attach_function :call_callback, [:pointer, :pointer], :void, blocking: true | |
end | |
class Foo | |
def initialize(name) | |
name_ptr = FFI::MemoryPointer.from_string(name) | |
@callback = FFI::Function.new(:void, [], blocking: true) do | |
yield | |
end | |
CallbackBug.call_callback(@callback, name_ptr) | |
end | |
end | |
f1 = Foo.new("f1") do | |
begin | |
puts "f1: indefinitely running block, e.g. actor handler" | |
sleep | |
ensure | |
puts "f1: block is being GC'd" | |
end | |
end | |
ObjectSpace.define_finalizer(f1) do | |
puts "f1 is being GC'd" | |
end | |
Foo.new("f2") do | |
begin | |
puts "f2" | |
ensure | |
puts "f2: block is being GC'd" | |
end | |
end | |
sleep 0.5 | |
f1 = nil | |
GC.start | |
sleep 1 | |
puts "__END__" | |
# What this script shows is that the callback for f1 never returns, so the | |
# mesage "f1: callback has returned." is not printed. |
This file contains 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_bug.dylib: callback_bug.h callback_bug.c | |
clang -dynamiclib -std=gnu99 callback_bug.c -o $@ |
This file contains 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
$ ruby callback_bug.rb | |
f1: calling callback ... | |
f2: calling callback ... | |
f1: indefinitely running block, e.g. actor handler | |
f2 | |
f2: block is being GC'd | |
f2: callback has returned. | |
__END__ | |
f1: block is being GC'd | |
f1 is being GC'd |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment