Skip to content

Rethink, consolidate and document Mutex's owner contract #3626

Open
@qwwdfsad

Description

@qwwdfsad

Mutex primitive provides the concept of ownership -- an additional token passed to every operation to ensure that the lock is not being operated with the same owner concurrently, catches (not supported) reentrancy and prevents logical races that are otherwise hard to debug.

Notably, every locking operation has the following note:

When owner is specified (non-null value) and this mutex is already locked with the same token (same identity), this function throws [IllegalStateException].

This contract makes sense in theory -- e.g. it deterministically prevents reentrancy issues and some trivial races, thus proving itself quite useful.
But it is much more complex in practice, for example, consider the following scenario:

mutex.lock(o1)
launch { mutex.lock(o2) }
launch { mutex.lock(o2) }
// ... sometimes later ...
mutex.unlock(o1)

This code works, though, depending on the interpretation, it should or should not throw IllegalStateException.
Things get more complicated when lock implementation is taken into account (tryLock + slow path) as well as when actual concurrency is present: detecting such scenarios in a robust and linearizable manner doesn't seem to be practical and requires O(n) operations (where n is a number of waiters).

We have to make a decision about the reasonable implementation complexity and thoroughly document the contract, even if we are going to leave it as is

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions