The following pattern is common but impossible with closure based API (at least for now):
let valueA: A
let valueB: B
let valueC: C
mutex.withLock {
valueA = ...
valueB = ...
valueC = ...
}
Are there any workarounds except returning a large tuple or using variables of implicitlyUnwrapedOptional types instead of let
? Or is it recommended to wait for Mutex.Guard
API?
As @FranzBusch mentioned above – "One thing that surprised me in the proposed API is the requirement for the Result
of both with
methods to be Sendable
."
I want to clarify some points:
- It may be feasible to allow returning non-Sendable value if its Type != State
let mutex: Mutex<NonSendableA> = ...
let value = mutex.withLock { state in
return NonSendableB(state.property)
}
let value2 = mutex.withLock { state in
let foo = Int.random()
state.updateWith(foo)
return NonSendableB(foo)
}
Any plans?
2. What if we try to simply return the state?
mutex.withLock { state in
return state
}
This case varies whether the Sendable constraint is lifted and / or Result become transferable. Nevertheless, it is possible the State
to be a Sendable and move-only-Type.
3. If I understand it the right way, move-only ~Copyable
types are not copied implicitly by compiler. Having a mutex with move-only type, what happens if we try to explicitly copy the state or the Mutex itself? In other words words, is there a way to make a copy explicitly or compiler will ultimately deny such attempts?
The last one is about mutability
. Mutex will be decorated with the @_staticExclusiveOnly
, so it is impossible to declare a var
.
How then willSet
/ didSet
observers can be done?
Will it trigger set
/ get
of enclosing instance?
struct Foo {
let state: Mutex<State>
}
let foo = Foo() // immutable
foo.state.withLock { ... } // is it allowed or a compiler error?
var foo2: Foo {
get {}
set {}
}
foo2.state.withLock { ... } // will it trigger `get / set`?