preserve concurrency constructor validation

This commit is contained in:
2026-10-10 14:25:54 +06:00
parent 63d66228ab
commit 761b14dc65
4 changed files with 29 additions and 2 deletions

View File

@@ -2,6 +2,16 @@
## 0.32.0
* `Coroutines`:
* `SmartSemaphore`:
* Rewrite docs for `freePermits` property.
* Add constructor arguments requirements to fail on invalid `permits` and `acquiredPermits` values.
* `SmartRWLocker`:
* Add constructor arguments requirements to fail on invalid `readPermits` values.
* `SmartKeyRWLocker`:
* Add constructor arguments requirements to fail on invalid `globalLockerReadPermits` and `perKeyReadPermits` values.
## 0.31.1
* `Coroutines`:

View File

@@ -28,6 +28,11 @@ class SmartKeyRWLocker<T>(
globalLockerWriteIsLocked: Boolean = false,
private val perKeyReadPermits: Int = Int.MAX_VALUE
) {
init {
require(globalLockerReadPermits > 0) { "The maximal number 'globalLockerReadPermits' of global permits on reading ($globalLockerReadPermits) must be positive." }
require(perKeyReadPermits > 0) { "The maximal number 'perKeyReadPermits' of permits on reading per key ($perKeyReadPermits) must be positive." }
}
private val globalRWLocker: SmartRWLocker = SmartRWLocker(
readPermits = globalLockerReadPermits,
writeIsLocked = globalLockerWriteIsLocked

View File

@@ -17,6 +17,10 @@ import kotlin.contracts.contract
* * [unlockWrite] will just unlock [writeMutex]
*/
class SmartRWLocker(private val readPermits: Int = Int.MAX_VALUE, writeIsLocked: Boolean = false) {
init {
require(readPermits > 0) { "The maximal number 'readPermits' of permits on reading ($readPermits) must be positive." }
}
private val _readSemaphore = SmartSemaphore.Mutable(permits = readPermits, acquiredPermits = if (writeIsLocked) readPermits else 0)
private val _writeMutex = SmartMutex.Mutable(locked = writeIsLocked)

View File

@@ -29,8 +29,10 @@ sealed interface SmartSemaphore {
val permitsStateFlow: StateFlow<Int>
/**
* * True - locked
* * False - unlocked
* The number of the available permits.
*
* If returns `0`, it is fully acquired (locked).
* If it returns the same value as `maxPermits`, it is fully released (unlocked).
*/
val freePermits: Int
get() = permitsStateFlow.value
@@ -47,6 +49,12 @@ sealed interface SmartSemaphore {
* @param locked Preset state of [freePermits] and its internal [_freePermitsStateFlow]
*/
class Mutable(permits: Int, acquiredPermits: Int = 0) : SmartSemaphore {
init {
require(permits > 0) { "The maximal number 'permits' of permits ($permits) must be positive." }
require(acquiredPermits >= 0) { "The number 'acquiredPermits' of initially acquired permits ($acquiredPermits) must be non-negative." }
require(permits >= acquiredPermits) { "The number 'acquiredPermits' of acquired initially permits ($acquiredPermits) must not exceed the maximal number 'permits' of permits ($permits)." }
}
override val maxPermits: Int = permits
private val _freePermitsStateFlow = MutableRedeliverStateFlow<Int>(permits - acquiredPermits)
override val permitsStateFlow: StateFlow<Int> = _freePermitsStateFlow.asStateFlow()