From 2b623c935446972bbc6122e809640144e1f0d396 Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 1 Jun 2017 16:10:33 +0200 Subject: [PATCH] Crypto: Fix race in device list updates Don't consider device lists up-to-date when we have another request for the relevant user in the queue. Port of https://github.com/matrix-org/matrix-js-sdk/pull/431 --- MatrixSDK/Crypto/Data/MXDeviceList.m | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/MatrixSDK/Crypto/Data/MXDeviceList.m b/MatrixSDK/Crypto/Data/MXDeviceList.m index 7dff6c2be2..6168502807 100644 --- a/MatrixSDK/Crypto/Data/MXDeviceList.m +++ b/MatrixSDK/Crypto/Data/MXDeviceList.m @@ -30,6 +30,10 @@ @interface MXDeviceList () // userId -> MXDeviceTrackingStatus* NSMutableDictionary *deviceTrackingStatus; + // The current request for each user. + // userId -> MXDeviceListOperation + NSMutableDictionary *keyDownloadsInProgressByUser; + /** The pool which the http request is currenlty being processed. (nil if there is no current request). @@ -61,6 +65,8 @@ - (id)initWithCrypto:(MXCrypto *)theCrypto // Retrieve tracking status from the store deviceTrackingStatus = [NSMutableDictionary dictionaryWithDictionary:[crypto.store deviceTrackingStatus]]; + keyDownloadsInProgressByUser = [NSMutableDictionary dictionary]; + for (NSString *userId in deviceTrackingStatus.allKeys) { // if a download was in progress or failed when we got shut down, it isn't any more. @@ -102,7 +108,7 @@ - (MXHTTPOperation*)downloadKeys:(NSArray*)userIds forceDownload:(BOO } } - MXDeviceListOperation *operation; + __block MXDeviceListOperation *operation; if (usersToDownload.count) { @@ -122,6 +128,16 @@ - (MXHTTPOperation*)downloadKeys:(NSArray*)userIds forceDownload:(BOO for (NSString *userId in succeededUserIds) { + // we may have queued up another download request for this user + // since we started this request. If that happens, we should + // ignore the completion of the first one. + if (keyDownloadsInProgressByUser[userId] != operation) + { + NSLog(@"[MXDeviceList] downloadKeys: Another update in the queue for %@ - not marking up-to-date", userId); + continue; + } + [keyDownloadsInProgressByUser removeObjectForKey:userId]; + MXDeviceTrackingStatus trackingStatus = MXDeviceTrackingStatusFromNSNumber(deviceTrackingStatus[userId]); if (trackingStatus == MXDeviceTrackingStatusDownloadInProgress) { @@ -155,6 +171,11 @@ - (MXHTTPOperation*)downloadKeys:(NSArray*)userIds forceDownload:(BOO } failure:failure]; + for (NSString *userId in usersToDownload) + { + keyDownloadsInProgressByUser[userId] = operation; + } + if (doANewQuery) { NSLog(@"[MXDeviceList] downloadKeys: waiting for next key query");