Lyricdev
GitHub

std.task

Tasks, channels and the scheduler that runs them.

Each thread has a scheduler, written here over the runtime's park and poller, and main runs as a task of it. The module holds spawn and its Task with its TaskStatus, TaskScope, spawnDetached, sleep and yieldNow; cancellation through Cancelled and withTimeout; a panic that ends a task, not the process, described by PanicInfo; and Channel, Select and Timer, which work within a thread and across threads.

The threads and their pool are std.thread's, the locks std.sync's and the signals std.os's; they stand on parts kept here, internal to std: the locks' state, the scheduler, launchOn, the registry of the living schedulers and the natives.

Examples

import std.io { println };
import std.task { spawn, Channel };

fn main(): void throws Error {
    let ch = Channel<int>.new();
    let producer = spawn(() => {
        for (i in 1..=3) {
            try ch.send(i * 10);
        }
        ch.close();
    });
    var total = 0;
    while (let v = try ch.recv()) {
        total += v;
    }
    try producer.await();
    println(total);
}
60

Types

Cancelled class — The error a wait throws in a cancelled task, and a suspended yield when close() unwinds its coroutine.
PanicInfo class — Describes a panic that ended a task: its code, its message, and the frames where it happened, as the panic report writes them.
TaskStatus enum — Where a task stands: still running; ended with its value, with an error, with Cancelled; or ended by a panic.
Task class — The handle of a task, which spawn gives: the body's result once it ended, or the error it ended with.
TimedOut class — The error withTimeout throws when its time ran out before the body ended.
ChannelClosed class — The error Channel.send throws on a closed channel.
Channel class — A queue of values between tasks: values go in with Channel.send and come out with Channel.recv, in the order they went in.
Select class — The way into a select, a wait on several channels at once.
Selection class — A select as it is built: its cases, in the order they were added, and a timeout.
Timer class — Timers, as channels a select can wait on.
TaskScope class — A scope whose tasks end before it does: structured concurrency.

Functions

pub fn sleep(d: Duration): void throws Cancelled

Parks the running task until at least d has passed, while the other tasks of its thread run.

A sleep of zero or less lets the tasks that are ready run first.

Errors

Throws Cancelled in a cancelled task; a cancel during the sleep ends it early.

pub fn yieldNow(): void throws Cancelled

Lets the other ready tasks of the thread run first: the running task goes behind them.

Errors

Throws Cancelled in a cancelled task, as every wait does.

pub fn spawn<T, E :: [Error]>(body: fn() -> T throws E): (Task<T> throws E)

Starts body as a task of the running thread and returns its handle.

The task runs once the tasks ready before it had their turn, and Task.await on the handle gives its value or throws its error — E, what the body throws, the handle's type carries. The handle is the only way to that error, so a call that drops it warns; spawnDetached is the task nobody awaits, and TaskScope.spawn one the scope's close() waits for.

pub fn withTimeout<T, E :: [Error]>(
    d: Duration,
    body: fn() -> T throws E
): T throws [E, TimedOut, Cancelled]

Runs body as a task of its own and returns what it returns, unless d passes first.

When d passes first, the body is cancelled, and TimedOut is thrown once it has ended. A cancel of the caller cancels the body too; whenever this returns, the body has ended.

Errors

Throws the body's own errors as they are; TimedOut when d passed before the body ended; Cancelled when the caller was cancelled.

pub fn spawnDetached(body: fn() -> void throws Cancelled): void

Starts body as a task of the running thread, with no handle.

It runs once the tasks ready before it had their turn, and nobody waits for it — the program ends with main, done or not. Only a cancellation may end it early: it handles every other error itself.