@@ -18,6 +18,8 @@ package org.matrix.android.sdk.internal.crypto
1818
1919import kotlinx.coroutines.CoroutineScope
2020import kotlinx.coroutines.launch
21+ import kotlinx.coroutines.sync.Mutex
22+ import kotlinx.coroutines.sync.withLock
2123import kotlinx.coroutines.withContext
2224import org.matrix.android.sdk.api.MatrixCallback
2325import org.matrix.android.sdk.api.MatrixCoroutineDispatchers
@@ -68,6 +70,7 @@ internal class EventDecryptor @Inject constructor(
6870 val senderKey : String?
6971 )
7072
73+ private val wedgedMutex = Mutex ()
7174 private val wedgedDevices = mutableListOf<WedgedDeviceInfo >()
7275
7376 /* *
@@ -151,11 +154,13 @@ internal class EventDecryptor @Inject constructor(
151154 }
152155 }
153156
154- private fun markOlmSessionForUnwedging (senderId : String , senderKey : String ) {
155- val info = WedgedDeviceInfo (senderId, senderKey)
156- if (! wedgedDevices.contains(info)) {
157- Timber .tag(loggerTag.value).d(" Marking device from $senderId key:$senderKey as wedged" )
158- wedgedDevices.add(info)
157+ private suspend fun markOlmSessionForUnwedging (senderId : String , senderKey : String ) {
158+ wedgedMutex.withLock {
159+ val info = WedgedDeviceInfo (senderId, senderKey)
160+ if (! wedgedDevices.contains(info)) {
161+ Timber .tag(loggerTag.value).d(" Marking device from $senderId key:$senderKey as wedged" )
162+ wedgedDevices.add(info)
163+ }
159164 }
160165 }
161166
@@ -167,15 +172,17 @@ internal class EventDecryptor @Inject constructor(
167172 Timber .tag(loggerTag.value).v(" Unwedging: ${wedgedDevices.size} are wedged" )
168173 // get the one that should be retried according to rate limit
169174 val now = clock.epochMillis()
170- val toUnwedge = wedgedDevices.filter {
171- val lastForcedDate = lastNewSessionForcedDates[it] ? : 0
172- if (now - lastForcedDate < DefaultCryptoService .CRYPTO_MIN_FORCE_SESSION_PERIOD_MILLIS ) {
173- Timber .tag(loggerTag.value).d(" Unwedging, New session for $it already forced with device at $lastForcedDate " )
174- return @filter false
175+ val toUnwedge = wedgedMutex.withLock {
176+ wedgedDevices.filter {
177+ val lastForcedDate = lastNewSessionForcedDates[it] ? : 0
178+ if (now - lastForcedDate < DefaultCryptoService .CRYPTO_MIN_FORCE_SESSION_PERIOD_MILLIS ) {
179+ Timber .tag(loggerTag.value).d(" Unwedging, New session for $it already forced with device at $lastForcedDate " )
180+ return @filter false
181+ }
182+ // let's already mark that we tried now
183+ lastNewSessionForcedDates[it] = now
184+ true
175185 }
176- // let's already mark that we tried now
177- lastNewSessionForcedDates[it] = now
178- true
179186 }
180187
181188 if (toUnwedge.isEmpty()) {
@@ -230,6 +237,15 @@ internal class EventDecryptor @Inject constructor(
230237 withContext(coroutineDispatchers.io) {
231238 sendToDeviceTask.executeRetry(sendToDeviceParams, remainingRetry = SEND_TO_DEVICE_RETRY_COUNT )
232239 }
240+
241+ deviceList.values.flatten().forEach { deviceInfo ->
242+ wedgedMutex.withLock {
243+ wedgedDevices.removeAll {
244+ it.senderKey == deviceInfo.identityKey() &&
245+ it.userId == deviceInfo.userId
246+ }
247+ }
248+ }
233249 } catch (failure: Throwable ) {
234250 deviceList.flatMap { it.value }.joinToString { it.shortDebugString() }.let {
235251 Timber .tag(loggerTag.value).e(failure, " ## Failed to unwedge devices: $it }" )
0 commit comments