From 04f82a03bfb5c9b1b6796d9fa17434236fd09e16 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Mon, 24 Mar 2025 14:21:22 +0600 Subject: [PATCH] add docs to SmartKeyRWLocker and SmartRWLocker --- .../micro_utils/coroutines/SmartKeyRWLocker.kt | 16 ++++++++++++++++ .../inmo/micro_utils/coroutines/SmartRWLocker.kt | 5 +++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/SmartKeyRWLocker.kt b/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/SmartKeyRWLocker.kt index 017e1c5009f..407eec5add4 100644 --- a/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/SmartKeyRWLocker.kt +++ b/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/SmartKeyRWLocker.kt @@ -7,6 +7,22 @@ import kotlin.contracts.ExperimentalContracts import kotlin.contracts.InvocationKind import kotlin.contracts.contract +/** + * Combining [globalRWLocker] and internal map of [SmartRWLocker] associated by [T] to provide next logic: + * + * * Locker by key, for reading: waiting for [globalRWLocker] unlock write by acquiring read permit in it and then + * taking or creating locker for key [T] and lock its reading too + * * Locker by key, for writing: waiting for [globalRWLocker] unlock write by acquiring read permit in it and then + * taking or creating locker for key [T] and lock its writing + * * [globalRWLocker], for reading: using [SmartRWLocker.acquireRead], will be suspended until its + * [SmartRWLocker.lockWrite] will not be unlocked + * * [globalRWLocker], for writing: using [SmartRWLocker.lockWrite], will be paused by other reading and writing + * operations and will pause other operations until the end of operation (calling of [unlockWrite]) + * + * You may see, that lockers by key still will use global locker permits - it is required to prevent [globalRWLocker] + * write locking during all other operations are not done. In fact, all the keys works like a simple [SmartRWLocker] as + * well, as [globalRWLocker], but they are linked with [globalRWLocker] [SmartRWLocker.acquireRead] permissions + */ class SmartKeyRWLocker( globalLockerReadPermits: Int = Int.MAX_VALUE, globalLockerWriteIsLocked: Boolean = false, diff --git a/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/SmartRWLocker.kt b/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/SmartRWLocker.kt index 60391978d81..aea220812cd 100644 --- a/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/SmartRWLocker.kt +++ b/coroutines/src/commonMain/kotlin/dev/inmo/micro_utils/coroutines/SmartRWLocker.kt @@ -8,9 +8,10 @@ import kotlin.contracts.contract /** * Composite mutex which works with next rules: * - * * [acquireRead] require to [writeMutex] be free. Then it will take one lock from [readSemaphore] + * * [acquireRead] require to [writeMutex] to be free. Then it will take one lock from [readSemaphore] * * [releaseRead] will just free up one permit in [readSemaphore] - * * [lockWrite] will lock [writeMutex] and then await while all [readSemaphore] will be freed + * * [lockWrite] will lock [writeMutex] and then await while all [readSemaphore] will be freed. If coroutine will be + * cancelled during read semaphore freeing, locking will be cancelled too with [SmartMutex.Mutable.unlock]ing of [writeMutex] * * [unlockWrite] will just unlock [writeMutex] */ class SmartRWLocker(private val readPermits: Int = Int.MAX_VALUE, writeIsLocked: Boolean = false) {