Commit f6ec072e authored by Mygod's avatar Mygod

Fix bandwidth listeners handled in wrong thread

parent 4da71a0b
...@@ -94,7 +94,7 @@ object BaseService { ...@@ -94,7 +94,7 @@ object BaseService {
} }
} }
class Binder(private var data: Data? = null) : IShadowsocksService.Stub(), AutoCloseable { class Binder(private var data: Data? = null) : IShadowsocksService.Stub(), CoroutineScope, AutoCloseable {
val callbacks = object : RemoteCallbackList<IShadowsocksServiceCallback>() { val callbacks = object : RemoteCallbackList<IShadowsocksServiceCallback>() {
override fun onCallbackDied(callback: IShadowsocksServiceCallback?, cookie: Any?) { override fun onCallbackDied(callback: IShadowsocksServiceCallback?, cookie: Any?) {
super.onCallbackDied(callback, cookie) super.onCallbackDied(callback, cookie)
...@@ -102,7 +102,8 @@ object BaseService { ...@@ -102,7 +102,8 @@ object BaseService {
} }
} }
private val bandwidthListeners = mutableMapOf<IBinder, Long>() // the binder is the real identifier private val bandwidthListeners = mutableMapOf<IBinder, Long>() // the binder is the real identifier
private val handler = Handler() override val coroutineContext = Dispatchers.Main.immediate + Job()
private var looper: Job? = null
override fun getState(): Int = (data?.state ?: State.Idle).ordinal override fun getState(): Int = (data?.state ?: State.Idle).ordinal
override fun getProfileName(): String = data?.proxy?.profile?.name ?: "Idle" override fun getProfileName(): String = data?.proxy?.profile?.name ?: "Idle"
...@@ -123,10 +124,9 @@ object BaseService { ...@@ -123,10 +124,9 @@ object BaseService {
callbacks.finishBroadcast() callbacks.finishBroadcast()
} }
private fun registerTimeout() { private suspend fun loop() {
handler.postDelayed(this::onTimeout, bandwidthListeners.values.min() ?: return) while (true) {
} delay(bandwidthListeners.values.min() ?: return)
private fun onTimeout() {
val proxies = listOfNotNull(data?.proxy, data?.udpFallback) val proxies = listOfNotNull(data?.proxy, data?.udpFallback)
val stats = proxies val stats = proxies
.map { Pair(it.profile.id, it.trafficMonitor?.requestUpdate()) } .map { Pair(it.profile.id, it.trafficMonitor?.requestUpdate()) }
...@@ -141,17 +141,21 @@ object BaseService { ...@@ -141,17 +141,21 @@ object BaseService {
} }
} }
} }
registerTimeout() }
} }
override fun startListeningForBandwidth(cb: IShadowsocksServiceCallback, timeout: Long) { override fun startListeningForBandwidth(cb: IShadowsocksServiceCallback, timeout: Long) {
launch {
val wasEmpty = bandwidthListeners.isEmpty() val wasEmpty = bandwidthListeners.isEmpty()
if (bandwidthListeners.put(cb.asBinder(), timeout) == null) { if (bandwidthListeners.put(cb.asBinder(), timeout) == null) {
if (wasEmpty) registerTimeout() if (wasEmpty) {
if (data?.state != State.Connected) return check(looper == null)
looper = launch { loop() }
}
if (data?.state != State.Connected) return@launch
var sum = TrafficStats() var sum = TrafficStats()
val data = data val data = data
val proxy = data?.proxy ?: return val proxy = data?.proxy ?: return@launch
proxy.trafficMonitor?.out.also { stats -> proxy.trafficMonitor?.out.also { stats ->
cb.trafficUpdated(proxy.profile.id, if (stats == null) sum else { cb.trafficUpdated(proxy.profile.id, if (stats == null) sum else {
sum += stats sum += stats
...@@ -169,10 +173,14 @@ object BaseService { ...@@ -169,10 +173,14 @@ object BaseService {
cb.trafficUpdated(0, sum) cb.trafficUpdated(0, sum)
} }
} }
}
override fun stopListeningForBandwidth(cb: IShadowsocksServiceCallback) { override fun stopListeningForBandwidth(cb: IShadowsocksServiceCallback) {
launch {
if (bandwidthListeners.remove(cb.asBinder()) != null && bandwidthListeners.isEmpty()) { if (bandwidthListeners.remove(cb.asBinder()) != null && bandwidthListeners.isEmpty()) {
handler.removeCallbacksAndMessages(null) looper!!.cancel()
looper = null
}
} }
} }
...@@ -194,7 +202,7 @@ object BaseService { ...@@ -194,7 +202,7 @@ object BaseService {
override fun close() { override fun close() {
callbacks.kill() callbacks.kill()
handler.removeCallbacksAndMessages(null) cancel()
data = null data = null
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment