Scope guards that borrow the supplied object, temporarily acquire or release its locking, and perform the opposite operation on destruction.


Guard model

Fields

The guard holds a view of the supplied object; it does not copy or own that object. An in-place argument remains a separately owned value in the enclosing scope. The object must remain alive at the same address until the guard is destroyed. A factory may return a guard over a caller-owned object, but not over an object local to the factory.

Guard contracts

Method contract

Lifetime

Compatibility


lockGuard

(object -- guard) Calls lock and returns a guard that calls unlock on destruction.

lockSharedGuard

(object -- guard) Calls lockShared and returns a guard that calls unlockShared on destruction.

unlockGuard

(object -- guard) Calls unlock and returns a guard that calls lock on destruction.

unlockSharedGuard

(object -- guard) Calls unlockShared and returns a guard that calls lockShared on destruction.

Examples

The example passes Ref to each DummyLock local so each guard operates on that existing local object.

Compile-time guard transitions

"control"   use
"lockGuard" use

DummyLock: [{
  state: 0i32;
  lock: [1 !state];
  unlock: [0 !state];
  lockShared: [2 !state];
  unlockShared: [0 !state];
}];

{} () {} [
  a: DummyLock;
  @a lockGuard drop
  a.state printStack _:;

  b: DummyLock;
  @b lockSharedGuard drop
  b.state printStack _:;

  c: DummyLock;
  1 @c.!state
  @c unlockGuard drop
  c.state printStack _:;

  d: DummyLock;
  2 @d.!state
  @d unlockSharedGuard drop
  d.state printStack _:;
] "main" exportFunction

Expected Output During Compilation

1 Cref
2 Cref
0 Cref
0 Cref

Runtime example

"String"    use
"control"   use
"lockGuard" use

DummyLock: [{
  state: 0i32;
  lock: [1 !state];
  unlock: [0 !state];
  lockShared: [2 !state];
  unlockShared: [0 !state];
}];

{} Int32 {} [
  a: DummyLock;
  [
    g0: @a lockGuard;
    ("locked=" a.state LF) printList
  ] call
  ("unlocked=" a.state LF) printList

  b: DummyLock;
  1 @b.!state
  [
    g1: @b unlockGuard;
    ("released=" b.state LF) printList
  ] call
  ("relocked=" b.state LF) printList
  0
] "main" exportFunction

Expected Output

locked=1
unlocked=0
released=0
relocked=1

See also