# @async calls to C API yields?

**URL:** <https://discourse.julialang.org/t/async-calls-to-c-api-yields/15399>\
**Category:** General Usage\
**Tags:** question\
**Created:** [September 23, 2018, 9:37pm UTC](https://discourse.julialang.org/t/async-calls-to-c-api-yields/15399 "2018-09-23T21:37:55Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![felipenoris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/felipenoris/32/553_2.png) [@felipenoris](https://discourse.julialang.org/u/felipenoris)\
**Post date:** [September 23, 2018, 9:37pm UTC](https://discourse.julialang.org/t/async-calls-to-c-api-yields/15399/1 "2018-09-23T21:37:55Z")

</div>

I’m calling a function in an external API with ccall. That C function makes an IO operation internally. If I call it with `@async` will the scheduler yield automatically, or do I have to hook this to libuv to make it async?

More generally, what makes an `@async` call yield to another task in parallel?

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [September 24, 2018, 2:21am UTC](https://discourse.julialang.org/t/async-calls-to-c-api-yields/15399/2 "2018-09-24T02:21:48Z")

</div>

> [@felipenoris](#):
>
> That C function makes an IO operation internally. If I call it with @async will the scheduler yield automatically, or do I have to hook this to libuv to make it async?

You have to hook it to libuv. The simplest way is probably to pass `@cfunction(yield, Nothing, ())` as a callback function of type `void (*yield)()` to C, allowing you to call the Julia `yield()` function directly.

---

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [September 24, 2018, 3:00am UTC](https://discourse.julialang.org/t/async-calls-to-c-api-yields/15399/3 "2018-09-24T03:00:03Z")

</div>

> [@stevengj](#):
>
> call the Julia `yield()` function

But then I don’t think you can do the IO while calling `yield`? I suppose all the IO has to go through the event loop in order to do them concurrently (non-blockingly).

IIUC, if you need to do IO without touching libuv’s IO interface, then you have to do it in a different thread. To ping Julia to come back to the C function in the main thread, you call `uv_async_send(cond.handle)` from the IO thread once the IO is finished, where this `cond` is created with [`Base.AsyncCondition`](https://docs.julialang.org/en/v1/base/base/#Base.AsyncCondition). You can call Julia code `wait(cond)` in the thread that initialized Julia. During this `wait(cond)`, Julia can run other tasks and block until `uv_async_send`. (Not sure if this is the only solution. It’s just what I know.)

---

<div class="post-metadata">

**Author:** ![felipenoris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/felipenoris/32/553_2.png) [@felipenoris](https://discourse.julialang.org/u/felipenoris)\
**Post date:** [January 27, 2019, 9:12pm UTC](https://discourse.julialang.org/t/async-calls-to-c-api-yields/15399/4 "2019-01-27T21:12:55Z")

</div>

The experimental macro `@threadcall` addresses this issue, right? I mean, if I want to make an external function call async.

---

<div class="post-metadata">

**Author:** ![felipenoris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/felipenoris/32/553_2.png) [@felipenoris](https://discourse.julialang.org/u/felipenoris)\
**Post date:** [February 10, 2019, 5:15pm UTC](https://discourse.julialang.org/t/async-calls-to-c-api-yields/15399/5 "2019-02-10T17:15:31Z")

</div>

Ref [macro threadcall does not accept `Ref` arguments · Issue #30864 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/30864)
