| Index: ios/web/crw_browsing_data_store.mm
|
| diff --git a/ios/web/crw_browsing_data_store.mm b/ios/web/crw_browsing_data_store.mm
|
| index 45242072b3b3b4dd3a99e54618c06c0241d0dfa5..646bb5ae107a2b5bcfe0be2aa801415accd0fcd0 100644
|
| --- a/ios/web/crw_browsing_data_store.mm
|
| +++ b/ios/web/crw_browsing_data_store.mm
|
| @@ -44,7 +44,13 @@ enum OperationType {
|
| @property(nonatomic, assign) CRWBrowsingDataStoreMode mode;
|
| // Sets the mode iff there are no more stash or restore operations that are
|
| // still pending. |mode| can only be either |ACTIVE| or |INACTIVE|.
|
| -- (void)setModeIfNotStashingOrRestoring:(CRWBrowsingDataStoreMode)mode;
|
| +// |handler| is called immediately (in the same runloop) with a BOOL indicating
|
| +// whether the mode change was successful or not. |handler| can be nil.
|
| +- (void)finalizeChangeToMode:(CRWBrowsingDataStoreMode)mode
|
| + andCallCompletionHandler:(void (^)(BOOL modeChangeWasSuccessful))handler;
|
| +
|
| +// The number of stash or restore operations that are still pending.
|
| +@property(nonatomic, assign) NSUInteger numberOfPendingStashOrRestoreOperations;
|
|
|
| // Performs operations of type |operationType| on each of the
|
| // |browsingDataManagers|.
|
| @@ -86,8 +92,10 @@ enum OperationType {
|
| // The last operation that was enqueued to be run. Can be stash, restore or a
|
| // delete operation.
|
| base::scoped_nsobject<NSOperation> _lastDispatchedOperation;
|
| - // The last stash or restore operations that was dispatched to be run.
|
| - base::scoped_nsobject<NSOperation> _lastDispatchedStashOrRestoreOperation;
|
| + // The number of stash or restore operations that are still pending. If this
|
| + // value > 0 the mode of the CRWBrowsingDataStore is SYNCHRONIZING. The mode
|
| + // can be made ACTIVE or INACTIVE only be set when this value is 0.
|
| + NSUInteger _numberOfPendingStashOrRestoreOperations;
|
| }
|
|
|
| + (NSOperationQueue*)operationQueueForStashAndRestoreOperations {
|
| @@ -172,6 +180,18 @@ enum OperationType {
|
| return result;
|
| }
|
|
|
| ++ (BOOL)automaticallyNotifiesObserversForKey:(NSString*)key {
|
| + // It is necessary to override this for |mode| because the default KVO
|
| + // behavior in NSObject is to fire a notification irrespective of if an actual
|
| + // change was made to the ivar or not. The |mode| property needs fine grained
|
| + // control over the actual notifications being fired since observers need to
|
| + // be notified iff the |mode| actually changed.
|
| + if ([key isEqual:@"mode"]) {
|
| + return NO;
|
| + }
|
| + return [super automaticallyNotifiesObserversForKey:(NSString*)key];
|
| +}
|
| +
|
| - (CRWBrowsingDataStoreMode)mode {
|
| DCHECK([NSThread isMainThread]);
|
| return _mode;
|
| @@ -179,42 +199,67 @@ enum OperationType {
|
|
|
| - (void)setMode:(CRWBrowsingDataStoreMode)mode {
|
| DCHECK([NSThread isMainThread]);
|
| + if (_mode == mode) {
|
| + return;
|
| + }
|
| + if (mode == ACTIVE || mode == INACTIVE) {
|
| + DCHECK(!self.numberOfPendingStashOrRestoreOperations);
|
| + }
|
| + [self willChangeValueForKey:@"mode"];
|
| _mode = mode;
|
| + [self didChangeValueForKey:@"mode"];
|
| }
|
|
|
| -- (void)setModeIfNotStashingOrRestoring:(CRWBrowsingDataStoreMode)mode {
|
| +- (void)finalizeChangeToMode:(CRWBrowsingDataStoreMode)mode
|
| + andCallCompletionHandler:(void (^)(BOOL modeChangeWasSuccessful))handler {
|
| DCHECK([NSThread isMainThread]);
|
| DCHECK_NE(SYNCHRONIZING, mode);
|
| - if ([_lastDispatchedStashOrRestoreOperation isFinished]) {
|
| - _mode = mode;
|
| +
|
| + BOOL modeChangeWasSuccessful = NO;
|
| + if (!self.numberOfPendingStashOrRestoreOperations) {
|
| + [self setMode:mode];
|
| + modeChangeWasSuccessful = YES;
|
| + }
|
| + if (handler) {
|
| + handler(modeChangeWasSuccessful);
|
| }
|
| }
|
|
|
| -- (void)makeActiveWithCompletionHandler:(ProceduralBlock)completionHandler {
|
| +- (NSUInteger)numberOfPendingStashOrRestoreOperations {
|
| + DCHECK([NSThread isMainThread]);
|
| + return _numberOfPendingStashOrRestoreOperations;
|
| +}
|
| +
|
| +- (void)setNumberOfPendingStashOrRestoreOperations:
|
| + (NSUInteger)numberOfPendingStashOrRestoreOperations {
|
| + DCHECK([NSThread isMainThread]);
|
| + _numberOfPendingStashOrRestoreOperations =
|
| + numberOfPendingStashOrRestoreOperations;
|
| +}
|
| +
|
| +- (void)makeActiveWithCompletionHandler:
|
| + (void (^)(BOOL success))completionHandler {
|
| DCHECK([NSThread isMainThread]);
|
|
|
| base::WeakNSObject<CRWBrowsingDataStore> weakSelf(self);
|
| [self performOperationWithType:RESTORE
|
| browsingDataManagers:[self allBrowsingDataManagers]
|
| completionHandler:^{
|
| - [weakSelf setModeIfNotStashingOrRestoring:ACTIVE];
|
| - if (completionHandler) {
|
| - completionHandler();
|
| - }
|
| + [weakSelf finalizeChangeToMode:ACTIVE
|
| + andCallCompletionHandler:completionHandler];
|
| }];
|
| }
|
|
|
| -- (void)makeInactiveWithCompletionHandler:(ProceduralBlock)completionHandler {
|
| +- (void)makeInactiveWithCompletionHandler:
|
| + (void (^)(BOOL success))completionHandler {
|
| DCHECK([NSThread isMainThread]);
|
|
|
| base::WeakNSObject<CRWBrowsingDataStore> weakSelf(self);
|
| [self performOperationWithType:STASH
|
| browsingDataManagers:[self allBrowsingDataManagers]
|
| completionHandler:^{
|
| - [weakSelf setModeIfNotStashingOrRestoring:INACTIVE];
|
| - if (completionHandler) {
|
| - completionHandler();
|
| - }
|
| + [weakSelf finalizeChangeToMode:INACTIVE
|
| + andCallCompletionHandler:completionHandler];
|
| }];
|
| }
|
|
|
| @@ -262,9 +307,20 @@ enum OperationType {
|
| break;
|
| };
|
|
|
| + if (operationType == RESTORE || operationType == STASH) {
|
| + [self setMode:SYNCHRONIZING];
|
| + ++self.numberOfPendingStashOrRestoreOperations;
|
| + completionHandler = ^{
|
| + --self.numberOfPendingStashOrRestoreOperations;
|
| + // It is safe to this and does not lead to the block (|completionHandler|)
|
| + // retaining itself.
|
| + completionHandler();
|
| + };
|
| + }
|
| +
|
| id callCompletionHandlerOnMainThread = ^{
|
| - // This can be called on a background thread, hence the need to bounce to
|
| - // the main thread.
|
| + // This is called on a background thread, hence the need to bounce to the
|
| + // main thread.
|
| dispatch_async(dispatch_get_main_queue(), ^{
|
| completionHandler();
|
| });
|
| @@ -274,10 +330,6 @@ enum OperationType {
|
| selector:selector
|
| completionHandler:callCompletionHandlerOnMainThread]);
|
|
|
| - if (operationType == RESTORE || operationType == STASH) {
|
| - _mode = SYNCHRONIZING;
|
| - _lastDispatchedStashOrRestoreOperation.reset([operation retain]);
|
| - }
|
|
|
| NSOperationQueue* queue = nil;
|
| switch (operationType) {
|
|
|