Skip to content

Commit 14328d1

Browse files
Francesco Vascoelizarov
authored andcommitted
Add Mutex.holdsLock
1 parent e1f89db commit 14328d1

File tree

2 files changed

+49
-0
lines changed
  • kotlinx-coroutines-core/src
    • main/kotlin/kotlinx/coroutines/experimental/sync
    • test/kotlin/kotlinx/coroutines/experimental/sync

2 files changed

+49
-0
lines changed

kotlinx-coroutines-core/src/main/kotlin/kotlinx/coroutines/experimental/sync/Mutex.kt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,13 @@ public interface Mutex {
9191
public fun <R> registerSelectLock(select: SelectInstance<R>, owner: Any?, block: suspend () -> R)
9292

9393
/**
94+
* Checks mutex locked by owner
95+
*
96+
* @return `true` on mutex lock by owner, `false` if not locker or it is locked by different owner
97+
*/
98+
public fun holdsLock(owner: Any): Boolean
99+
100+
/**
94101
* Unlocks this mutex. Throws [IllegalStateException] if invoked on a mutex that is not locked.
95102
*
96103
* @param owner Optional owner token for debugging. When `owner` is specified (non-null value) and this mutex
@@ -325,6 +332,15 @@ internal class MutexImpl(locked: Boolean) : Mutex {
325332
}
326333
}
327334

335+
public override fun holdsLock(owner: Any) =
336+
_state.value.let { state ->
337+
when (state) {
338+
is Empty -> state.locked === owner
339+
is LockedQueue -> state.owner === owner
340+
else -> false
341+
}
342+
}
343+
328344
public override fun unlock(owner: Any?) {
329345
_state.loop { state ->
330346
when (state) {

kotlinx-coroutines-core/src/test/kotlin/kotlinx/coroutines/experimental/sync/MutexTest.kt

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,37 @@ class MutexTest : TestBase() {
107107
mutex.unlock() // should not produce StackOverflowError
108108
assertThat(done, IsEqual(waiters))
109109
}
110+
111+
@Test
112+
fun holdLock() = runBlocking {
113+
val mutex = Mutex()
114+
val firstOwner = Any()
115+
val secondOwner = Any()
116+
117+
// no lock
118+
assertFalse(mutex.holdsLock(firstOwner))
119+
assertFalse(mutex.holdsLock(secondOwner))
120+
121+
// owner firstOwner
122+
mutex.lock(firstOwner)
123+
val secondLockJob = launch(CommonPool) {
124+
mutex.lock(secondOwner)
125+
}
126+
127+
assertTrue(mutex.holdsLock(firstOwner))
128+
assertFalse(mutex.holdsLock(secondOwner))
129+
130+
// owner secondOwner
131+
mutex.unlock(firstOwner)
132+
secondLockJob.join()
133+
134+
assertFalse(mutex.holdsLock(firstOwner))
135+
assertTrue(mutex.holdsLock(secondOwner))
136+
137+
mutex.unlock(secondOwner)
138+
139+
// no lock
140+
assertFalse(mutex.holdsLock(firstOwner))
141+
assertFalse(mutex.holdsLock(secondOwner))
142+
}
110143
}

0 commit comments

Comments
 (0)