Another clue - if I add another `yield()` after the first, I get "waiting, n: 
2”, which implies that the async task is waking up even though I haven’t called 
`uv_async_send`.

Probably what’s going on below is that the `println` is switching to the async 
task, so it finishes before we’ve run the 2nd `uv_async_send`, so then when we 
wait on `waitcond` we wait forever.

So perhaps the question is - why is the async task being woken up without 
calling `uv_async_send`?

-s

> On Jul 26, 2016, at 3:44 PM, Spencer Russell <[email protected]> wrote:
> 
> 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