Fix potential lock due to nested `synchronized(unknownSessionsFailure)`

This commit is contained in:
Benoit Marty 2019-10-22 14:20:43 +02:00
parent 3abce34484
commit 78dfd6b3e6
1 changed files with 15 additions and 12 deletions

View File

@ -38,15 +38,14 @@ internal class TimelineEventDecryptor(
private val newSessionListener = object : NewSessionListener { private val newSessionListener = object : NewSessionListener {
override fun onNewSession(roomId: String?, senderKey: String, sessionId: String) { override fun onNewSession(roomId: String?, senderKey: String, sessionId: String) {
synchronized(unknownSessionsFailure) { synchronized(unknownSessionsFailure) {
val toDecryptAgain = ArrayList<String>() unknownSessionsFailure[sessionId]
val eventIds = unknownSessionsFailure[sessionId] .orEmpty()
if (eventIds != null) toDecryptAgain.addAll(eventIds) .toList()
if (toDecryptAgain.isNotEmpty()) { .also {
eventIds?.clear() unknownSessionsFailure[sessionId]?.clear()
toDecryptAgain.forEach { }
requestDecryption(it) }.forEach {
} requestDecryption(it)
}
} }
} }
} }
@ -67,8 +66,12 @@ internal class TimelineEventDecryptor(
cryptoService.removeSessionListener(newSessionListener) cryptoService.removeSessionListener(newSessionListener)
executor?.shutdownNow() executor?.shutdownNow()
executor = null executor = null
unknownSessionsFailure.clear() synchronized(unknownSessionsFailure) {
existingRequests.clear() unknownSessionsFailure.clear()
}
synchronized(existingRequests) {
existingRequests.clear()
}
} }
fun requestDecryption(eventId: String) { fun requestDecryption(eventId: String) {
@ -108,7 +111,7 @@ internal class TimelineEventDecryptor(
eventEntity.setDecryptionResult(result) eventEntity.setDecryptionResult(result)
} }
} catch (e: MXCryptoError) { } catch (e: MXCryptoError) {
Timber.v("Failed to decrypt event $eventId $e") Timber.v(e, "Failed to decrypt event $eventId")
if (e is MXCryptoError.Base && e.errorType == MXCryptoError.ErrorType.UNKNOWN_INBOUND_SESSION_ID) { if (e is MXCryptoError.Base && e.errorType == MXCryptoError.ErrorType.UNKNOWN_INBOUND_SESSION_ID) {
// Keep track of unknown sessions to automatically try to decrypt on new session // Keep track of unknown sessions to automatically try to decrypt on new session
realm.executeTransaction { realm.executeTransaction {