Skip to content

Commit ce8951f

Browse files
authored
Replace Semaphore with Mutex in Connection (#490)
1 parent c79fd29 commit ce8951f

2 files changed

Lines changed: 7 additions & 9 deletions

File tree

core/src/appleMain/kotlin/Connection.kt

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import kotlinx.coroutines.Deferred
88
import kotlinx.coroutines.Job
99
import kotlinx.coroutines.async
1010
import kotlinx.coroutines.cancel
11-
import kotlinx.coroutines.sync.Semaphore
12-
import kotlinx.coroutines.sync.withPermit
11+
import kotlinx.coroutines.sync.Mutex
12+
import kotlinx.coroutines.sync.withLock
1313
import kotlin.coroutines.CoroutineContext
1414

1515
internal class Connection(
@@ -23,14 +23,12 @@ internal class Connection(
2323

2424
private val logger = Logger(logging, tag = "Kable/Connection", identifier = identifier)
2525

26-
// Using Semaphore as Mutex never relinquished lock when multiple concurrent `withLock`s are executed.
27-
val semaphore = Semaphore(1)
28-
2926
private var deferredResponse: Deferred<PeripheralDelegate.Response>? = null
27+
val guard = Mutex()
3028

3129
suspend inline fun <T> execute(
3230
action: () -> Unit,
33-
): T = semaphore.withPermit {
31+
): T = guard.withLock {
3432
deferredResponse?.let {
3533
if (it.isActive) {
3634
// Discard response as we've performed another `execute` without the previous finishing. This happens if

core/src/appleMain/kotlin/Peripheral.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ import kotlinx.coroutines.flow.onEach
4343
import kotlinx.coroutines.flow.onSubscription
4444
import kotlinx.coroutines.flow.updateAndGet
4545
import kotlinx.coroutines.job
46-
import kotlinx.coroutines.sync.withPermit
46+
import kotlinx.coroutines.sync.withLock
4747
import kotlinx.coroutines.withContext
4848
import platform.CoreBluetooth.CBCharacteristicWriteWithResponse
4949
import platform.CoreBluetooth.CBCharacteristicWriteWithoutResponse
@@ -283,7 +283,7 @@ internal class CBPeripheralCoreBluetoothPeripheral(
283283
WithResponse -> connection.execute<DidWriteValueForCharacteristic> {
284284
centralManager.write(cbPeripheral, data, platformCharacteristic, CBCharacteristicWriteWithResponse)
285285
}
286-
WithoutResponse -> connection.semaphore.withPermit {
286+
WithoutResponse -> connection.guard.withLock {
287287
if (!canSendWriteWithoutResponse.updateAndGet { cbPeripheral.canSendWriteWithoutResponse }) {
288288
canSendWriteWithoutResponse.first { it }
289289
}
@@ -308,7 +308,7 @@ internal class CBPeripheralCoreBluetoothPeripheral(
308308

309309
val platformCharacteristic = discoveredServices.obtain(characteristic, Read)
310310

311-
val event = connection.semaphore.withPermit {
311+
val event = connection.guard.withLock {
312312
observers
313313
.characteristicChanges
314314
.onSubscription { centralManager.read(cbPeripheral, platformCharacteristic) }

0 commit comments

Comments
 (0)