- 
                Notifications
    
You must be signed in to change notification settings  - Fork 1.9k
 
Closed
Labels
Description
The following code hangs forever on the call to mutex.unlock():
val mutex = Mutex()
(mutex as Semaphore).aquire()
println("locked: ${mutex.isLocked}")
mutex.unlock()
println("unlocked: ${!mutex.isLocked}")The reason seems to be that MutexImpl extends SemaphoreImpl but SemaphoreImpl.aquire() bypasses the invariants of MutexImpl.owner: aquire doesn't change owner but unlock spin loops because it expects to see something different than NO_OWNER.
Similar bugs might be possible with other combinations of Mutex and Semaphore calls for MutexImpl, I haven't checked yet.
Admittedly, this is a bit contrived, so I'm not sure if this is really a bug or just a missuse of implementatiom details (the public Mutex interface doesn't extend Semaphore). But if this is considered worth fixing I see two possible approaches:
- changing the behavior of the 
SemaphoreImplmethods (through override etc.) so they don't breakMutexImplinvariants - splitting up 
SemaphoreImplinto a new abstract base type for bothMutexandSemaphore(that however doesn't implementSemaphoredirectly) and a thin wrapper around it to actually implementSemaphore- that way interacting with instances ofMutexImplthrough the methods ofSemaphorewon't be possible in the first place