Adds `IO.getTaskState` which returns the state of a `Task` in the Lean runtime's task manager. The `TaskState` inductive has 3 constructors: `waiting`, `running`, and `finished`. The `waiting` constructor encompasses the waiting and queued states within the C task object documentation, because the task object does not provide a low cost way to distinguish these different forms of waiting. Furthermore, it seems unlikely for consumers to wish to distinguish between these internal states. The `running` constructor encompasses both the running and promised states in C docs. While not ideal, the C implementation does not provide a way to distinguish between a running `Task` and a waiting `Promise.result` (they both have null closures).
25 lines
1.1 KiB
Text
25 lines
1.1 KiB
Text
def assertBEq [BEq α] [ToString α] (caption : String) (actual expected : α) : IO Unit := do
|
||
unless actual == expected do
|
||
throw <| IO.userError <|
|
||
s!"{caption}: expected '{expected}', got '{actual}'"
|
||
|
||
def test : IO Unit := do
|
||
let p1 : IO.Promise Unit ← IO.Promise.new -- resolving queues the task
|
||
let p2 : IO.Promise Unit ← IO.Promise.new -- resolved once task is running
|
||
let p3 : IO.Promise Unit ← IO.Promise.new -- resolving finishes the task
|
||
let t ← BaseIO.mapTask (fun () => do p2.resolve (); IO.wait p3.result) p1.result
|
||
assertBEq "p1" (← IO.getTaskState p1.result) .running
|
||
assertBEq "p2" (← IO.getTaskState p2.result) .running
|
||
assertBEq "p3" (← IO.getTaskState p3.result) .running
|
||
assertBEq "t" (← IO.getTaskState t) .waiting
|
||
p1.resolve ()
|
||
assertBEq "p1" (← IO.getTaskState p1.result) .finished
|
||
IO.wait p2.result
|
||
assertBEq "p2" (← IO.getTaskState p2.result) .finished
|
||
assertBEq "t" (← IO.getTaskState t) .running
|
||
p3.resolve ()
|
||
assertBEq "p3" (← IO.getTaskState p3.result) .finished
|
||
IO.wait t
|
||
assertBEq "t" (← IO.getTaskState t) .finished
|
||
|
||
#eval test
|