diff options
Diffstat (limited to 'android/src')
| -rw-r--r-- | android/src/main/kotlin/net/mullvad/mullvadvpn/util/Intermittent.kt | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/android/src/main/kotlin/net/mullvad/mullvadvpn/util/Intermittent.kt b/android/src/main/kotlin/net/mullvad/mullvadvpn/util/Intermittent.kt index 2578ef78e5..15e39d7c19 100644 --- a/android/src/main/kotlin/net/mullvad/mullvadvpn/util/Intermittent.kt +++ b/android/src/main/kotlin/net/mullvad/mullvadvpn/util/Intermittent.kt @@ -9,6 +9,7 @@ import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.Semaphore import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.sync.withPermit +import net.mullvad.talpid.util.EventNotifier // Wrapper to allow awaiting for intermittent values. // @@ -21,13 +22,24 @@ import kotlinx.coroutines.sync.withPermit // // Calling `update` will set the internal value after it guarantees that no other coroutine is // currently reading the value (through a permit from the semaphore). After the value is set, it -// provides a premit to the semaphore so that suspended coroutines can use the new value. +// provides a permit to the semaphore so that suspended coroutines can use the new value. +// +// Extra initialization can be done on the intermittent value when it becomes available and before +// it is provided to the awaiting coroutines, through the use of listener callbacks. These are +// called after the value is updated but before it is made available to the coroutines. class Intermittent<T> { + private val notifier = EventNotifier<T?>(null) private val semaphore = Semaphore(1, 1) private val writeLock = Mutex() private var updateJob: Job? = null - private var value: T? = null + private var value by notifier.notifiable() + + // When the internal value is updated, listeners can be notified before the awaiting coroutines + // resume execution. This allows performing any extra initialization before the value is made + // available for usage. + fun registerListener(id: Any, listener: (T?) -> Unit) = notifier.subscribe(id, listener) + fun unregisterListener(id: Any) = notifier.unsubscribe(id) suspend fun await(): T { return semaphore.withPermit { value!! } @@ -40,6 +52,7 @@ class Intermittent<T> { semaphore.acquire() } + // This will trigger the listeners to run before the awaiting coroutines resume value = newValue if (newValue != null) { @@ -63,4 +76,8 @@ class Intermittent<T> { } } } + + fun onDestroy() { + notifier.unsubscribeAll() + } } |
