Address deadlocks in profile manager.

// FREEBIE
pull/1/head
Matthew Chen 8 years ago
parent 1fe905f0f9
commit 16d4256e99

@ -307,10 +307,7 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640;
_localUserProfile.profileKey = [OWSAES256Key generateRandomKey]; _localUserProfile.profileKey = [OWSAES256Key generateRandomKey];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
@synchronized(self)
{
[self saveUserProfile:_localUserProfile]; [self saveUserProfile:_localUserProfile];
}
}); });
} }
} }
@ -534,6 +531,7 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640;
// TODO: Revisit this so that failed profile updates don't leave // TODO: Revisit this so that failed profile updates don't leave
// the profile avatar blank, etc. // the profile avatar blank, etc.
void (^clearLocalAvatar)() = ^{ void (^clearLocalAvatar)() = ^{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
@synchronized(self) @synchronized(self)
{ {
UserProfile *userProfile = self.localUserProfile; UserProfile *userProfile = self.localUserProfile;
@ -549,6 +547,7 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640;
self.localCachedAvatarImage = nil; self.localCachedAvatarImage = nil;
} }
});
}; };
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
@ -754,6 +753,7 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640;
- (void)regenerateLocalProfile - (void)regenerateLocalProfile
{ {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
@synchronized(self) @synchronized(self)
{ {
_localUserProfile = nil; _localUserProfile = nil;
@ -765,6 +765,7 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640;
// rebuild localUserProfile // rebuild localUserProfile
OWSAssert(self.localUserProfile); OWSAssert(self.localUserProfile);
} }
});
} }
- (void)addUserToProfileWhitelist:(NSString *)recipientId - (void)addUserToProfileWhitelist:(NSString *)recipientId

@ -10,7 +10,6 @@
#import "NewContactThreadViewController.h" #import "NewContactThreadViewController.h"
#import "OWSContactsManager.h" #import "OWSContactsManager.h"
#import "OWSNavigationController.h" #import "OWSNavigationController.h"
#import "OWSProfileManager.h"
#import "ProfileViewController.h" #import "ProfileViewController.h"
#import "PushManager.h" #import "PushManager.h"
#import "Signal-Swift.h" #import "Signal-Swift.h"

@ -149,6 +149,19 @@ NS_ASSUME_NONNULL_BEGIN
NSString *localNumber = [TSAccountManager localNumber]; NSString *localNumber = [TSAccountManager localNumber];
OWSAssert(localNumber.length > 0); OWSAssert(localNumber.length > 0);
// Many OWSProfileManager methods aren't safe to call from inside a database
// transaction, so do this work now.
OWSProfileManager *profileManager = OWSProfileManager.sharedManager;
BOOL hasLocalProfile = [profileManager hasLocalProfile];
BOOL isThreadInProfileWhitelist = [profileManager isThreadInProfileWhitelist:thread];
BOOL hasUnwhitelistedMember = NO;
for (NSString *recipientId in thread.recipientIdentifiers) {
if (![profileManager isUserInProfileWhitelist:recipientId]) {
hasUnwhitelistedMember = YES;
break;
}
}
ThreadDynamicInteractions *result = [ThreadDynamicInteractions new]; ThreadDynamicInteractions *result = [ThreadDynamicInteractions new];
[dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
@ -407,25 +420,15 @@ NS_ASSUME_NONNULL_BEGIN
shouldHaveBlockOffer = NO; shouldHaveBlockOffer = NO;
} }
if (![OWSProfileManager.sharedManager hasLocalProfile] || if (!hasLocalProfile || isThreadInProfileWhitelist) {
[OWSProfileManager.sharedManager isThreadInProfileWhitelist:thread]) {
// Don't show offer if thread is local user hasn't configured their profile. // Don't show offer if thread is local user hasn't configured their profile.
// Don't show offer if thread is already in profile whitelist. // Don't show offer if thread is already in profile whitelist.
shouldHaveAddToProfileWhitelistOffer = NO; shouldHaveAddToProfileWhitelistOffer = NO;
} else if (thread.isGroupThread) { } else if (thread.isGroupThread && !hasUnwhitelistedMember) {
BOOL hasUnwhitelistedMember = NO;
for (NSString *recipientId in thread.recipientIdentifiers) {
if (![OWSProfileManager.sharedManager isUserInProfileWhitelist:recipientId]) {
hasUnwhitelistedMember = YES;
break;
}
}
if (!hasUnwhitelistedMember) {
// Don't show offer in group thread if all members are already individually // Don't show offer in group thread if all members are already individually
// whitelisted. // whitelisted.
shouldHaveAddToProfileWhitelistOffer = NO; shouldHaveAddToProfileWhitelistOffer = NO;
} }
}
BOOL shouldHaveContactOffers BOOL shouldHaveContactOffers
= (shouldHaveBlockOffer || shouldHaveAddToContactsOffer || shouldHaveAddToProfileWhitelistOffer); = (shouldHaveBlockOffer || shouldHaveAddToContactsOffer || shouldHaveAddToProfileWhitelistOffer);

@ -6,7 +6,6 @@
#import "NSDate+OWS.h" #import "NSDate+OWS.h"
#import "OWSOutgoingSyncMessage.h" #import "OWSOutgoingSyncMessage.h"
#import "OWSSignalServiceProtos.pb.h" #import "OWSSignalServiceProtos.pb.h"
#import "ProfileManagerProtocol.h"
#import "ProtoBuf+OWS.h" #import "ProtoBuf+OWS.h"
#import "SignalRecipient.h" #import "SignalRecipient.h"
#import "TSAttachmentStream.h" #import "TSAttachmentStream.h"

@ -36,10 +36,7 @@ NS_ASSUME_NONNULL_BEGIN
// Once we've shared our profile key with a user (perhaps due to being // Once we've shared our profile key with a user (perhaps due to being
// a member of a whitelisted group), make sure they're whitelisted. // a member of a whitelisted group), make sure they're whitelisted.
id<ProfileManagerProtocol> profileManager = [TextSecureKitEnv sharedEnv].profileManager; id<ProfileManagerProtocol> profileManager = [TextSecureKitEnv sharedEnv].profileManager;
// FIXME PERF avoid this dispatch. It's going to happen for *each* recipient in a group message.
dispatch_async(dispatch_get_main_queue(), ^{
[profileManager addUserToProfileWhitelist:recipientId]; [profileManager addUserToProfileWhitelist:recipientId];
});
} }
return [builder build]; return [builder build];

Loading…
Cancel
Save