Skip to content

Instantly share code, notes, and snippets.

@ssfrr
Last active March 23, 2016 15:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ssfrr/331b9bfb98b629383d70 to your computer and use it in GitHub Desktop.
Save ssfrr/331b9bfb98b629383d70 to your computer and use it in GitHub Desktop.
// Build with gcc --shared -o cbtest.so
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
typedef void *(*callback_t)(void *);
pthread_t thread;
callback_t cb = NULL;
void *cbdata = NULL;
void *threadtask(void *data) {
while(1) {
if(cb != NULL) {
cb(cbdata);
}
sleep(1);
}
NULL;
}
void registercb(callback_t c, void *data) {
if(cb != NULL) {
printf("there can be only one");
return;
}
cb = c;
cbdata = data;
pthread_create(&thread, NULL, threadtask, NULL);
}
# run this as a script after building cbtest.so
registercb(cb, data) = ccall((:registercb, "./cbtest.so"), Void,
(Ptr{Void}, Ptr{Void}), cb, data)
function threadtask(userdata)
ccall(:uv_async_send, Void, (Ptr{Void},), userdata)
C_NULL
end
waiters = Condition[]
maincond = Condition()
function jltask()
if length(waiters) > 0
println("waiter found")
notify(waiters[1])
yield() # this behaves as expected
# wait(maincond) # the addwaiter task never wakes up if we wait
end
print("T")
end
work = Base.SingleAsyncWork(_ -> jltask())
threadtask_c = cfunction(threadtask, Ptr{Void}, (Ptr{Void},))
registercb(threadtask_c, work.handle)
function addwaiter()
c = Condition()
push!(waiters, c)
for _ in 1:5
wait(c)
println("waiter awoken")
notify(maincond)
end
shift!(waiters)
end
sleep(3)
addwaiter()
# Expected output:
# TTTTwaiter found
# Twaiter awoken
# waiter found
# Twaiter awoken
# waiter found
# Twaiter awoken
# ...
# output with `wait`
# TTTTwaiter found
# Twaiter found
# waiter found
# waiter found
# waiter found
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment