Skip to main content

Module shared

Module shared 

Source
Expand description

Shared<T>: mutable state that more than one task may reach.

The Language Card names this type in the sentence that keeps a vector out of a task: “finish it as an array or wrap mutable state in Shared or another synchronized type.” ADR 0008 makes it the one value that crosses a task boundary by sharing rather than by copying, which is the reason the type exists.

let metrics = Shared(Metrics(requests: 0, failures: 0))
metrics.lock(fn(var value) { value.record(failed) })

There is no get and no set. Every access is a scoped SharedCell::lock, so a read-modify-write cannot be written as two operations that race: the read, the modification, and the write are one call with the lock held for all three.

What the cell holds is a Transfer, not a Value: the wrapped value must be task-safe, a task-safe value is exactly one a Transfer can carry, and a Transfer is the only form two threads can both address. Each lock therefore converts the cell’s contents into the locking task’s own Value and converts back what the closure leaves — the same copy the task-safety rule already demands at every other boundary.

§Cycles

A cell may hold another cell, including itself, and ADR 0011 says plainly that nothing reclaims such an Arc cycle: cells outlive every task that holds one, so collecting a cycle among them needs a collector that stops every thread, which the per-task collector rules out by design. The ADR’s amendment picks a narrower, cheaper policy: lock rejects the one shape of cycle it can see for free — the cell ending up holding a handle to itself — and leaves everything wider as a documented, accepted leak. See Transfer::reaches and direct_cycle.

Structs§

SharedCell
The storage a Shared<T> value addresses.