@std/sync

Overview

Atomics, channels, locks, and barriers for threads.

Every type here is a thin handle over a number. A handle carries nothing but a registry id, so passing a handle between threads shares the same underlying cell, queue, or lock, and two handles built from the same id always name the same object. The registries are separate per type: an AtomicInt and a Mutex that both use id 5 are unrelated objects.

That sharing rule is the whole design. A handle created in one thread with byId(5) reaches the same object as a handle created in another thread with byId(5), without any registration step, because both look the id up in one process-wide table. Pick ids that no other code in the program uses.

Values start at their zero state the first time an id is touched, and the entry then lives for the rest of the run. There is no way to unregister an id, so reuse an id only when you mean to reopen the same object.

Blocking calls park the calling thread until the condition is met. Channel.recv, Mutex.lock, RwLock.readLock, RwLock.writeLock, Condvar.wait, Barrier.wait, and Thread.join all block. Each has a non-blocking or bounded partner where one makes sense, and a non-blocking call reports absence in its return value rather than by throwing, so polling loops stay easy to write.

Locks are not reentrant and not owned. A lock does not track which thread holds it, so unlocking a lock you do not hold aborts the program instead of returning an error. Thread.join is the one call here that reports failure as a value.

.rnx
import { AtomicInt, Channel } from "@std/sync";

let counter = AtomicInt.byId(1);
counter.set(0);

let jobs = Channel.byId(2);
jobs.send("first");
jobs.send("second");

print(counter.fetchAdd(5), counter.get());
print("queued:", jobs.len(), "took:", jobs.tryRecv());

When to use it

Reach for @std/sync whenever threads share anything. Every primitive is constructed byId so separate threads open the same cell — the only legal cross-thread sharing path in the language.

Capabilities

  • AtomicInt counters
  • Mutex/RwLock guards
  • Channel/Barrier coordination

Symbols

  • class AtomicInt — A 64-bit integer cell shared through the registry, with atomic access.
  • class Barrier — Rendezvous gate: all count parties block in wait until the count-th
  • class Channel — An unbounded first-in-first-out queue shared through the registry.
  • class Condvar — Condition variable for wait/notify coordination, shared through the
  • class Mutex — Mutual exclusion lock shared through the registry.
  • class RwLock — Reader-writer lock shared through the registry.
  • class Thread — Owned handle to a spawned thread. Thread.spawn returns this nominal