Date: Wed, 13 Sep 2023 09:55:14 +0400
Postcondition of std::lock and std::try_lock:
All of Mutexes... are locked, no deadlock occurs.
*Effects*: All arguments are locked via a sequence of calls to lock(), try_
lock(), or unlock() on each argument.
<https://eel.is/c++draft/thread.lock.algorithm#5.sentence-1>
The sequence of calls does not result in deadlock, but is otherwise
unspecified. <https://eel.is/c++draft/thread.lock.algorithm#5.sentence-2>
But in an common case, when there is a type with a mutex and you need to
swap it
void swap(Type& other) {
std::scoped_lock l(this->mutex, other.mutex);
// ... do swap ...
}
If addressof(other) == this same mutex will be locked, and there are no
precondition which blocks this usage.
But in fact its undefined behavior (implementation uses try_lock on already
locked mutex) (deadlock on msvc-stl, just ub on others)
There are several solutions to this, either we explicitly add precondition,
or the implementation must handle this (then there could potentially be an
overhead when unlocking)
All of Mutexes... are locked, no deadlock occurs.
*Effects*: All arguments are locked via a sequence of calls to lock(), try_
lock(), or unlock() on each argument.
<https://eel.is/c++draft/thread.lock.algorithm#5.sentence-1>
The sequence of calls does not result in deadlock, but is otherwise
unspecified. <https://eel.is/c++draft/thread.lock.algorithm#5.sentence-2>
But in an common case, when there is a type with a mutex and you need to
swap it
void swap(Type& other) {
std::scoped_lock l(this->mutex, other.mutex);
// ... do swap ...
}
If addressof(other) == this same mutex will be locked, and there are no
precondition which blocks this usage.
But in fact its undefined behavior (implementation uses try_lock on already
locked mutex) (deadlock on msvc-stl, just ub on others)
There are several solutions to this, either we explicitly add precondition,
or the implementation must handle this (then there could potentially be an
overhead when unlocking)
Received on 2023-09-13 05:55:27