On Thu, Nov 5, 2015 at 12:55 AM, Valentin Churavy <
v.ch...@gmail.com> wrote:
>
> I was wondering if someone with a bit more detailed knowledge of libuv could
> help me out.
>
> In
https://github.com/dmlc/MXNet.jl/pull/16 I have a function that is called
> from a c/c++ library like this
>
> function _wrapper(data :: Ptr{Float64}, jf :: Ptr{Void})
> julia_function = unsafe_pointer_to_objref(jf) :: Function
> julia_function(data)
> return nothing
> end
>
> Now I am trying to make this call thread-safe
> (
http://docs.julialang.org/en/latest/manual/calling-c-and-fortran-code/#thread-safety)
> by rewriting this function as
>
> function _wrapper(data :: Ptr{Float64}, jf :: Ptr{Void})
> julia_function = unsafe_pointer_to_objref(jf) :: Function
> cb_packaged = Base.SingleAsyncWork(_ -> julia_function(data))
> ccall(:uv_async_send, Void, (Ptr{Void},), cb_packaged.handle)
> wait(cb_packaged)
> return nothing
> end
>
IIUC, you want to execute `_wrapper` in a different thread. This is
not going to work. Note that in the document[1], it explicitly
mentioned,
> The callback you pass to C should only execute a ccall to :uv_async_send, passing cb.handle as the argument.
The runtime for 0.4 is not thread safe so you cannot call any runtime
in your callback function. (typeassert, allocate memory, setup GC
frame, call other non-threadsafe functions)
You can probably construct the callback as a struct including the
actual function, the barrier and the slot for the result then only do
the scheduling, waiting and returning in the callback wrapper.
[1]
http://docs.julialang.org/en/latest/manual/calling-c-and-fortran-code/#thread-safety