Skip to content

Commit 99d7170

Browse files
authored
Prevent connection state monitor from being cancelled on disconnect (#246)
Closes #226
1 parent 3597853 commit 99d7170

1 file changed

Lines changed: 9 additions & 7 deletions

File tree

core/src/appleMain/kotlin/Peripheral.kt

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import kotlinx.coroutines.CoroutineScope
3434
import kotlinx.coroutines.CoroutineStart.LAZY
3535
import kotlinx.coroutines.CoroutineStart.UNDISPATCHED
3636
import kotlinx.coroutines.Deferred
37+
import kotlinx.coroutines.Job
3738
import kotlinx.coroutines.NonCancellable
3839
import kotlinx.coroutines.SupervisorJob
3940
import kotlinx.coroutines.async
@@ -95,6 +96,7 @@ public class ApplePeripheral internal constructor(
9596

9697
private val job = SupervisorJob(parentCoroutineContext.job) // todo: Disconnect/dispose CBPeripheral on completion?
9798
private val scope = CoroutineScope(parentCoroutineContext + job)
99+
private val connectionScope = CoroutineScope(scope.coroutineContext + Job(scope.coroutineContext[Job]))
98100

99101
private val centralManager: CentralManager = CentralManager.Default
100102

@@ -145,13 +147,13 @@ public class ApplePeripheral internal constructor(
145147
_connection.value = null
146148
}
147149

148-
private fun connectAsync() = scope.async(start = LAZY) {
150+
private fun connectAsync() = connectionScope.async(start = LAZY) {
149151
logger.info { message = "Connecting" }
150152
_state.value = State.Connecting.Bluetooth
151153

152154
centralManager.delegate.onDisconnected.onEach { identifier ->
153155
if (identifier == cbPeripheral.identifier) onDisconnected()
154-
}.launchIn(scope)
156+
}.launchIn(connectionScope)
155157

156158
try {
157159
// todo: Create in `connectPeripheral`.
@@ -173,7 +175,7 @@ public class ApplePeripheral internal constructor(
173175
)
174176
}
175177
.onEach(observers.characteristicChanges::emit)
176-
.launchIn(scope, start = UNDISPATCHED)
178+
.launchIn(connectionScope, start = UNDISPATCHED)
177179

178180
// fixme: Handle centralManager:didFailToConnectPeripheral:error:
179181
// https://developer.apple.com/documentation/corebluetooth/cbcentralmanagerdelegate/1518988-centralmanager
@@ -184,13 +186,13 @@ public class ApplePeripheral internal constructor(
184186
_state.value = State.Connecting.Observes
185187
logger.verbose { message = "Configuring characteristic observations" }
186188
observers.onConnected()
187-
} catch (t: Throwable) {
188-
logger.error(t) { message = "Failed to connect" }
189+
} catch (e: Exception) {
190+
logger.error(e) { message = "Failed to connect" }
189191
withContext(NonCancellable) {
190192
centralManager.cancelPeripheralConnection(cbPeripheral)
191193
_connection.value = null
192194
}
193-
throw t
195+
throw e
194196
}
195197

196198
logger.info { message = "Connected" }
@@ -203,7 +205,7 @@ public class ApplePeripheral internal constructor(
203205

204206
public override suspend fun disconnect() {
205207
try {
206-
scope.coroutineContext.job.cancelAndJoinChildren()
208+
connectionScope.coroutineContext.job.cancelAndJoinChildren()
207209
} finally {
208210
withContext(NonCancellable) {
209211
centralManager.cancelPeripheralConnection(cbPeripheral)

0 commit comments

Comments
 (0)