summaryrefslogtreecommitdiffhomepage
path: root/android/src
diff options
context:
space:
mode:
authorJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2021-01-25 17:43:18 +0000
committerJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2021-02-11 14:36:18 +0000
commit1ec10358c88dfa7e144e7bc185951cda47d5dc1d (patch)
tree44a822c605854bb6538310d8d2ba24302a28eb71 /android/src
parentc823fb016fdb33f2d501b97d6ebc3cc0536a8724 (diff)
downloadmullvadvpn-1ec10358c88dfa7e144e7bc185951cda47d5dc1d.tar.xz
mullvadvpn-1ec10358c88dfa7e144e7bc185951cda47d5dc1d.zip
Allow listening to intermittent value changes
Diffstat (limited to 'android/src')
-rw-r--r--android/src/main/kotlin/net/mullvad/mullvadvpn/util/Intermittent.kt21
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()
+ }
}