Skip to content

Commit

Permalink
Prevent connection state monitor from being cancelled on disconnect (#…
Browse files Browse the repository at this point in the history
…246)

Closes #226
  • Loading branch information
twyatt authored Jan 18, 2022
1 parent 3597853 commit 99d7170
Showing 1 changed file with 9 additions and 7 deletions.
16 changes: 9 additions & 7 deletions core/src/appleMain/kotlin/Peripheral.kt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart.LAZY
import kotlinx.coroutines.CoroutineStart.UNDISPATCHED
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.Job
import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.async
Expand Down Expand Up @@ -95,6 +96,7 @@ public class ApplePeripheral internal constructor(

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

private val centralManager: CentralManager = CentralManager.Default

Expand Down Expand Up @@ -145,13 +147,13 @@ public class ApplePeripheral internal constructor(
_connection.value = null
}

private fun connectAsync() = scope.async(start = LAZY) {
private fun connectAsync() = connectionScope.async(start = LAZY) {
logger.info { message = "Connecting" }
_state.value = State.Connecting.Bluetooth

centralManager.delegate.onDisconnected.onEach { identifier ->
if (identifier == cbPeripheral.identifier) onDisconnected()
}.launchIn(scope)
}.launchIn(connectionScope)

try {
// todo: Create in `connectPeripheral`.
Expand All @@ -173,7 +175,7 @@ public class ApplePeripheral internal constructor(
)
}
.onEach(observers.characteristicChanges::emit)
.launchIn(scope, start = UNDISPATCHED)
.launchIn(connectionScope, start = UNDISPATCHED)

// fixme: Handle centralManager:didFailToConnectPeripheral:error:
// https://developer.apple.com/documentation/corebluetooth/cbcentralmanagerdelegate/1518988-centralmanager
Expand All @@ -184,13 +186,13 @@ public class ApplePeripheral internal constructor(
_state.value = State.Connecting.Observes
logger.verbose { message = "Configuring characteristic observations" }
observers.onConnected()
} catch (t: Throwable) {
logger.error(t) { message = "Failed to connect" }
} catch (e: Exception) {
logger.error(e) { message = "Failed to connect" }
withContext(NonCancellable) {
centralManager.cancelPeripheralConnection(cbPeripheral)
_connection.value = null
}
throw t
throw e
}

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

public override suspend fun disconnect() {
try {
scope.coroutineContext.job.cancelAndJoinChildren()
connectionScope.coroutineContext.job.cancelAndJoinChildren()
} finally {
withContext(NonCancellable) {
centralManager.cancelPeripheralConnection(cbPeripheral)
Expand Down

0 comments on commit 99d7170

Please sign in to comment.