Skip to content

Mutexes

Calibre provides Mutex:<T> for safely sharing mutable state across concurrent tasks.

let mut total : Mutex:<int> = Mutex:<int>.new(0);

A mutex wraps a value and controls access to it.

You can read the current value with .get().

print(total.get());

You can replace the value with .set(...).

total.set(10);

One of the most useful operations is .with(...), which applies a function to the current value and stores the updated result.

total.with(fn (x : int) -> int => x + 5);

This pattern is very common in concurrent worker code.

const worker := fn (score : int, total : &mut Mutex:<int>) => {
total.with(fn (x : int) -> int => x + score);
};

The stdlib Mutex API includes:

  • Mutex.new(...)
  • .get()
  • .set(...)
  • .with(...)
  • .write()
  • .swap(...)
  • .update(...)

For example, swap returns the previous value:

let old := total.swap(99);
print(old);

update(...) is useful when you want to express a transformation directly.

total.update(fn (x : int) -> int => x * 2);

Use channels when you want to move values between tasks, and use a mutex when several tasks need coordinated access to the same shared value.