mutex_update
result = mutex_update(m, "fnName")
Input: m, "fnName" · Output: result
What it is
Atomic read-modify-write via an arbitrary user function called with the current value as its one argument — for accumulations mutex_add can't express (a running max, an append-only log). m is a Mutex handle; "fnName" (string) names a one-argument user-defined function whose return value becomes the mutex's new stored value. The lock is held for the whole call, so fnName's body must not touch this same mutex itself, directly or indirectly — that deadlocks.
Overloads
One call shape — this function is not overloaded.
| Code | Input | Output | Description |
result = mutex_update(m, "fnName") | m Mutexm is a Mutex handle."fnName" string"fnName" (string) names a one-argument user-defined function whose return value becomes the mutex's new stored value. | result — | Returns the new value (whatever fnName returned). |
Examples
From the documentation, and run by the build -- the output and the figure below are what the engine actually produced. Simplest first.
running_max(current) := max(current, 7)
m = mutex(0)
mutex_set(m, 3) # overwrite -- no read involved
mutex_update(m, "running_max") # atomic read-modify-write via a user fn
print(mutex_get(m)) # 7
7
from concurrency
How it works
mutex_update(m, "fnName") — atomic read-modify-write via an arbitrary user function (called with the current value as its one argument), for accumulations mutex_add can't express (e.g. tracking a running max, appending to a log). The lock is held for the whole call, so fnName's body must not itself touch this same mutex (directly or by calling back into anything that does) — that would deadlock, the same way any mutex reentered from inside its own critical section would.
From the note above this builtin in the interpreter, where the reasoning was written down as it was built.