]> git.saurik.com Git - apple/security.git/blob - keychain/ckks/NSOperationCategories.m
Security-58286.51.6.tar.gz
[apple/security.git] / keychain / ckks / NSOperationCategories.m
1 /*
2 * Copyright (c) 2017 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 #import <Foundation/Foundation.h>
25 #import "keychain/ckks/NSOperationCategories.h"
26
27 @implementation NSOperation (CKKSUsefulPrintingOperation)
28 - (NSString*)selfname {
29 if(self.name) {
30 return [NSString stringWithFormat: @"%@(%@)", NSStringFromClass([self class]), self.name];
31 } else {
32 return NSStringFromClass([self class]);
33 }
34 }
35
36 -(void)linearDependencies: (NSHashTable*) collection {
37 @synchronized(collection) {
38 for(NSOperation* existingop in collection) {
39 if(existingop == self) {
40 // don't depend on yourself
41 continue;
42 }
43 [self addDependency: existingop];
44 }
45 [collection addObject:self];
46 }
47 }
48
49 -(void)linearDependenciesWithSelfFirst: (NSHashTable*) collection {
50 @synchronized(collection) {
51 for(NSOperation* existingop in collection) {
52 if(existingop == self) {
53 // don't depend on yourself
54 continue;
55 }
56
57 if([existingop isPending]) {
58 [existingop addDependency: self];
59 if([existingop isPending]) {
60 // Good, we're ahead of this one.
61 } else {
62 // It started before we told it to wait on us. Reverse the dependency.
63 [existingop removeDependency: self];
64 [self addDependency:existingop];
65 }
66 } else {
67 // Not a pending op? We depend on it.
68 [self addDependency: existingop];
69 }
70 }
71 [collection addObject:self];
72 }
73 }
74
75 -(NSString*)pendingDependenciesString:(NSString*)prefix {
76 NSArray* dependencies = [self.dependencies copy];
77 dependencies = [dependencies objectsAtIndexes: [dependencies indexesOfObjectsPassingTest: ^BOOL (id obj,
78 NSUInteger idx,
79 BOOL* stop) {
80 return [obj isFinished] ? NO : YES;
81 }]];
82
83 if(dependencies.count == 0u) {
84 return @"";
85 }
86
87 return [NSString stringWithFormat: @"%@%@", prefix, [dependencies componentsJoinedByString: @", "]];
88 }
89
90 - (NSString*)description {
91 NSString* state = ([self isFinished] ? @"finished" :
92 [self isCancelled] ? @"cancelled" :
93 [self isExecuting] ? @"executing" :
94 [self isReady] ? @"ready" :
95 @"pending");
96
97 return [NSString stringWithFormat: @"<%@: %@%@>", [self selfname], state, [self pendingDependenciesString: @" dep:"]];
98 }
99 - (NSString*)debugDescription {
100 NSString* state = ([self isFinished] ? @"finished" :
101 [self isCancelled] ? @"cancelled" :
102 [self isExecuting] ? @"executing" :
103 [self isReady] ? @"ready" :
104 @"pending");
105
106 return [NSString stringWithFormat: @"<%@ (%p): %@%@>", [self selfname], self, state, [self pendingDependenciesString: @" dep:"]];
107 }
108
109 - (BOOL)isPending {
110 return (!([self isExecuting] || [self isFinished] || [self isCancelled])) ? YES : NO;
111 }
112
113 - (void)addNullableDependency: (NSOperation*) op {
114 if(op) {
115 [self addDependency:op];
116 }
117 }
118
119 - (void)removeDependenciesUponCompletion
120 {
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];
126 }
127 };
128 }
129
130 @end
131
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];
136 blockOp.name = name;
137 return blockOp;
138 }
139 @end