| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #import "ios/web/public/crw_browsing_data_store.h" | 5 #import "ios/web/public/crw_browsing_data_store.h" |
| 6 | 6 |
| 7 #import <Foundation/Foundation.h> | 7 #import <Foundation/Foundation.h> |
| 8 | 8 |
| 9 #include "base/ios/ios_util.h" | 9 #include "base/ios/ios_util.h" |
| 10 #import "base/ios/weak_nsobject.h" | 10 #import "base/ios/weak_nsobject.h" |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 (web::BrowsingDataTypes)browsingDataTypes; | 54 (web::BrowsingDataTypes)browsingDataTypes; |
| 55 // Returns the selector that needs to be performed on the | 55 // Returns the selector that needs to be performed on the |
| 56 // CRWBrowsingDataManagers for the |operationType|. |operationType| cannot be | 56 // CRWBrowsingDataManagers for the |operationType|. |operationType| cannot be |
| 57 // |NONE|. | 57 // |NONE|. |
| 58 - (SEL)browsingDataManagerSelectorForOperationType:(OperationType)operationType; | 58 - (SEL)browsingDataManagerSelectorForOperationType:(OperationType)operationType; |
| 59 // Returns the selector that needs to be performed on the | 59 // Returns the selector that needs to be performed on the |
| 60 // CRWBrowsingDataManagers for a REMOVE operation. | 60 // CRWBrowsingDataManagers for a REMOVE operation. |
| 61 - (SEL)browsingDataManagerSelectorForRemoveOperationType; | 61 - (SEL)browsingDataManagerSelectorForRemoveOperationType; |
| 62 | 62 |
| 63 // Redefined to be read-write. Must be called from the main thread. | 63 // Redefined to be read-write. Must be called from the main thread. |
| 64 @property(nonatomic, assign) CRWBrowsingDataStoreMode mode; | 64 @property(nonatomic, assign) web::BrowsingDataStoreMode mode; |
| 65 // Sets the mode iff there are no more stash or restore operations that are | 65 // Sets the mode iff there are no more stash or restore operations that are |
| 66 // still pending. |mode| can only be either |ACTIVE| or |INACTIVE|. | 66 // still pending. |mode| can only be either |ACTIVE| or |INACTIVE|. |
| 67 // |handler| is called immediately (in the same runloop) with a BOOL indicating | 67 // |handler| is called immediately (in the same runloop) with a BOOL indicating |
| 68 // whether the mode change was successful or not. |handler| can be nil. | 68 // whether the mode change was successful or not. |handler| can be nil. |
| 69 - (void)finalizeChangeToMode:(CRWBrowsingDataStoreMode)mode | 69 - (void)finalizeChangeToMode:(web::BrowsingDataStoreMode)mode |
| 70 andCallCompletionHandler:(void (^)(BOOL modeChangeWasSuccessful))handler; | 70 andCallCompletionHandler:(void (^)(BOOL modeChangeWasSuccessful))handler; |
| 71 | 71 |
| 72 // Changes the mode of the CRWBrowsingDataStore to |mode|. This is an | 72 // Changes the mode of the CRWBrowsingDataStore to |mode|. This is an |
| 73 // asynchronous operation and the mode is not changed immediately. | 73 // asynchronous operation and the mode is not changed immediately. |
| 74 // |completionHandler| can be nil. | 74 // |completionHandler| can be nil. |
| 75 // |completionHandler| is called on the main thread. This block has no return | 75 // |completionHandler| is called on the main thread. This block has no return |
| 76 // value and takes a single BOOL argument that indicates whether or not the | 76 // value and takes a single BOOL argument that indicates whether or not the |
| 77 // mode change was successfully changed to |mode|. | 77 // mode change was successfully changed to |mode|. |
| 78 - (void)changeMode:(CRWBrowsingDataStoreMode)mode | 78 - (void)changeMode:(web::BrowsingDataStoreMode)mode |
| 79 completionHandler:(void (^)(BOOL modeChangeWasSuccessful))completionHandler; | 79 completionHandler:(void (^)(BOOL modeChangeWasSuccessful))completionHandler; |
| 80 | 80 |
| 81 // The number of stash or restore operations that are still pending. | 81 // The number of stash or restore operations that are still pending. |
| 82 @property(nonatomic, assign) NSUInteger numberOfPendingStashOrRestoreOperations; | 82 @property(nonatomic, assign) NSUInteger numberOfPendingStashOrRestoreOperations; |
| 83 | 83 |
| 84 // Performs operations of type |operationType| on each of the | 84 // Performs operations of type |operationType| on each of the |
| 85 // |browsingDataManagers|. |operationType| cannot be |NONE|. | 85 // |browsingDataManagers|. |operationType| cannot be |NONE|. |
| 86 // Precondition: There must be no web views associated with the BrowserState. | 86 // Precondition: There must be no web views associated with the BrowserState. |
| 87 // |completionHandler| is called on the main thread and cannot be nil. | 87 // |completionHandler| is called on the main thread and cannot be nil. |
| 88 - (void)performOperationWithType:(OperationType)operationType | 88 - (void)performOperationWithType:(OperationType)operationType |
| (...skipping 11 matching lines...) Expand all Loading... |
| 100 // Enqueues |operation| to be run on |queue|. All operations are serialized to | 100 // Enqueues |operation| to be run on |queue|. All operations are serialized to |
| 101 // be run one after another. | 101 // be run one after another. |
| 102 - (void)addOperation:(NSOperation*)operation toQueue:(NSOperationQueue*)queue; | 102 - (void)addOperation:(NSOperation*)operation toQueue:(NSOperationQueue*)queue; |
| 103 @end | 103 @end |
| 104 | 104 |
| 105 @implementation CRWBrowsingDataStore { | 105 @implementation CRWBrowsingDataStore { |
| 106 web::BrowserState* _browserState; // Weak, owns this object. | 106 web::BrowserState* _browserState; // Weak, owns this object. |
| 107 // The delegate. | 107 // The delegate. |
| 108 base::WeakNSProtocol<id<CRWBrowsingDataStoreDelegate>> _delegate; | 108 base::WeakNSProtocol<id<CRWBrowsingDataStoreDelegate>> _delegate; |
| 109 // The mode of the CRWBrowsingDataStore. | 109 // The mode of the CRWBrowsingDataStore. |
| 110 CRWBrowsingDataStoreMode _mode; | 110 web::BrowsingDataStoreMode _mode; |
| 111 // The dictionary that maps a browsing data type to its | 111 // The dictionary that maps a browsing data type to its |
| 112 // CRWBrowsingDataManager. | 112 // CRWBrowsingDataManager. |
| 113 base::scoped_nsobject<NSDictionary> _browsingDataTypeMap; | 113 base::scoped_nsobject<NSDictionary> _browsingDataTypeMap; |
| 114 // The last operation that was enqueued to be run. Can be stash, restore or a | 114 // The last operation that was enqueued to be run. Can be stash, restore or a |
| 115 // delete operation. | 115 // delete operation. |
| 116 base::scoped_nsobject<NSOperation> _lastDispatchedOperation; | 116 base::scoped_nsobject<NSOperation> _lastDispatchedOperation; |
| 117 // The last dispatched stash or restore operation that was enqueued to be run. | 117 // The last dispatched stash or restore operation that was enqueued to be run. |
| 118 base::scoped_nsobject<NSOperation> _lastDispatchedStashOrRestoreOperation; | 118 base::scoped_nsobject<NSOperation> _lastDispatchedStashOrRestoreOperation; |
| 119 // The number of stash or restore operations that are still pending. If this | 119 // The number of stash or restore operations that are still pending. If this |
| 120 // value > 0 the mode of the CRWBrowsingDataStore is SYNCHRONIZING. The mode | 120 // value > 0 the mode of the CRWBrowsingDataStore is |CHANGING|. The mode |
| 121 // can be made ACTIVE or INACTIVE only be set when this value is 0. | 121 // can be made ACTIVE or INACTIVE only be set when this value is 0. |
| 122 NSUInteger _numberOfPendingStashOrRestoreOperations; | 122 NSUInteger _numberOfPendingStashOrRestoreOperations; |
| 123 } | 123 } |
| 124 | 124 |
| 125 + (NSOperationQueue*)operationQueueForStashAndRestoreOperations { | 125 + (NSOperationQueue*)operationQueueForStashAndRestoreOperations { |
| 126 static dispatch_once_t onceToken = 0; | 126 static dispatch_once_t onceToken = 0; |
| 127 static NSOperationQueue* operationQueueForStashAndRestoreOperations = nil; | 127 static NSOperationQueue* operationQueueForStashAndRestoreOperations = nil; |
| 128 dispatch_once(&onceToken, ^{ | 128 dispatch_once(&onceToken, ^{ |
| 129 operationQueueForStashAndRestoreOperations = | 129 operationQueueForStashAndRestoreOperations = |
| 130 [[NSOperationQueue alloc] init]; | 130 [[NSOperationQueue alloc] init]; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 156 - (instancetype)initWithBrowserState:(web::BrowserState*)browserState { | 156 - (instancetype)initWithBrowserState:(web::BrowserState*)browserState { |
| 157 self = [super init]; | 157 self = [super init]; |
| 158 if (self) { | 158 if (self) { |
| 159 DCHECK([NSThread isMainThread]); | 159 DCHECK([NSThread isMainThread]); |
| 160 // TODO(shreyasv): Instantiate the necessary CRWBrowsingDataManagers that | 160 // TODO(shreyasv): Instantiate the necessary CRWBrowsingDataManagers that |
| 161 // are encapsulated within this class. crbug.com/480654. | 161 // are encapsulated within this class. crbug.com/480654. |
| 162 _browserState = browserState; | 162 _browserState = browserState; |
| 163 web::ActiveStateManager* activeStateManager = | 163 web::ActiveStateManager* activeStateManager = |
| 164 web::BrowserState::GetActiveStateManager(browserState); | 164 web::BrowserState::GetActiveStateManager(browserState); |
| 165 DCHECK(activeStateManager); | 165 DCHECK(activeStateManager); |
| 166 _mode = activeStateManager->IsActive() ? ACTIVE : INACTIVE; | 166 _mode = activeStateManager->IsActive() ? web::ACTIVE : web::INACTIVE; |
| 167 // TODO(shreyasv): If the creation of CRWBrowsingDataManagers turns out to | 167 // TODO(shreyasv): If the creation of CRWBrowsingDataManagers turns out to |
| 168 // be an expensive operations re-visit this with a lazy-evaluation approach. | 168 // be an expensive operations re-visit this with a lazy-evaluation approach. |
| 169 base::scoped_nsobject<CRWCookieBrowsingDataManager> | 169 base::scoped_nsobject<CRWCookieBrowsingDataManager> |
| 170 cookieBrowsingDataManager([[CRWCookieBrowsingDataManager alloc] | 170 cookieBrowsingDataManager([[CRWCookieBrowsingDataManager alloc] |
| 171 initWithBrowserState:browserState]); | 171 initWithBrowserState:browserState]); |
| 172 _browsingDataTypeMap.reset([@{ | 172 _browsingDataTypeMap.reset([@{ |
| 173 @(web::BROWSING_DATA_TYPE_COOKIES) : cookieBrowsingDataManager, | 173 @(web::BROWSING_DATA_TYPE_COOKIES) : cookieBrowsingDataManager, |
| 174 } retain]); | 174 } retain]); |
| 175 } | 175 } |
| 176 return self; | 176 return self; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 225 case RESTORE: | 225 case RESTORE: |
| 226 return @selector(restoreData); | 226 return @selector(restoreData); |
| 227 case REMOVE: | 227 case REMOVE: |
| 228 return [self browsingDataManagerSelectorForRemoveOperationType]; | 228 return [self browsingDataManagerSelectorForRemoveOperationType]; |
| 229 }; | 229 }; |
| 230 NOTREACHED(); | 230 NOTREACHED(); |
| 231 return nullptr; | 231 return nullptr; |
| 232 } | 232 } |
| 233 | 233 |
| 234 - (SEL)browsingDataManagerSelectorForRemoveOperationType { | 234 - (SEL)browsingDataManagerSelectorForRemoveOperationType { |
| 235 if (self.mode == ACTIVE) { | 235 if (self.mode == web::ACTIVE) { |
| 236 return @selector(removeDataAtCanonicalPath); | 236 return @selector(removeDataAtCanonicalPath); |
| 237 } | 237 } |
| 238 if (self.mode == INACTIVE) { | 238 if (self.mode == web::INACTIVE) { |
| 239 return @selector(removeDataAtStashPath); | 239 return @selector(removeDataAtStashPath); |
| 240 } | 240 } |
| 241 DCHECK(_lastDispatchedStashOrRestoreOperation); | 241 DCHECK(_lastDispatchedStashOrRestoreOperation); |
| 242 NSString* lastDispatchedStashOrRestoreOperationName = | 242 NSString* lastDispatchedStashOrRestoreOperationName = |
| 243 [_lastDispatchedStashOrRestoreOperation name]; | 243 [_lastDispatchedStashOrRestoreOperation name]; |
| 244 if ([lastDispatchedStashOrRestoreOperationName | 244 if ([lastDispatchedStashOrRestoreOperationName |
| 245 isEqual:kRestoreOperationName]) { | 245 isEqual:kRestoreOperationName]) { |
| 246 return @selector(removeDataAtCanonicalPath); | 246 return @selector(removeDataAtCanonicalPath); |
| 247 } | 247 } |
| 248 if ([lastDispatchedStashOrRestoreOperationName isEqual:kStashOperationName]) { | 248 if ([lastDispatchedStashOrRestoreOperationName isEqual:kStashOperationName]) { |
| 249 return @selector(removeDataAtStashPath); | 249 return @selector(removeDataAtStashPath); |
| 250 } | 250 } |
| 251 NOTREACHED(); | 251 NOTREACHED(); |
| 252 return nullptr; | 252 return nullptr; |
| 253 } | 253 } |
| 254 | 254 |
| 255 + (BOOL)automaticallyNotifiesObserversForKey:(NSString*)key { | 255 + (BOOL)automaticallyNotifiesObserversForKey:(NSString*)key { |
| 256 // It is necessary to override this for |mode| because the default KVO | 256 // It is necessary to override this for |mode| because the default KVO |
| 257 // behavior in NSObject is to fire a notification irrespective of if an actual | 257 // behavior in NSObject is to fire a notification irrespective of if an actual |
| 258 // change was made to the ivar or not. The |mode| property needs fine grained | 258 // change was made to the ivar or not. The |mode| property needs fine grained |
| 259 // control over the actual notifications being fired since observers need to | 259 // control over the actual notifications being fired since observers need to |
| 260 // be notified iff the |mode| actually changed. | 260 // be notified iff the |mode| actually changed. |
| 261 if ([key isEqual:@"mode"]) { | 261 if ([key isEqual:@"mode"]) { |
| 262 return NO; | 262 return NO; |
| 263 } | 263 } |
| 264 return [super automaticallyNotifiesObserversForKey:(NSString*)key]; | 264 return [super automaticallyNotifiesObserversForKey:(NSString*)key]; |
| 265 } | 265 } |
| 266 | 266 |
| 267 - (CRWBrowsingDataStoreMode)mode { | 267 - (web::BrowsingDataStoreMode)mode { |
| 268 DCHECK([NSThread isMainThread]); | 268 DCHECK([NSThread isMainThread]); |
| 269 return _mode; | 269 return _mode; |
| 270 } | 270 } |
| 271 | 271 |
| 272 - (void)setMode:(CRWBrowsingDataStoreMode)mode { | 272 - (void)setMode:(web::BrowsingDataStoreMode)mode { |
| 273 DCHECK([NSThread isMainThread]); | 273 DCHECK([NSThread isMainThread]); |
| 274 if (_mode == mode) { | 274 if (_mode == mode) { |
| 275 return; | 275 return; |
| 276 } | 276 } |
| 277 if (mode == ACTIVE || mode == INACTIVE) { | 277 if (mode == web::ACTIVE || mode == web::INACTIVE) { |
| 278 DCHECK(!self.numberOfPendingStashOrRestoreOperations); | 278 DCHECK(!self.numberOfPendingStashOrRestoreOperations); |
| 279 } | 279 } |
| 280 [self willChangeValueForKey:@"mode"]; | 280 [self willChangeValueForKey:@"mode"]; |
| 281 _mode = mode; | 281 _mode = mode; |
| 282 [self didChangeValueForKey:@"mode"]; | 282 [self didChangeValueForKey:@"mode"]; |
| 283 } | 283 } |
| 284 | 284 |
| 285 - (void)finalizeChangeToMode:(CRWBrowsingDataStoreMode)mode | 285 - (void)finalizeChangeToMode:(web::BrowsingDataStoreMode)mode |
| 286 andCallCompletionHandler:(void (^)(BOOL modeChangeWasSuccessful))handler { | 286 andCallCompletionHandler:(void (^)(BOOL modeChangeWasSuccessful))handler { |
| 287 DCHECK([NSThread isMainThread]); | 287 DCHECK([NSThread isMainThread]); |
| 288 DCHECK_NE(SYNCHRONIZING, mode); | 288 DCHECK_NE(web::CHANGING, mode); |
| 289 | 289 |
| 290 BOOL modeChangeWasSuccessful = NO; | 290 BOOL modeChangeWasSuccessful = NO; |
| 291 if (!self.numberOfPendingStashOrRestoreOperations) { | 291 if (!self.numberOfPendingStashOrRestoreOperations) { |
| 292 [self setMode:mode]; | 292 [self setMode:mode]; |
| 293 modeChangeWasSuccessful = YES; | 293 modeChangeWasSuccessful = YES; |
| 294 } | 294 } |
| 295 if (handler) { | 295 if (handler) { |
| 296 handler(modeChangeWasSuccessful); | 296 handler(modeChangeWasSuccessful); |
| 297 } | 297 } |
| 298 } | 298 } |
| 299 | 299 |
| 300 - (NSUInteger)numberOfPendingStashOrRestoreOperations { | 300 - (NSUInteger)numberOfPendingStashOrRestoreOperations { |
| 301 DCHECK([NSThread isMainThread]); | 301 DCHECK([NSThread isMainThread]); |
| 302 return _numberOfPendingStashOrRestoreOperations; | 302 return _numberOfPendingStashOrRestoreOperations; |
| 303 } | 303 } |
| 304 | 304 |
| 305 - (void)setNumberOfPendingStashOrRestoreOperations: | 305 - (void)setNumberOfPendingStashOrRestoreOperations: |
| 306 (NSUInteger)numberOfPendingStashOrRestoreOperations { | 306 (NSUInteger)numberOfPendingStashOrRestoreOperations { |
| 307 DCHECK([NSThread isMainThread]); | 307 DCHECK([NSThread isMainThread]); |
| 308 _numberOfPendingStashOrRestoreOperations = | 308 _numberOfPendingStashOrRestoreOperations = |
| 309 numberOfPendingStashOrRestoreOperations; | 309 numberOfPendingStashOrRestoreOperations; |
| 310 } | 310 } |
| 311 | 311 |
| 312 - (void)makeActiveWithCompletionHandler: | 312 - (void)makeActiveWithCompletionHandler: |
| 313 (void (^)(BOOL success))completionHandler { | 313 (void (^)(BOOL success))completionHandler { |
| 314 DCHECK([NSThread isMainThread]); | 314 DCHECK([NSThread isMainThread]); |
| 315 | 315 |
| 316 [self changeMode:ACTIVE completionHandler:completionHandler]; | 316 [self changeMode:web::ACTIVE completionHandler:completionHandler]; |
| 317 } | 317 } |
| 318 | 318 |
| 319 - (void)makeInactiveWithCompletionHandler: | 319 - (void)makeInactiveWithCompletionHandler: |
| 320 (void (^)(BOOL success))completionHandler { | 320 (void (^)(BOOL success))completionHandler { |
| 321 DCHECK([NSThread isMainThread]); | 321 DCHECK([NSThread isMainThread]); |
| 322 | 322 |
| 323 [self changeMode:INACTIVE completionHandler:completionHandler]; | 323 [self changeMode:web::INACTIVE completionHandler:completionHandler]; |
| 324 } | 324 } |
| 325 | 325 |
| 326 - (void)changeMode:(CRWBrowsingDataStoreMode)mode | 326 - (void)changeMode:(web::BrowsingDataStoreMode)mode |
| 327 completionHandler: | 327 completionHandler: |
| 328 (void (^)(BOOL modeChangeWasSuccessful))completionHandler { | 328 (void (^)(BOOL modeChangeWasSuccessful))completionHandler { |
| 329 DCHECK([NSThread isMainThread]); | 329 DCHECK([NSThread isMainThread]); |
| 330 | 330 |
| 331 ProceduralBlock completionHandlerAfterPerformingOperation = ^{ | 331 ProceduralBlock completionHandlerAfterPerformingOperation = ^{ |
| 332 [self finalizeChangeToMode:mode andCallCompletionHandler:completionHandler]; | 332 [self finalizeChangeToMode:mode andCallCompletionHandler:completionHandler]; |
| 333 }; | 333 }; |
| 334 | 334 |
| 335 // Already in the desired mode. | 335 // Already in the desired mode. |
| 336 if (self.mode == mode) { | 336 if (self.mode == mode) { |
| 337 // As a caller of this API, it is awkward to get the callback before the | 337 // As a caller of this API, it is awkward to get the callback before the |
| 338 // method call has completed, hence defer it. | 338 // method call has completed, hence defer it. |
| 339 dispatch_async(dispatch_get_main_queue(), ^{ | 339 dispatch_async(dispatch_get_main_queue(), ^{ |
| 340 completionHandlerAfterPerformingOperation(); | 340 completionHandlerAfterPerformingOperation(); |
| 341 }); | 341 }); |
| 342 return; | 342 return; |
| 343 } | 343 } |
| 344 | 344 |
| 345 OperationType operationType = NONE; | 345 OperationType operationType = NONE; |
| 346 if (mode == ACTIVE) { | 346 if (mode == web::ACTIVE) { |
| 347 // By default a |RESTORE| operation is performed when the mode is changed | 347 // By default a |RESTORE| operation is performed when the mode is changed |
| 348 // to |ACTIVE|. | 348 // to |ACTIVE|. |
| 349 operationType = RESTORE; | 349 operationType = RESTORE; |
| 350 web::BrowsingDataStoreMakeActivePolicy makeActivePolicy = | 350 web::BrowsingDataStoreMakeActivePolicy makeActivePolicy = |
| 351 [_delegate decideMakeActiveOperationPolicyForBrowsingDataStore:self]; | 351 [_delegate decideMakeActiveOperationPolicyForBrowsingDataStore:self]; |
| 352 operationType = (makeActivePolicy == web::ADOPT) ? REMOVE : RESTORE; | 352 operationType = (makeActivePolicy == web::ADOPT) ? REMOVE : RESTORE; |
| 353 } else { | 353 } else { |
| 354 // By default a |STASH| operation is performed when the mode is changed to | 354 // By default a |STASH| operation is performed when the mode is changed to |
| 355 // |INACTIVE|. | 355 // |INACTIVE|. |
| 356 operationType = STASH; | 356 operationType = STASH; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 391 completionHandler:(ProceduralBlock)completionHandler { | 391 completionHandler:(ProceduralBlock)completionHandler { |
| 392 DCHECK([NSThread isMainThread]); | 392 DCHECK([NSThread isMainThread]); |
| 393 DCHECK(completionHandler); | 393 DCHECK(completionHandler); |
| 394 DCHECK_NE(NONE, operationType); | 394 DCHECK_NE(NONE, operationType); |
| 395 | 395 |
| 396 SEL selector = | 396 SEL selector = |
| 397 [self browsingDataManagerSelectorForOperationType:operationType]; | 397 [self browsingDataManagerSelectorForOperationType:operationType]; |
| 398 DCHECK(selector); | 398 DCHECK(selector); |
| 399 | 399 |
| 400 if (operationType == RESTORE || operationType == STASH) { | 400 if (operationType == RESTORE || operationType == STASH) { |
| 401 [self setMode:SYNCHRONIZING]; | 401 [self setMode:web::CHANGING]; |
| 402 ++self.numberOfPendingStashOrRestoreOperations; | 402 ++self.numberOfPendingStashOrRestoreOperations; |
| 403 completionHandler = ^{ | 403 completionHandler = ^{ |
| 404 --self.numberOfPendingStashOrRestoreOperations; | 404 --self.numberOfPendingStashOrRestoreOperations; |
| 405 // It is safe to this and does not lead to the block (|completionHandler|) | 405 // It is safe to this and does not lead to the block (|completionHandler|) |
| 406 // retaining itself. | 406 // retaining itself. |
| 407 completionHandler(); | 407 completionHandler(); |
| 408 }; | 408 }; |
| 409 } | 409 } |
| 410 | 410 |
| 411 id callCompletionHandlerOnMainThread = ^{ | 411 id callCompletionHandlerOnMainThread = ^{ |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 464 DCHECK(queue); | 464 DCHECK(queue); |
| 465 | 465 |
| 466 if (_lastDispatchedOperation) { | 466 if (_lastDispatchedOperation) { |
| 467 [operation addDependency:_lastDispatchedOperation]; | 467 [operation addDependency:_lastDispatchedOperation]; |
| 468 } | 468 } |
| 469 _lastDispatchedOperation.reset([operation retain]); | 469 _lastDispatchedOperation.reset([operation retain]); |
| 470 [queue addOperation:operation]; | 470 [queue addOperation:operation]; |
| 471 } | 471 } |
| 472 | 472 |
| 473 @end | 473 @end |
| OLD | NEW |