From 44051bd7e7dfae7c41242c8de7d982fa01adf134 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Wed, 11 Oct 2017 11:59:08 -0400 Subject: [PATCH] Avoid deadlock in profile manager. // FREEBIE --- Signal/src/Profiles/OWSProfileManager.m | 74 +++++++++++++------------ 1 file changed, 38 insertions(+), 36 deletions(-) diff --git a/Signal/src/Profiles/OWSProfileManager.m b/Signal/src/Profiles/OWSProfileManager.m index 47356f458..c2ba6fc9a 100644 --- a/Signal/src/Profiles/OWSProfileManager.m +++ b/Signal/src/Profiles/OWSProfileManager.m @@ -242,43 +242,45 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640; // Other threads may modify this profile's properties OWSAssert([userProfile isEqual:userProfileCopy]); } - - // Make sure to save on the local db connection for consistency. - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - [userProfileCopy saveWithTransaction:transaction]; - }]; - - BOOL isLocalUserProfile = userProfile == self.localUserProfile; - - dispatch_async(dispatch_get_main_queue(), ^{ - if (isLocalUserProfile) { - // We populate an initial (empty) profile on launch of a new install, but until - // we have a registered account, syncing will fail (and there could not be any - // linked device to sync to at this point anyway). - if ([TSAccountManager isRegistered]) { - [MultiDeviceProfileKeyUpdateJob runWithProfileKey:userProfile.profileKey - identityManager:self.identityManager - messageSender:self.messageSender - profileManager:self]; + + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + // Make sure to save on the local db connection for consistency. + [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [userProfileCopy saveWithTransaction:transaction]; + }]; + + BOOL isLocalUserProfile = userProfile == self.localUserProfile; + + dispatch_async(dispatch_get_main_queue(), ^{ + if (isLocalUserProfile) { + // We populate an initial (empty) profile on launch of a new install, but until + // we have a registered account, syncing will fail (and there could not be any + // linked device to sync to at this point anyway). + if ([TSAccountManager isRegistered]) { + [MultiDeviceProfileKeyUpdateJob runWithProfileKey:userProfile.profileKey + identityManager:self.identityManager + messageSender:self.messageSender + profileManager:self]; + } + + [[NSNotificationCenter defaultCenter] postNotificationNameAsync:kNSNotificationName_LocalProfileDidChange + object:nil + userInfo:nil]; + } else { + [[NSNotificationCenter defaultCenter] + postNotificationNameAsync:kNSNotificationName_OtherUsersProfileWillChange + object:nil + userInfo:@{ + kNSNotificationKey_ProfileRecipientId : userProfile.recipientId, + }]; + [[NSNotificationCenter defaultCenter] + postNotificationNameAsync:kNSNotificationName_OtherUsersProfileDidChange + object:nil + userInfo:@{ + kNSNotificationKey_ProfileRecipientId : userProfile.recipientId, + }]; } - - [[NSNotificationCenter defaultCenter] postNotificationNameAsync:kNSNotificationName_LocalProfileDidChange - object:nil - userInfo:nil]; - } else { - [[NSNotificationCenter defaultCenter] - postNotificationNameAsync:kNSNotificationName_OtherUsersProfileWillChange - object:nil - userInfo:@{ - kNSNotificationKey_ProfileRecipientId : userProfile.recipientId, - }]; - [[NSNotificationCenter defaultCenter] - postNotificationNameAsync:kNSNotificationName_OtherUsersProfileDidChange - object:nil - userInfo:@{ - kNSNotificationKey_ProfileRecipientId : userProfile.recipientId, - }]; - } + }); }); }