2 * Copyright (c) 2017 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
24 #import <Foundation/Foundation.h>
25 #import "keychain/ckks/NSOperationCategories.h"
27 @implementation NSOperation (CKKSUsefulPrintingOperation)
28 - (NSString*)selfname {
30 return [NSString stringWithFormat: @"%@(%@)", NSStringFromClass([self class]), self.name];
32 return NSStringFromClass([self class]);
36 -(void)linearDependencies: (NSHashTable*) collection {
37 @synchronized(collection) {
38 for(NSOperation* existingop in collection) {
39 if(existingop == self) {
40 // don't depend on yourself
43 [self addDependency: existingop];
45 [collection addObject:self];
49 -(void)linearDependenciesWithSelfFirst: (NSHashTable*) collection {
50 @synchronized(collection) {
51 for(NSOperation* existingop in collection) {
52 if(existingop == self) {
53 // don't depend on yourself
57 if([existingop isPending]) {
58 [existingop addDependency: self];
59 if([existingop isPending]) {
60 // Good, we're ahead of this one.
62 // It started before we told it to wait on us. Reverse the dependency.
63 [existingop removeDependency: self];
64 [self addDependency:existingop];
67 // Not a pending op? We depend on it.
68 [self addDependency: existingop];
71 [collection addObject:self];
75 -(NSString*)pendingDependenciesString:(NSString*)prefix {
76 NSArray* dependencies = [self.dependencies copy];
77 dependencies = [dependencies objectsAtIndexes: [dependencies indexesOfObjectsPassingTest: ^BOOL (id obj,
80 return [obj isFinished] ? NO : YES;
83 if(dependencies.count == 0u) {
87 return [NSString stringWithFormat: @"%@%@", prefix, [dependencies componentsJoinedByString: @", "]];
90 - (NSString*)description {
91 NSString* state = ([self isFinished] ? @"finished" :
92 [self isCancelled] ? @"cancelled" :
93 [self isExecuting] ? @"executing" :
94 [self isReady] ? @"ready" :
97 return [NSString stringWithFormat: @"<%@: %@%@>", [self selfname], state, [self pendingDependenciesString: @" dep:"]];
99 - (NSString*)debugDescription {
100 NSString* state = ([self isFinished] ? @"finished" :
101 [self isCancelled] ? @"cancelled" :
102 [self isExecuting] ? @"executing" :
103 [self isReady] ? @"ready" :
106 return [NSString stringWithFormat: @"<%@ (%p): %@%@>", [self selfname], self, state, [self pendingDependenciesString: @" dep:"]];
110 return (!([self isExecuting] || [self isFinished] || [self isCancelled])) ? YES : NO;
113 - (void)addNullableDependency: (NSOperation*) op {
115 [self addDependency:op];
119 - (void)removeDependenciesUponCompletion
121 __weak __typeof(self) weakSelf = self;
122 self.completionBlock = ^{
123 __strong __typeof(weakSelf) strongSelf = weakSelf;
124 for (NSOperation *op in strongSelf.dependencies) {
125 [strongSelf removeDependency:op];
132 @implementation NSBlockOperation (CKKSUsefulConstructorOperation)
133 +(instancetype)named: (NSString*)name withBlock: (void(^)(void)) block {
134 // How many blocks could a block block if a block could block blocks?
135 NSBlockOperation* blockOp = [NSBlockOperation blockOperationWithBlock: block];