If you don't want to use pipes to synchronize your threads, the only function that is safe to use from another thread (or signal handler) is uv_async_send. Any other function will cause undefined behavior. It may occasionally work, but it will probably also corrupt other random parts of the program.
-Jameson On Fri, Jan 31, 2014 at 5:05 PM, Tim Holy <[email protected]> wrote: > This is very helpful, thanks for the tips. I especially like the idea of > waiting on a file descriptor controlled by a C thread; that should avoid the > need for any Julia code to be called by the callback. > > You may be interested in some experiments I ran (see below), trying to > reproduce my problem in a simpler context. "Unfortunately," all of these > experiments work. So either there is something specific to this particular > library, or "working" is fragile in some fashion and I just haven't succeeded > in triggering a failure. > > --Tim > > c = Condition() > > function c_notify(p::Ptr{Void}) > cond = unsafe_pointer_to_objref(p) > notify(cond) > C_NULL > end > > const cb = cfunction(c_notify, Ptr{Void}, (Ptr{Void},)) > > @sync begin > @async begin > println("About to wait from 1") > wait(c) > println("Done waiting from 1") > end > @async begin > println("About to notify from 2") > # notify(c) > ccall(cb, Void, (Ptr{Void},), pointer_from_objref(c)) > println("Done notifying from 2") > end > end > > threads = Uint64[0] > > @sync begin > @async begin > println("About to wait from 1") > wait(c) > println("Done waiting from 1") > end > @async begin > println("About to notify from 2") > # notify(c) > ccall(:pthread_create, Cint, (Ptr{Void}, Ptr{Void}, Ptr{Void}, > Ptr{Void}), threads, C_NULL, cb, pointer_from_objref(c)) > ccall(:pthread_join, Cint, (Uint64, Ptr{Void}), threads[1], C_NULL) > println("Done notifying from 2") > end > end > > > On Friday, January 31, 2014 01:50:53 PM Spencer Russell wrote: >> Hi Tim, >> >> I spent some time playing around with interfacing to multi-threaded C >> libraries for AudioIO, namely portaudio. In Portaudio you register a >> callback which gets called periodically whenever the audio card needs a new >> frame of data. It gets called from a separate thread, so I was getting >> segfaults if I executed julia code directly from the callback. >> >> In the end I wrote a small C module that implemented a callback which I >> kept synchronized with a Julia Task. For the C callback to wake up the Task >> I used a file descriptor (that way in Julia land I could wait on it and >> only block that task instead of the whole julia process). For the Julia >> Task to wake up the C callback I used a semaphore. >> >> You can see my C code (as well as the BinDeps stuff to compile it) in the >> AudioIO repo at >> >> https://github.com/ssfrr/AudioIO.jl >> >> I'm not sure if this approach would work in your situation, but if your C >> library is spawning a separate thread I think this is one way to handle it. >> >> -s >> >> On Fri, Jan 31, 2014 at 7:58 AM, Tim Holy <[email protected]> wrote: >> > I'm interfacing with a C library that provides the ability to set a >> > callback >> > function so you can be notified when some job is done. I'm hoping to >> > exploit >> > this with the Task interface so I can feed multiple jobs with a single >> > Julia >> > process. I'm declaring my notify function like this: >> > >> > function callback_notify(hnd, status, data) >> > >> > println("In notify") >> > s = unsafe_pointer_to_objref(data)::Stream >> > @show s >> > s.status = status >> > notify(s.c) >> > println("Done notifying") >> > nothing >> > >> > end >> > >> > Stream is a type that has a Condition member, >> > type Stream >> > >> > handle::StreamHandle >> > status::Cuint >> > c::Condition >> > >> > end >> > >> > I've successfully set the callback function, issued wait(s.c), and from >> > the >> > println statements I can see that the notify callback executes fully. >> > However, >> > my task never wakes up. My suspicion is that the C library is spawning a >> > new >> > thread; does that pose problems for the Task interface? Or is something >> > else >> > happening? Any good workarounds? >> > >> > --Tim
