Locking around UP registration, #230

This commit is contained in:
Philipp Heckel 2022-05-03 18:01:00 -04:00
parent a2551bc7f0
commit 821a1ac222
2 changed files with 65 additions and 49 deletions

View file

@ -11,7 +11,10 @@ import io.heckel.ntfy.util.randomString
import io.heckel.ntfy.util.topicUrlUp import io.heckel.ntfy.util.topicUrlUp
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import java.util.* import java.util.*
import kotlin.random.Random import kotlin.random.Random
@ -44,6 +47,10 @@ class BroadcastReceiver : android.content.BroadcastReceiver() {
return return
} }
GlobalScope.launch(Dispatchers.IO) { GlobalScope.launch(Dispatchers.IO) {
// We're doing all of this inside a critical section, because of possible races.
// See https://github.com/binwiederhier/ntfy/issues/230 for details.
mutex.withLock {
val existingSubscription = repository.getSubscriptionByConnectorToken(connectorToken) val existingSubscription = repository.getSubscriptionByConnectorToken(connectorToken)
if (existingSubscription != null) { if (existingSubscription != null) {
if (existingSubscription.upAppId == appId) { if (existingSubscription.upAppId == appId) {
@ -87,6 +94,7 @@ class BroadcastReceiver : android.content.BroadcastReceiver() {
} }
} }
} }
}
private fun unregister(context: Context, intent: Intent) { private fun unregister(context: Context, intent: Intent) {
val connectorToken = intent.getStringExtra(EXTRA_TOKEN) ?: return val connectorToken = intent.getStringExtra(EXTRA_TOKEN) ?: return
@ -95,6 +103,10 @@ class BroadcastReceiver : android.content.BroadcastReceiver() {
val distributor = Distributor(app) val distributor = Distributor(app)
Log.d(TAG, "UNREGISTER received (connectorToken=$connectorToken)") Log.d(TAG, "UNREGISTER received (connectorToken=$connectorToken)")
GlobalScope.launch(Dispatchers.IO) { GlobalScope.launch(Dispatchers.IO) {
// We're doing all of this inside a critical section, because of possible races.
// See https://github.com/binwiederhier/ntfy/issues/230 for details.
mutex.withLock {
val existingSubscription = repository.getSubscriptionByConnectorToken(connectorToken) val existingSubscription = repository.getSubscriptionByConnectorToken(connectorToken)
if (existingSubscription == null) { if (existingSubscription == null) {
Log.d(TAG, "Subscription with connectorToken $connectorToken does not exist. Ignoring.") Log.d(TAG, "Subscription with connectorToken $connectorToken does not exist. Ignoring.")
@ -110,10 +122,13 @@ class BroadcastReceiver : android.content.BroadcastReceiver() {
SubscriberServiceManager.refresh(context) SubscriberServiceManager.refresh(context)
} }
} }
}
companion object { companion object {
private const val TAG = "NtfyUpBroadcastRecv" private const val TAG = "NtfyUpBroadcastRecv"
private const val UP_PREFIX = "up" private const val UP_PREFIX = "up"
private const val TOPIC_RANDOM_ID_LENGTH = 12 private const val TOPIC_RANDOM_ID_LENGTH = 12
val mutex = Mutex() // https://github.com/binwiederhier/ntfy/issues/230
} }
} }

View file

@ -6,6 +6,7 @@ Bugs:
* Make messages with links selectable (#226, thanks to @StoyanDimitrov for reporting) * Make messages with links selectable (#226, thanks to @StoyanDimitrov for reporting)
* Restoring topics or settings from backup doesn't work (#223, thanks to @shadow00 for reporting) * Restoring topics or settings from backup doesn't work (#223, thanks to @shadow00 for reporting)
* Fix app icon on old Android versions (#120, thanks to @shadow00 for reporting) * Fix app icon on old Android versions (#120, thanks to @shadow00 for reporting)
* Fix races in UnifiedPush registration (#230, thanks to @Jakob for reporting)
**Thanks for testing:** **Thanks for testing:**