From fe67cd924c00e4fa41b8a279018225c2bf8033ec Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Mon, 18 Dec 2017 22:56:02 -0500 Subject: [PATCH] Rework database view registration. --- Signal/src/AppDelegate.m | 16 ++-- SignalMessaging/environment/AppSetup.m | 3 +- .../src/Messages/OWSBatchMessageProcessor.m | 12 +-- .../src/Messages/OWSMessageReceiver.m | 12 +-- .../src/Messages/OWSReadReceiptManager.m | 12 +-- SignalServiceKit/src/Storage/OWSStorage.h | 20 +++- SignalServiceKit/src/Storage/OWSStorage.m | 95 +++++++++++++++++-- SignalServiceKit/src/Storage/TSDatabaseView.h | 8 -- SignalServiceKit/src/Storage/TSDatabaseView.m | 72 -------------- .../src/Storage/TSStorageManager.h | 10 -- .../src/Storage/TSStorageManager.m | 35 ++++--- .../ShareViewController.swift | 8 +- 12 files changed, 156 insertions(+), 147 deletions(-) diff --git a/Signal/src/AppDelegate.m b/Signal/src/AppDelegate.m index 5c24c0adf..5bbd8ebf1 100644 --- a/Signal/src/AppDelegate.m +++ b/Signal/src/AppDelegate.m @@ -135,7 +135,7 @@ static NSString *const kURLHostVerifyPrefix = @"verify"; // Prevent the device from sleeping during database view async registration // (e.g. long database upgrades). // - // This block will be cleared in databaseViewRegistrationComplete. + // This block will be cleared in storageIsReady. [DeviceSleepManager.sharedInstance addBlockWithBlockObject:self]; [AppSetup setupEnvironment:^{ @@ -175,8 +175,8 @@ static NSString *const kURLHostVerifyPrefix = @"verify"; [OWSContactsSyncing sharedManager]; [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(databaseViewRegistrationComplete) - name:DatabaseViewRegistrationCompleteNotification + selector:@selector(storageIsReady) + name:StorageIsReadyNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(registrationStateDidChange) @@ -713,9 +713,9 @@ static NSString *const kURLHostVerifyPrefix = @"verify"; completionHandler:completionHandler]; } -- (void)databaseViewRegistrationComplete +- (void)storageIsReady { - DDLogInfo(@"%@ databaseViewRegistrationComplete", self.logTag); + DDLogInfo(@"%@ storageIsReady", self.logTag); [OWSPreferences setIsRegistered:[TSAccountManager isRegistered]]; @@ -739,8 +739,6 @@ static NSString *const kURLHostVerifyPrefix = @"verify"; [Environment.current.contactsManager loadSignalAccountsFromCache]; - [self ensureRootViewController]; - // If there were any messages in our local queue which we hadn't yet processed. [[OWSMessageReceiver sharedInstance] handleAnyUnprocessedEnvelopesAsync]; [[OWSBatchMessageProcessor sharedInstance] handleAnyUnprocessedEnvelopesAsync]; @@ -766,6 +764,8 @@ static NSString *const kURLHostVerifyPrefix = @"verify"; // Disable the SAE until the main app has successfully completed launch process // at least once in the post-SAE world. [OWSPreferences setIsReadyForAppExtensions]; + + [self ensureRootViewController]; } - (void)registrationStateDidChange @@ -797,7 +797,7 @@ static NSString *const kURLHostVerifyPrefix = @"verify"; { DDLogInfo(@"%@ ensureRootViewController", self.logTag); - if ([TSDatabaseView hasPendingViewRegistrations] || self.hasInitialRootViewController) { + if (![OWSStorage isStorageReady] || self.hasInitialRootViewController) { return; } self.hasInitialRootViewController = YES; diff --git a/SignalMessaging/environment/AppSetup.m b/SignalMessaging/environment/AppSetup.m index 6bc25aadf..abc3583cd 100644 --- a/SignalMessaging/environment/AppSetup.m +++ b/SignalMessaging/environment/AppSetup.m @@ -9,6 +9,7 @@ #import #import #import +#import #import NS_ASSUME_NONNULL_BEGIN @@ -39,7 +40,7 @@ NS_ASSUME_NONNULL_BEGIN profileManager:OWSProfileManager.sharedManager]; [TextSecureKitEnv setSharedEnv:sharedEnv]; - [[TSStorageManager sharedManager] setupDatabaseWithSafeBlockingMigrations:^{ + [OWSStorage setupWithSafeBlockingMigrations:^{ [VersionMigrations runSafeBlockingMigrations]; }]; [[Environment current].contactsManager startObserving]; diff --git a/SignalServiceKit/src/Messages/OWSBatchMessageProcessor.m b/SignalServiceKit/src/Messages/OWSBatchMessageProcessor.m index c4461d5da..e98377dde 100644 --- a/SignalServiceKit/src/Messages/OWSBatchMessageProcessor.m +++ b/SignalServiceKit/src/Messages/OWSBatchMessageProcessor.m @@ -9,6 +9,7 @@ #import "OWSMessageManager.h" #import "OWSQueues.h" #import "OWSSignalServiceProtos.pb.h" +#import "OWSStorage.h" #import "TSDatabaseView.h" #import "TSStorageManager.h" #import "TSYapDatabaseObject.h" @@ -261,8 +262,8 @@ NSString *const OWSMessageContentJobFinderExtensionGroup = @"OWSMessageContentJo _isDrainingQueue = NO; [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(databaseViewRegistrationComplete) - name:DatabaseViewRegistrationCompleteNotification + selector:@selector(storageIsReady) + name:StorageIsReadyNotification object:nil]; return self; @@ -273,7 +274,7 @@ NSString *const OWSMessageContentJobFinderExtensionGroup = @"OWSMessageContentJo [[NSNotificationCenter defaultCenter] removeObserver:self]; } -- (void)databaseViewRegistrationComplete +- (void)storageIsReady { [self drainQueue]; } @@ -306,9 +307,8 @@ NSString *const OWSMessageContentJobFinderExtensionGroup = @"OWSMessageContentJo } dispatch_async(self.serialQueue, ^{ - if ([TSDatabaseView hasPendingViewRegistrations]) { - // We don't want to process incoming messages until database - // view registration is complete. + if (![OWSStorage isStorageReady]) { + // We don't want to process incoming messages until storage is ready. return; } diff --git a/SignalServiceKit/src/Messages/OWSMessageReceiver.m b/SignalServiceKit/src/Messages/OWSMessageReceiver.m index c07e31586..93151e9fa 100644 --- a/SignalServiceKit/src/Messages/OWSMessageReceiver.m +++ b/SignalServiceKit/src/Messages/OWSMessageReceiver.m @@ -10,6 +10,7 @@ #import "OWSMessageDecrypter.h" #import "OWSQueues.h" #import "OWSSignalServiceProtos.pb.h" +#import "OWSStorage.h" #import "TSDatabaseView.h" #import "TSStorageManager.h" #import "TSYapDatabaseObject.h" @@ -241,8 +242,8 @@ NSString *const OWSMessageDecryptJobFinderExtensionGroup = @"OWSMessageProcessin _isDrainingQueue = NO; [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(databaseViewRegistrationComplete) - name:DatabaseViewRegistrationCompleteNotification + selector:@selector(storageIsReady) + name:StorageIsReadyNotification object:nil]; return self; @@ -253,7 +254,7 @@ NSString *const OWSMessageDecryptJobFinderExtensionGroup = @"OWSMessageProcessin [[NSNotificationCenter defaultCenter] removeObserver:self]; } -- (void)databaseViewRegistrationComplete +- (void)storageIsReady { [self drainQueue]; } @@ -283,9 +284,8 @@ NSString *const OWSMessageDecryptJobFinderExtensionGroup = @"OWSMessageProcessin } dispatch_async(self.serialQueue, ^{ - if ([TSDatabaseView hasPendingViewRegistrations]) { - // We don't want to process incoming messages until database - // view registration is complete. + if (![OWSStorage isStorageReady]) { + // We don't want to process incoming messages until storage is ready. return; } diff --git a/SignalServiceKit/src/Messages/OWSReadReceiptManager.m b/SignalServiceKit/src/Messages/OWSReadReceiptManager.m index 239bc4ef0..c06fbbe97 100644 --- a/SignalServiceKit/src/Messages/OWSReadReceiptManager.m +++ b/SignalServiceKit/src/Messages/OWSReadReceiptManager.m @@ -9,6 +9,7 @@ #import "OWSReadReceiptsForLinkedDevicesMessage.h" #import "OWSReadReceiptsForSenderMessage.h" #import "OWSSignalServiceProtos.pb.h" +#import "OWSStorage.h" #import "OWSSyncConfigurationMessage.h" #import "TSContactThread.h" #import "TSDatabaseView.h" @@ -176,8 +177,8 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE OWSSingletonAssert(); [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(databaseViewRegistrationComplete) - name:DatabaseViewRegistrationCompleteNotification + selector:@selector(storageIsReady) + name:StorageIsReadyNotification object:nil]; // Try to start processing. @@ -191,7 +192,7 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE [[NSNotificationCenter defaultCenter] removeObserver:self]; } -- (void)databaseViewRegistrationComplete +- (void)storageIsReady { [self scheduleProcessing]; } @@ -202,9 +203,8 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ @synchronized(self) { - if ([TSDatabaseView hasPendingViewRegistrations]) { - DDLogInfo( - @"%@ Deferring read receipt processing due to pending database view registrations.", self.logTag); + if (![OWSStorage isStorageReady]) { + DDLogInfo(@"%@ Deferring read receipt processing; storage not yet ready.", self.logTag); return; } if (self.isProcessing) { diff --git a/SignalServiceKit/src/Storage/OWSStorage.h b/SignalServiceKit/src/Storage/OWSStorage.h index a69131484..943fa8ca7 100644 --- a/SignalServiceKit/src/Storage/OWSStorage.h +++ b/SignalServiceKit/src/Storage/OWSStorage.h @@ -6,6 +6,8 @@ NS_ASSUME_NONNULL_BEGIN +extern NSString *const StorageIsReadyNotification; + @class YapDatabaseExtension; @interface OWSStorage : NSObject @@ -13,7 +15,23 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)init NS_UNAVAILABLE; - (instancetype)initStorage NS_DESIGNATED_INITIALIZER; -- (void)setSyncRegistrationsAreComplete; ++ (BOOL)isStorageReady; + +- (void)runSyncRegistrations; +- (void)runAsyncRegistrationsWithCompletion:(void (^_Nonnull)(void))completion; + +- (BOOL)areAsyncRegistrationsComplete; +- (BOOL)areSyncRegistrationsComplete; + +/** + * The safeBlockingMigrationsBlock block will + * run any outstanding version migrations that are a) blocking and b) safe + * to be run before the environment and storage is completely configured. + * + * Specifically, these migration should not depend on or affect the data + * of any database view. + */ ++ (void)setupWithSafeBlockingMigrations:(void (^_Nonnull)(void))safeBlockingMigrationsBlock; + (void)resetAllStorage; diff --git a/SignalServiceKit/src/Storage/OWSStorage.m b/SignalServiceKit/src/Storage/OWSStorage.m index 8e291902e..ad99f4a21 100644 --- a/SignalServiceKit/src/Storage/OWSStorage.m +++ b/SignalServiceKit/src/Storage/OWSStorage.m @@ -5,6 +5,7 @@ #import "OWSStorage.h" #import "AppContext.h" #import "NSData+Base64.h" +#import "NSNotificationCenter+OWS.h" #import "TSAttachmentStream.h" #import "TSStorageManager.h" #import @@ -13,6 +14,8 @@ NS_ASSUME_NONNULL_BEGIN +NSString *const StorageIsReadyNotification = @"StorageIsReadyNotification"; + NSString *const OWSStorageExceptionName_DatabasePasswordInaccessibleWhileBackgrounded = @"OWSStorageExceptionName_DatabasePasswordInaccessibleWhileBackgrounded"; NSString *const OWSStorageExceptionName_DatabasePasswordUnwritable @@ -26,7 +29,7 @@ static NSString *keychainDBPassAccount = @"TSDatabasePass"; @protocol OWSDatabaseConnectionDelegate -- (BOOL)areSyncRegistrationsAreComplete; +- (BOOL)areSyncRegistrationsComplete; @end @@ -80,7 +83,7 @@ static NSString *keychainDBPassAccount = @"TSDatabasePass"; { id delegate = self.delegate; OWSAssert(delegate); - OWSAssert(delegate.areSyncRegistrationsAreComplete); + OWSAssert(delegate.areSyncRegistrationsComplete); [super readWriteWithBlock:block]; } @@ -89,7 +92,7 @@ static NSString *keychainDBPassAccount = @"TSDatabasePass"; { id delegate = self.delegate; OWSAssert(delegate); - OWSAssert(delegate.areSyncRegistrationsAreComplete); + OWSAssert(delegate.areSyncRegistrationsComplete); [super asyncReadWriteWithBlock:block]; } @@ -99,7 +102,7 @@ static NSString *keychainDBPassAccount = @"TSDatabasePass"; { id delegate = self.delegate; OWSAssert(delegate); - OWSAssert(delegate.areSyncRegistrationsAreComplete); + OWSAssert(delegate.areSyncRegistrationsComplete); [super asyncReadWriteWithBlock:block completionBlock:completionBlock]; } @@ -110,7 +113,7 @@ static NSString *keychainDBPassAccount = @"TSDatabasePass"; { id delegate = self.delegate; OWSAssert(delegate); - OWSAssert(delegate.areSyncRegistrationsAreComplete); + OWSAssert(delegate.areSyncRegistrationsComplete); [super asyncReadWriteWithBlock:block completionQueue:completionQueue completionBlock:completionBlock]; } @@ -232,7 +235,6 @@ static NSString *keychainDBPassAccount = @"TSDatabasePass"; @interface OWSStorage () @property (atomic, nullable) YapDatabase *database; -@property (atomic) BOOL areSyncRegistrationsAreComplete; @end @@ -270,11 +272,82 @@ static NSString *keychainDBPassAccount = @"TSDatabasePass"; return self; } -- (void)setSyncRegistrationsAreComplete +- (BOOL)areAsyncRegistrationsComplete { - OWSAssert(!self.areSyncRegistrationsAreComplete); + OWS_ABSTRACT_METHOD(); - self.areSyncRegistrationsAreComplete = YES; + return NO; +} + +- (BOOL)areSyncRegistrationsComplete +{ + OWS_ABSTRACT_METHOD(); + + return NO; +} + +- (void)runSyncRegistrations +{ + OWS_ABSTRACT_METHOD(); +} + +- (void)runAsyncRegistrationsWithCompletion:(void (^_Nonnull)(void))completion +{ + OWS_ABSTRACT_METHOD(); +} + ++ (NSArray *)allStorages +{ + return @[ + TSStorageManager.sharedManager, + ]; +} + ++ (void)setupWithSafeBlockingMigrations:(void (^_Nonnull)(void))safeBlockingMigrationsBlock +{ + OWSAssert(safeBlockingMigrationsBlock); + + for (OWSStorage *storage in self.allStorages) { + [storage runSyncRegistrations]; + } + + // Run the blocking migrations. + // + // These need to run _before_ the async registered database views or + // they will block on them, which (in the upgrade case) can block + // return of appDidFinishLaunching... which in term can cause the + // app to crash on launch. + safeBlockingMigrationsBlock(); + + for (OWSStorage *storage in self.allStorages) { + [storage runAsyncRegistrationsWithCompletion:^{ + [self postRegistrationCompleteNotificationIfPossible]; + }]; + } +} + ++ (void)postRegistrationCompleteNotificationIfPossible +{ + if (!self.isStorageReady) { + return; + } + + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + [[NSNotificationCenter defaultCenter] postNotificationNameAsync:StorageIsReadyNotification + object:nil + userInfo:nil]; + }); +} + ++ (BOOL)isStorageReady +{ + for (OWSStorage *storage in self.allStorages) { + if (!storage.areAsyncRegistrationsComplete) { + return NO; + } + } + return YES; } - (BOOL)tryToLoadDatabase @@ -373,7 +446,9 @@ static NSString *keychainDBPassAccount = @"TSDatabasePass"; + (void)resetAllStorage { - [[TSStorageManager sharedManager] resetStorage]; + for (OWSStorage *storage in self.allStorages) { + [storage resetStorage]; + } [self deletePasswordFromKeychain]; diff --git a/SignalServiceKit/src/Storage/TSDatabaseView.h b/SignalServiceKit/src/Storage/TSDatabaseView.h index 6f353e1cd..c3871659e 100644 --- a/SignalServiceKit/src/Storage/TSDatabaseView.h +++ b/SignalServiceKit/src/Storage/TSDatabaseView.h @@ -4,8 +4,6 @@ #import -extern NSString *const DatabaseViewRegistrationCompleteNotification; - extern NSString *const TSInboxGroup; extern NSString *const TSArchiveGroup; extern NSString *const TSUnreadIncomingMessagesGroup; @@ -22,9 +20,6 @@ extern NSString *const TSSecondaryDevicesDatabaseViewExtensionName; - (instancetype)init NS_UNAVAILABLE; -// This method can be called from any thread. -+ (BOOL)hasPendingViewRegistrations; - + (void)registerCrossProcessNotifier; // This method must be called _AFTER_ registerThreadInteractionsDatabaseView. @@ -57,7 +52,4 @@ extern NSString *const TSSecondaryDevicesDatabaseViewExtensionName; // NOTE: It is not safe to call this method while hasPendingViewRegistrations is YES. + (id)threadSpecialMessagesDatabaseView:(YapDatabaseReadTransaction *)transaction; -// This method should be called _after_ all async database registrations have been started. -+ (void)asyncRegistrationCompletion; - @end diff --git a/SignalServiceKit/src/Storage/TSDatabaseView.m b/SignalServiceKit/src/Storage/TSDatabaseView.m index 028ff1fff..b913b2468 100644 --- a/SignalServiceKit/src/Storage/TSDatabaseView.m +++ b/SignalServiceKit/src/Storage/TSDatabaseView.m @@ -3,7 +3,6 @@ // #import "TSDatabaseView.h" -#import "NSNotificationCenter+OWS.h" #import "OWSDevice.h" #import "OWSReadTracking.h" #import "TSIncomingMessage.h" @@ -15,8 +14,6 @@ #import #import -NSString *const DatabaseViewRegistrationCompleteNotification = @"DatabaseViewRegistrationCompleteNotification"; - NSString *const TSInboxGroup = @"TSInboxGroup"; NSString *const TSArchiveGroup = @"TSArchiveGroup"; @@ -33,62 +30,8 @@ NSString *const TSUnseenDatabaseViewExtensionName = @"TSUnseenDatabaseViewExtens NSString *const TSThreadSpecialMessagesDatabaseViewExtensionName = @"TSThreadSpecialMessagesDatabaseViewExtensionName"; NSString *const TSSecondaryDevicesDatabaseViewExtensionName = @"TSSecondaryDevicesDatabaseViewExtensionName"; -@interface TSDatabaseView () - -@property (nonatomic) BOOL areAllAsyncRegistrationsComplete; - -@end - -#pragma mark - - @implementation TSDatabaseView -+ (instancetype)sharedInstance -{ - static TSDatabaseView *sharedInstance = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - sharedInstance = [[self alloc] initDefault]; - }); - return sharedInstance; -} - -- (instancetype)initDefault -{ - self = [super init]; - - if (!self) { - return self; - } - - OWSSingletonAssert(); - - return self; -} - -- (BOOL)hasPendingViewRegistrations -{ - @synchronized(self) - { - return !self.areAllAsyncRegistrationsComplete; - } -} - -+ (BOOL)hasPendingViewRegistrations -{ - return ![TSDatabaseView sharedInstance].areAllAsyncRegistrationsComplete; -} - -- (void)setAreAllAsyncRegistrationsComplete -{ - @synchronized(self) - { - OWSAssert(!self.areAllAsyncRegistrationsComplete); - - self.areAllAsyncRegistrationsComplete = YES; - } -} - + (void)registerCrossProcessNotifier { // I don't think the identifier and name of this extension matter for our purposes, @@ -444,19 +387,4 @@ NSString *const TSSecondaryDevicesDatabaseViewExtensionName = @"TSSecondaryDevic return result; } -+ (void)asyncRegistrationCompletion -{ - OWSAssertIsOnMainThread(); - - // All async registrations are complete when writes are unblocked. - [[TSStorageManager sharedManager].newDatabaseConnection - asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { - [TSDatabaseView.sharedInstance setAreAllAsyncRegistrationsComplete]; - - [[NSNotificationCenter defaultCenter] postNotificationNameAsync:DatabaseViewRegistrationCompleteNotification - object:nil - userInfo:nil]; - }]; -} - @end diff --git a/SignalServiceKit/src/Storage/TSStorageManager.h b/SignalServiceKit/src/Storage/TSStorageManager.h index 642d499d5..153721f83 100644 --- a/SignalServiceKit/src/Storage/TSStorageManager.h +++ b/SignalServiceKit/src/Storage/TSStorageManager.h @@ -12,16 +12,6 @@ NS_ASSUME_NONNULL_BEGIN + (instancetype)sharedManager; -/** - * The safeBlockingMigrationsBlock block will - * run any outstanding version migrations that are a) blocking and b) safe - * to be run before the environment and storage is completely configured. - * - * Specifically, these migration should not depend on or affect the data - * of any database view. - */ -- (void)setupDatabaseWithSafeBlockingMigrations:(void (^_Nonnull)(void))safeBlockingMigrationsBlock; - - (YapDatabaseConnection *)dbReadConnection; - (YapDatabaseConnection *)dbReadWriteConnection; + (YapDatabaseConnection *)dbReadConnection; diff --git a/SignalServiceKit/src/Storage/TSStorageManager.m b/SignalServiceKit/src/Storage/TSStorageManager.m index f4121e21b..0d55a3ef6 100644 --- a/SignalServiceKit/src/Storage/TSStorageManager.m +++ b/SignalServiceKit/src/Storage/TSStorageManager.m @@ -28,6 +28,9 @@ NSString *const TSStorageManagerExceptionName_CouldNotCreateDatabaseDirectory @property (nonatomic, readonly) YapDatabaseConnection *dbReadConnection; @property (nonatomic, readonly) YapDatabaseConnection *dbReadWriteConnection; +@property (atomic) BOOL areAsyncRegistrationsComplete; +@property (atomic) BOOL areSyncRegistrationsComplete; + @end #pragma mark - @@ -69,7 +72,7 @@ NSString *const TSStorageManagerExceptionName_CouldNotCreateDatabaseDirectory [super resetStorage]; } -- (void)setupDatabaseWithSafeBlockingMigrations:(void (^_Nonnull)(void))safeBlockingMigrationsBlock +- (void)runSyncRegistrations { // Synchronously register extensions which are essential for views. [TSDatabaseView registerCrossProcessNotifier]; @@ -86,15 +89,13 @@ NSString *const TSStorageManagerExceptionName_CouldNotCreateDatabaseDirectory // seeing, this issue only seems to affect sync and not async registrations. We've always // been opening write transactions before the async registrations complete without negative // consequences. - [self setSyncRegistrationsAreComplete]; + OWSAssert(!self.areSyncRegistrationsComplete); + self.areSyncRegistrationsComplete = YES; +} - // Run the blocking migrations. - // - // These need to run _before_ the async registered database views or - // they will block on them, which (in the upgrade case) can block - // return of appDidFinishLaunching... which in term can cause the - // app to crash on launch. - safeBlockingMigrationsBlock(); +- (void)runAsyncRegistrationsWithCompletion:(void (^_Nonnull)(void))completion +{ + OWSAssert(completion); // Asynchronously register other extensions. // @@ -111,10 +112,14 @@ NSString *const TSStorageManagerExceptionName_CouldNotCreateDatabaseDirectory [OWSFailedMessagesJob asyncRegisterDatabaseExtensionsWithStorageManager:self]; [OWSFailedAttachmentDownloadsJob asyncRegisterDatabaseExtensionsWithStorageManager:self]; - // NOTE: [TSDatabaseView asyncRegistrationCompletion] ensures that - // DatabaseViewRegistrationCompleteNotification is not fired until all - // of the async registrations are complete. - [TSDatabaseView asyncRegistrationCompletion]; + // Block until all async registrations are complete. + [self.newDatabaseConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { + OWSAssert(!self.areAsyncRegistrationsComplete); + + self.areAsyncRegistrationsComplete = YES; + + completion(); + }]; } + (void)protectFiles @@ -216,12 +221,12 @@ NSString *const TSStorageManagerExceptionName_CouldNotCreateDatabaseDirectory + (YapDatabaseConnection *)dbReadConnection { - return TSStorageManager.dbReadConnection; + return TSStorageManager.sharedManager.dbReadConnection; } + (YapDatabaseConnection *)dbReadWriteConnection { - return TSStorageManager.dbReadWriteConnection; + return TSStorageManager.sharedManager.dbReadWriteConnection; } - (void)deleteDatabaseFile diff --git a/SignalShareExtension/ShareViewController.swift b/SignalShareExtension/ShareViewController.swift index 58a69e88b..0c331488e 100644 --- a/SignalShareExtension/ShareViewController.swift +++ b/SignalShareExtension/ShareViewController.swift @@ -102,8 +102,8 @@ public class ShareViewController: UINavigationController, ShareViewDelegate, SAE OWSContactsSyncing.sharedManager() NotificationCenter.default.addObserver(self, - selector: #selector(databaseViewRegistrationComplete), - name: .DatabaseViewRegistrationComplete, + selector: #selector(storageIsReady), + name: .StorageIsReady, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(registrationStateDidChange), @@ -177,7 +177,7 @@ public class ShareViewController: UINavigationController, ShareViewDelegate, SAE } @objc - func databaseViewRegistrationComplete() { + func storageIsReady() { AssertIsOnMainThread() Logger.debug("\(self.logTag) \(#function)") @@ -232,7 +232,7 @@ public class ShareViewController: UINavigationController, ShareViewDelegate, SAE private func ensureRootViewController() { Logger.debug("\(self.logTag) \(#function)") - guard !TSDatabaseView.hasPendingViewRegistrations() else { + guard OWSStorage.isStorageReady() else { return } guard !hasInitialRootViewController else {