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