
Shared.pudu
Pudu39 lines1.3 KB
1/** @Utils.Shared.Module — mutable state shared between threads */2module PuduLangResilience.Utils.Shared34import Std.Sync as Sync56/** @Utils.Shared.Shared — a value changed only under its lock */7export type Shared[S] = { lock: Sync.Mutex, held: Sync.Cell[S] }8910export fn shared[S](initial: S) -> Shared[S] { Shared{lock: Sync.mutex(), held: Sync.cell(initial)} }111213export fn current[S](source: &Shared[S]) -> S {14 match Sync.get(&source.held) {15 case Ok(value) => value16 case Err(problem) => panic("shared state could not be read: " + show(problem))17 }18}19202122export fn change[S, R](target: &Shared[S], step: fn(S) -> (S, R)) -> R {23 let held = target.held24 let outcome = Sync.withLock(&target.lock, fn() -> R {25 let next = step(current(target))26 let _stored = Sync.set(&held, next[0])27 next[1]28 })29 match outcome {30 case Ok(answer) => answer31 case Err(problem) => panic("shared state could not be locked: " + show(problem))32 }33}343536export fn update[S](target: &Shared[S], step: fn(S) -> S) -> () {37 change(target, fn(value: S) -> (S, ()) { (step(value), ()) })38}39