Concurrent_in_async.PortableCapabilities for submitting jobs to the async scheduler from other threads
val scheduler :
unit ->
Await.Capsule.Initial.k Await.Capsule.Access.boxed Concurrent.Scheduler.t @ portablescheduler () is a handle that allows spawning concurrent tasks in the Async scheduler from other threads. It uses the thread-safe external job queue in the async scheduler under the hood, so is less efficient than the non-portable scheduler if you don't need to spawn tasks from arbitrary threads.
Usage example
open! Core
open! Async
open! Await
let print_endline = Capsule.Initial.Data.wrap Async_unix.Print.print_endline
let () =
let scheduler = Concurrent_in_async.Portable.scheduler () in
Mdx_async.run (fun () ->
Concurrent_in_async.schedule_with_concurrent Terminator.never ~f:(fun conc ->
Concurrent.with_scope
conc
(* Use the scheduler as our scope context to avoid allocating a closure *)
scheduler
~f:(fun s ->
(* Spawn a thread, given the handle to the scheduler *)
Concurrent.spawn
(Concurrent_in_thread.spawn_into s)
~f:(fun scope _ _ ->
(* Recover the scheduler *)
let scheduler = Concurrent.Scope.context scope in
(* We can now spawn tasks into the async scheduler *)
Concurrent.Scheduler.spawn scheduler scope ~f:(fun _ access _ ->
(* Those tasks get access to the initial capsule, which they can
use to call functions that use async *)
let print_endline =
Capsule.Data.unwrap
~access:(Capsule.Access.unbox access)
print_endline
in
print_endline "Hello from async!")
[@nontail])
[@nontail])))
;;