Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crypto: Fix race in device list updates #299

Merged
merged 1 commit into from
Jun 1, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion MatrixSDK/Crypto/Data/MXDeviceList.m
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ @interface MXDeviceList ()
// userId -> MXDeviceTrackingStatus*
NSMutableDictionary<NSString*, NSNumber*> *deviceTrackingStatus;

// The current request for each user.
// userId -> MXDeviceListOperation
NSMutableDictionary<NSString*, MXDeviceListOperation*> *keyDownloadsInProgressByUser;

/**
The pool which the http request is currenlty being processed.
(nil if there is no current request).
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -102,7 +108,7 @@ - (MXHTTPOperation*)downloadKeys:(NSArray<NSString*>*)userIds forceDownload:(BOO
}
}

MXDeviceListOperation *operation;
__block MXDeviceListOperation *operation;

if (usersToDownload.count)
{
Expand All @@ -122,6 +128,16 @@ - (MXHTTPOperation*)downloadKeys:(NSArray<NSString*>*)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)
{
Expand Down Expand Up @@ -155,6 +171,11 @@ - (MXHTTPOperation*)downloadKeys:(NSArray<NSString*>*)userIds forceDownload:(BOO

} failure:failure];

for (NSString *userId in usersToDownload)
{
keyDownloadsInProgressByUser[userId] = operation;
}

if (doANewQuery)
{
NSLog(@"[MXDeviceList] downloadKeys: waiting for next key query");
Expand Down