diff --git a/AWSCore/Utility/AWSSynchronizedMutableDictionary.m b/AWSCore/Utility/AWSSynchronizedMutableDictionary.m index 7144f333d57..82ab031e614 100644 --- a/AWSCore/Utility/AWSSynchronizedMutableDictionary.m +++ b/AWSCore/Utility/AWSSynchronizedMutableDictionary.m @@ -74,13 +74,13 @@ - (id)objectForKey:(id)aKey { } - (void)setObject:(id)anObject forKey:(id)aKey { - dispatch_barrier_async(self.dispatchQueue, ^{ + dispatch_barrier_sync(self.dispatchQueue, ^{ [self.dictionary setObject:anObject forKey:aKey]; }); } - (void)removeObject:(id)object { - dispatch_barrier_async(self.dispatchQueue, ^{ + dispatch_barrier_sync(self.dispatchQueue, ^{ for (NSString *key in self.dictionary) { if (object == self.dictionary[key]) { [self.dictionary removeObjectForKey:key]; @@ -91,19 +91,19 @@ - (void)removeObject:(id)object { } - (void)removeObjectForKey:(id)aKey { - dispatch_barrier_async(self.dispatchQueue, ^{ + dispatch_barrier_sync(self.dispatchQueue, ^{ [self.dictionary removeObjectForKey:aKey]; }); } - (void)removeAllObjects { - dispatch_barrier_async(self.dispatchQueue, ^{ + dispatch_barrier_sync(self.dispatchQueue, ^{ [self.dictionary removeAllObjects]; }); } - (void)mutateWithBlock:(void (^)(NSMutableDictionary *))block { - dispatch_barrier_async(self.dispatchQueue, ^{ + dispatch_barrier_sync(self.dispatchQueue, ^{ block(self.dictionary); }); } @@ -112,7 +112,7 @@ + (void)mutateSyncedDictionaries:(NSArray *) AWSSynchronizedMutableDictionary *first = [dictionaries firstObject]; if (!first) { return; } - dispatch_barrier_async(first.dispatchQueue, ^{ + dispatch_barrier_sync(first.dispatchQueue, ^{ [dictionaries enumerateObjectsUsingBlock:^(AWSSynchronizedMutableDictionary * _Nonnull atomicDictionary, NSUInteger index, BOOL * _Nonnull stop) { NSCAssert([first.syncKey isEqual:atomicDictionary.syncKey], @"Sync keys much match"); block(atomicDictionary.instanceKey, atomicDictionary.dictionary); diff --git a/AWSIoT/Internal/AWSIoTAtomicDictionary.h b/AWSIoT/Internal/AWSIoTAtomicDictionary.h new file mode 100644 index 00000000000..400aa959428 --- /dev/null +++ b/AWSIoT/Internal/AWSIoTAtomicDictionary.h @@ -0,0 +1,36 @@ +// +// Copyright 2010-2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). +// You may not use this file except in compliance with the License. +// A copy of the License is located at +// +// http://aws.amazon.com/apache2.0 +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface AWSIoTAtomicDictionary : NSObject + +@property (readonly, copy) NSArray *allKeys; +@property (readonly, copy) NSArray *allValues; + +/// Create new instance. +- (instancetype)init; + +- (id)objectForKey:(id)aKey; +- (void)setObject:(id)anObject forKey:(id )aKey; + +- (void)removeObjectForKey:(id)aKey; +- (void)removeAllObjects; + +@end + +NS_ASSUME_NONNULL_END diff --git a/AWSIoT/Internal/AWSIoTAtomicDictionary.m b/AWSIoT/Internal/AWSIoTAtomicDictionary.m new file mode 100644 index 00000000000..bbbdd939f09 --- /dev/null +++ b/AWSIoT/Internal/AWSIoTAtomicDictionary.m @@ -0,0 +1,75 @@ +// +// Copyright 2010-2024 Amazon.com, Inc. or its affiliates. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"). +// You may not use this file except in compliance with the License. +// A copy of the License is located at +// +// http://aws.amazon.com/apache2.0 +// +// or in the "license" file accompanying this file. This file is distributed +// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either +// express or implied. See the License for the specific language governing +// permissions and limitations under the License. +// + +#import "AWSIoTAtomicDictionary.h" + +@interface AWSIoTAtomicDictionary() + +@property (nonatomic, strong) NSMutableDictionary *dictionary; +@property (nonatomic, strong) NSLock *lock; + +@end + +@implementation AWSIoTAtomicDictionary + +- (instancetype)init { + self = [super init]; + if (self) { + _lock = [[NSLock alloc] init]; + _dictionary = [NSMutableDictionary new]; + } + return self; +} + +- (NSArray *)allKeys { + [self.lock lock]; + NSArray * result = self.dictionary.allKeys; + [self.lock unlock]; + return result; +} + +- (NSArray *)allValues { + [self.lock lock]; + NSArray * result = self.dictionary.allValues; + [self.lock unlock]; + return result; +} + +- (id)objectForKey:(id)aKey { + [self.lock lock]; + id result = [self.dictionary objectForKey:aKey]; + [self.lock unlock]; + return result; +} + +- (void)setObject:(id)anObject forKey:(id)aKey { + [self.lock lock]; + [self.dictionary setObject:anObject forKey:aKey]; + [self.lock unlock]; +} + +- (void)removeObjectForKey:(id)aKey { + [self.lock lock]; + [self.dictionary removeObjectForKey:aKey]; + [self.lock unlock]; +} + +- (void)removeAllObjects { + [self.lock lock]; + [self.dictionary removeAllObjects]; + [self.lock unlock]; +} + +@end diff --git a/AWSIoT/Internal/AWSIoTMQTTClient.m b/AWSIoT/Internal/AWSIoTMQTTClient.m index e0b6e83b258..010a2df956f 100644 --- a/AWSIoT/Internal/AWSIoTMQTTClient.m +++ b/AWSIoT/Internal/AWSIoTMQTTClient.m @@ -25,6 +25,7 @@ #import "AWSMQTTMessage.h" #import "AWSIoTManager.h" #import "AWSIoTStreamThread.h" +#import "AWSIoTAtomicDictionary.h" @implementation AWSIoTMQTTTopicModel @end @@ -38,7 +39,7 @@ @interface AWSIoTMQTTClient()