I'm seeing some behavior with `AsyncCondition`s (on 0.5) that I don't 
understand. I'm not sure if it's a bug or expected behavior.

Here’s a minimal example that doesn’t work the way I expect:

begin # wrapped for easy REPL-pasting

asynccond = Base.AsyncCondition()
waitcond = Condition()
n = 0
ccall(:uv_async_send, Cint, (Ptr{Void}, ), asynccond.handle) # this seems like 
it shouldn't have any effect
@async begin
    global n
    n += 1
    wait(asynccond)
    n += 1
    notify(waitcond)
end
yield() # give the async task a chance to run
println("waiting, n: $n")
ccall(:uv_async_send, Cint, (Ptr{Void}, ), asynccond.handle)
wait(waitcond)
# if we get here then the waiter was successfully woken
println("woke, n: $n")

end

Here’s what I’d expect to happen:

The first uv_async_send wouldn’t do anything because there are no tasks waiting 
on the AsyncCondition.
The async task is added to the scheduler
the main task hits the first yield(), which switches to the async task
the async task blocks waiting on asynccond, which hands control back to the 
main task
we print out n from the main task
this call to uv_async_send should put the async task back in the schedule queue
the main task blocks waiting on waitcond, which hands control back to the async 
task
the async task notifies waitcond, which should add the main task back to the 
schedule queue, then that task is complete
the main task prints the “woke” message

Instead it prints "waiting, n: 1”, then hangs.
It seems like the async task is never waking up from waiting on asynccond. If I 
remove the first `uv_async_send` or add a `yield()` immediately after it, then 
it works as expected.

Any ideas what’s going on?

-s

Reply via email to