package async_unix

  1. Overview
  2. Docs
Legend:
Library
Module
Module type
Parameter
Class
Class type

The Thread_safe module has functions that are safe to call from threads outside Async, such as the ones spawned by In_thread.run.

This is in contrast with the rest of Async library which is generally not thread-safe.

All the Thread_safe.block* and Thread_safe.run* functions wake up the Async scheduler to ensure that it continues in a timely manner with whatever jobs got started. Some functions take an optional ?wakeup_scheduler:bool argument, which defaults to true. One can cause the scheduler to not be woken up by supplying ~wakeup_scheduler:false, which can reduce CPU use, but increase latency, because the scheduler may not wake up for a while to process jobs.

val am_holding_async_lock : unit -> bool

am_holding_async_lock () returns true if the currently running thread is holding the Async lock.

val deferred : unit -> 'a Async_kernel.Deferred.t * ('a -> unit)

deferred () returns (d, fill) where d is a deferred that will become determined with value v once fill v is called.

It is ok to call deferred from inside or outside Async. fill must be called from outside Async.

val run_in_async_with_optional_cycle : ?wakeup_scheduler:bool -> (unit -> [ `Run_a_cycle | `Do_not_run_a_cycle ] * 'a) -> ('a, exn) Core.Result.t

run_in_async_with_optional_cycle f acquires the Async lock and runs f () while holding the lock. Depending on the result of f, it may also run a cycle.

val run_in_async : ?wakeup_scheduler:bool -> (unit -> 'a) -> ('a, exn) Core.Result.t

run_in_async f acquires the Async lock and runs f () while holding the lock. It returns the result of f () to the outside world. The scheduler is woken up to ensure the code that depends on f () is run soon enough.

run_in_async doesn't run a cycle.

run_in_async does not automatically start the Async scheduler. You still need to call Scheduler.go elsewhere in your program.

val run_in_async_exn : ?wakeup_scheduler:bool -> (unit -> 'a) -> 'a
val block_on_async : (unit -> 'a Async_kernel.Deferred.t) -> ('a, exn) Core.Result.t

block_on_async f runs f () in the Async world and blocks until the result becomes determined. This function can be called from the main thread (before Async is started) or from a thread outside Async.

block_on_async will run a cycle if the deferred isn't determined, in the hope that running the cycle will cause the deferred to become determined.

block_on_async will automatically start the scheduler if it isn't already running.

val block_on_async_exn : (unit -> 'a Async_kernel.Deferred.t) -> 'a
val run_in_async_wait : (unit -> 'a Async_kernel.Deferred.t) -> ('a, exn) Core.Result.t

run_in_async_wait f is like block_on_async f, except that it must be called from a thread outside Async. Upon returning from run_in_async_wait, it is guaranteed that the caller does not have the Async lock.

val run_in_async_wait_exn : (unit -> 'a Async_kernel.Deferred.t) -> 'a
val reset_scheduler : unit -> unit

reset_scheduler stops the scheduler thread and any associated threads, and resets Async's global state to its initial state. This is useful if you need to first use Async to compute a value and then to daemonize (in which case you should daemonize with ~allow_threads_to_have_been_created:true).

reset_scheduler can be called from the main thread (before Async is started) or from a thread outside Async. reset_scheduler is known to be imperfect, and to have races in which there are still threads running after it returns.

val without_async_lock : (unit -> 'a) -> 'a

without_async_lock f can not be called from async, usually because f is expected to block. It's safe to call it in these two circumstances:

  • from a separate thread that's not holding the async lock
  • from the main thread, even if it is holding the async lock, as long as it's not running async jobs. In the latter case the async lock is dropped for the duration of f.