OctagonFlags.m   [plain text]

#if OCTAGON

#import "keychain/ot/OctagonFlags.h"
#import "keychain/ot/OTStates.h"
#import "keychain/ckks/CKKSCondition.h"

@interface OctagonFlags ()
@property dispatch_queue_t queue;
@property NSMutableSet<OctagonFlag*>* flags;
@property (readonly) NSSet* allowableFlags;
@end

@implementation OctagonFlags

- (instancetype)initWithQueue:(dispatch_queue_t)queue
flags:(NSSet<OctagonFlag*>*)possibleFlags
{
if((self = [super init])) {
_queue = queue;
_flags = [NSMutableSet set];
_flagConditions = [[NSMutableDictionary alloc] init];
_allowableFlags = possibleFlags;

for(OctagonFlag* flag in possibleFlags) {
self.flagConditions[flag] = [[CKKSCondition alloc] init];
}
}
return self;
}

- (NSString*)description
{
return [NSString stringWithFormat:@"<OctagonFlags: %@>", [self contentsAsString]];
}

- (NSString*)contentsAsString
{
if(self.flags.count == 0) {
return @"none";
}
return [[self.flags allObjects] componentsJoinedByString:@","];
}

- (NSArray<NSString*>*)dumpFlags
{
return [self.flags allObjects];
}

- (BOOL)_onqueueContains:(nonnull OctagonFlag *)flag {
dispatch_assert_queue(self.queue);
return [self.flags containsObject:flag];
}

- (void)_onqueueSetFlag:(nonnull OctagonFlag *)flag {
dispatch_assert_queue(self.queue);
[self.flags addObject:flag];
}

- (CKKSCondition*)conditionForFlag:(OctagonFlag*)flag {
return self.flagConditions[flag];
}

- (void)setFlag:(nonnull OctagonFlag *)flag {
dispatch_sync(self.queue, ^{
[self _onqueueSetFlag:flag];
});
}

- (void)_onqueueRemoveFlag:(nonnull OctagonFlag *)flag {
dispatch_assert_queue(self.queue);

NSAssert([self.allowableFlags containsObject:flag], @"state machine tried to handle unknown flag %@", flag);

[self.flags removeObject:flag];
[self.flagConditions[flag] fulfill];
self.flagConditions[flag] = [[CKKSCondition alloc]init];
}

@end

#endif