In_threadmodule has functions for interaction between the Async world and other (kernel) threads. The name is to remind us to think about threads and race conditions.
All threads come from the one thread pool used for all Async-managed threads.
module Priority :
module type of
Core.Std.Linux_ext.Prioritywith type t = Core.Std.Linux_ext.Priority.t
module Helper_thread :
val create :
?priority:Priority.t -> ?name:string -> unit -> t Core.Std.Or_error.t
create ?name ()creates a new helper thread. The
namewill be used as the thread name for any work that that is done by the thread that doesn't get its own name.
create uses a thread from Async's thread pool, reserving that thread for exclusive
use by the helper thread until the helper thread is no longer used (specifically,
finalized and is finished with all its work), at which point the thread is made
available for general use by the pool.
val pipe_of_squeue :
'a Core.Std.Squeue.t -> 'a Async_kernel.Pipe.Reader.t
pipe_of_squeue squeuereturns a pipe
pand consumes the contents
squeue, placing them in
p. It repeatedly grabs everything from
squeue, places it in
p, and then waits for pushback on
val run :
?priority:Priority.t -> ?thread:Helper_thread.t -> ?when_finished:[ `Best | `Notify_the_scheduler | `Take_the_async_lock ] -> ?name:string -> (unit -> 'a) -> 'a Async_kernel.Deferred.t
run ?priority ?thread ?name fruns
f ()in another thread and returns the result as a Deferred in the Async world. If
f ()raises an exception (asynchronously, since it is another thread) then that exception will be raised to the monitor that called
Async code should not be used from within
thread is not supplied, then any thread from the thread pool could be used. If
you need to run routines in a specific thread (as is required by some libraries like
Sqlite), you should create a helper thread and supply it to
priority is supplied, the priority of the thread in the linux scheduler will be
priority for the duration of
f (), provided the thread is allowed to do so,
see `man setpriority`.
If you call
run several times with the same helper thread, the
f () calls will run
in sequence, in the order in which they are supplied to
f () will
complete (return or raise) before another
f () starts.
For example, if you do:
let () = run ~thread f1; run ~thread f2; run ~thread f3;
Then the thread will run
f1 () to completion, then
f2 () to completion, then
f3 () to completion.
name is supplied, the name of the thread will be set to it for the duration of
the execution of
when_finished describes how the helper thread behaves once
f () has completed:
`Take_the_lockit takes the Async lock and runs a cycle immediately
`Notify_the_schedulerit just notifies the scheduler that the result is ready
`Bestit tries to take the lock and run a cycle, but will fallback to
`Notify_the_schedulermethod if the Async lock is already held by someone else. The default is
`Best, and one shouldn't need to change it -- it is useful only for unit testing.
val syscall :
name:string -> (unit -> 'a) -> ('a, exn) Core.Std.Result.t Async_kernel.Deferred.t
syscall fruns f, which should be a single system call, and returns the result, handling the restarting of interrupted system calls. To avoid race conditions, the
syscallshould just make a system call. That way, everything else is done holding the Async lock.
val syscall_exn :
name:string -> (unit -> 'a) -> 'a Async_kernel.Deferred.t