From fba3ea44650ab896c0062631b6f9306edece88a5 Mon Sep 17 00:00:00 2001 From: Patryk Goworowski Date: Sun, 11 Aug 2024 14:19:38 +0200 Subject: [PATCH] Synchronize registrations in `ChartEntryModelProducer` Co-authored-by: Patrick Michalik <120058021+patrickmichalik@users.noreply.github.com> --- .../core/entry/ChartEntryModelProducer.kt | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/vico/core/src/main/java/com/patrykandpatrick/vico/core/entry/ChartEntryModelProducer.kt b/vico/core/src/main/java/com/patrykandpatrick/vico/core/entry/ChartEntryModelProducer.kt index 9752d8775..1ceb1eca5 100644 --- a/vico/core/src/main/java/com/patrykandpatrick/vico/core/entry/ChartEntryModelProducer.kt +++ b/vico/core/src/main/java/com/patrykandpatrick/vico/core/entry/ChartEntryModelProducer.kt @@ -32,7 +32,10 @@ import kotlinx.coroutines.awaitAll import kotlinx.coroutines.currentCoroutineContext import kotlinx.coroutines.ensureActive import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock +import java.util.concurrent.ConcurrentHashMap /** * A [ChartModelProducer] implementation that generates [ChartEntryModel] instances. @@ -51,8 +54,9 @@ public class ChartEntryModelProducer( private var cachedInternalModel: InternalModel? = null private val mutex = Mutex() private val coroutineScope = CoroutineScope(dispatcher) - private val updateReceivers: HashMap = HashMap() + private val updateReceivers = ConcurrentHashMap() private val extraStore = MutableExtraStore() + private val registrationLock = Mutex() public constructor( vararg entryCollections: List, @@ -74,11 +78,14 @@ public class ChartEntryModelProducer( series = entries.copy() updateExtras(extraStore) cachedInternalModel = null - val deferredUpdates = updateReceivers.values.map { updateReceiver -> - coroutineScope.async { updateReceiver.handleUpdate() } - } coroutineScope.launch { + registrationLock.lock() + val deferredUpdates = updateReceivers.values.map { updateReceiver -> + async { updateReceiver.handleUpdate() } + } + deferredUpdates.awaitAll() + registrationLock.unlock() mutex.unlock() } return true @@ -200,8 +207,12 @@ public class ChartEntryModelProducer( getOldModel, updateChartValues, ).run { - updateReceivers[key] = this - handleUpdate() + runBlocking { + registrationLock.withLock { + updateReceivers[key] = this@run + handleUpdate() + } + } } }