From cd4134c9dac11b810a37f7526413086f07122a69 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Fri, 31 Mar 2017 18:36:08 -0400 Subject: [PATCH 1/3] Apply assert to ensure singletons are only created once. // FREEBIE --- .../Attachments/TSAttachmentPointer.h | 4 ++- src/Messages/TSBlockingManager.m | 2 ++ src/Messages/TSMessagesManager.m | 4 ++- src/Network/WebSockets/TSSocketManager.h | 8 ++--- src/Network/WebSockets/TSSocketManager.m | 2 ++ src/Storage/TSStorageManager.h | 2 ++ src/Storage/TSStorageManager.m | 2 ++ src/Util/Asserts.h | 34 +++++++++++++++++++ 8 files changed, 51 insertions(+), 7 deletions(-) diff --git a/src/Messages/Attachments/TSAttachmentPointer.h b/src/Messages/Attachments/TSAttachmentPointer.h index cb8143fdb..becece41d 100644 --- a/src/Messages/Attachments/TSAttachmentPointer.h +++ b/src/Messages/Attachments/TSAttachmentPointer.h @@ -17,11 +17,13 @@ typedef NS_ENUM(NSUInteger, TSAttachmentPointerState) { */ @interface TSAttachmentPointer : TSAttachment +- (instancetype)init NS_UNAVAILABLE; + - (instancetype)initWithServerId:(UInt64)serverId key:(NSData *)key digest:(nullable NSData *)digest contentType:(NSString *)contentType - relay:(NSString *)relay NS_DESIGNATED_INITIALIZER; + relay:(NSString *)relay; @property (nonatomic, readonly) NSString *relay; @property (atomic) TSAttachmentPointerState state; diff --git a/src/Messages/TSBlockingManager.m b/src/Messages/TSBlockingManager.m index 032c3dc96..c10357402 100644 --- a/src/Messages/TSBlockingManager.m +++ b/src/Messages/TSBlockingManager.m @@ -66,6 +66,8 @@ NSString *const kTSStorageManager_SyncedBlockedPhoneNumbersKey = @"kTSStorageMan _storageManager = storageManager; _messageSender = messageSender; + OWSSingletonAssert(); + return self; } diff --git a/src/Messages/TSMessagesManager.m b/src/Messages/TSMessagesManager.m index 2f660901e..4ea23fc6d 100644 --- a/src/Messages/TSMessagesManager.m +++ b/src/Messages/TSMessagesManager.m @@ -105,7 +105,9 @@ NS_ASSUME_NONNULL_BEGIN _disappearingMessagesJob = [[OWSDisappearingMessagesJob alloc] initWithStorageManager:storageManager]; _incomingMessageFinder = [[OWSIncomingMessageFinder alloc] initWithDatabase:storageManager.database]; _blockingManager = [TSBlockingManager sharedManager]; - + + OWSSingletonAssert(); + return self; } diff --git a/src/Network/WebSockets/TSSocketManager.h b/src/Network/WebSockets/TSSocketManager.h index 9a6e81457..079eea6a2 100644 --- a/src/Network/WebSockets/TSSocketManager.h +++ b/src/Network/WebSockets/TSSocketManager.h @@ -1,9 +1,5 @@ // -// TSSocketManager.h -// TextSecureiOS -// -// Created by Frederic Jacobs on 17/05/14. -// Copyright (c) 2014 Open Whisper Systems. All rights reserved. +// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // #import @@ -23,6 +19,8 @@ extern NSString *const SocketConnectingNotification; @interface TSSocketManager : NSObject +- (instancetype)init NS_UNAVAILABLE; + + (void)becomeActiveFromForeground; + (void)becomeActiveFromBackgroundExpectMessage:(BOOL)expected; diff --git a/src/Network/WebSockets/TSSocketManager.m b/src/Network/WebSockets/TSSocketManager.m index 68404d339..83a2ad4a0 100644 --- a/src/Network/WebSockets/TSSocketManager.m +++ b/src/Network/WebSockets/TSSocketManager.m @@ -61,6 +61,8 @@ NSString *const SocketConnectingNotification = @"SocketConnectingNotification"; [self addObserver:self forKeyPath:@"status" options:0 context:kSocketStatusObservationContext]; + OWSSingletonAssert(); + return self; } diff --git a/src/Storage/TSStorageManager.h b/src/Storage/TSStorageManager.h index 08f41e367..a0c9be407 100644 --- a/src/Storage/TSStorageManager.h +++ b/src/Storage/TSStorageManager.h @@ -16,6 +16,8 @@ extern NSString *const TSUIDatabaseConnectionDidUpdateNotification; @interface TSStorageManager : NSObject +- (instancetype)init NS_UNAVAILABLE; + + (instancetype)sharedManager; /** diff --git a/src/Storage/TSStorageManager.m b/src/Storage/TSStorageManager.m index eaca489b8..ace86f0a2 100644 --- a/src/Storage/TSStorageManager.m +++ b/src/Storage/TSStorageManager.m @@ -129,6 +129,8 @@ static NSString *keychainDBPassAccount = @"TSDatabasePass"; [NSException raise:TSStorageManagerExceptionNameNoDatabase format:@"Failed to initialize database."]; } + + OWSSingletonAssert(); } return self; diff --git a/src/Util/Asserts.h b/src/Util/Asserts.h index d0cfbc728..6ec08413e 100755 --- a/src/Util/Asserts.h +++ b/src/Util/Asserts.h @@ -35,3 +35,37 @@ NSCAssert(0, @"Assertion failed: %s", CONVERT_EXPR_TO_STRING(X)); \ #endif #endif + +#pragma mark - Singleton Asserts + +// The "singleton asserts" can be used to ensure +// that we only create a singleton once. +// +// The simplest way to use them is the OWSSingletonAssert() macro. +// It is intended to be used inside the singleton's initializer. +// +// If, however, a singleton has multiple possible initializers, +// you need to: +// +// 1. Use OWSSingletonAssertFlag() outside the class definition. +// 2. Use OWSSingletonAssertInit() in each initializer. +#ifdef DEBUG + +#define OWSSingletonAssertFlag() static BOOL _isSingletonCreated = NO; + +#define OWSSingletonAssertInit() \ + @synchronized([self class]) \ + { \ + OWSAssert(!_isSingletonCreated); \ + _isSingletonCreated = YES; \ + } + +#define OWSSingletonAssert() OWSSingletonAssertFlag() OWSSingletonAssertInit() + +#else + +#define OWSSingletonAssertFlag() +#define OWSSingletonAssertInit() +#define OWSSingletonAssert() + +#endif From e038d24103dc710ab9bf5cfa66cddc8815f51dfe Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Fri, 31 Mar 2017 18:45:46 -0400 Subject: [PATCH 2/3] Apply assert to ensure singletons are only created once. // FREEBIE --- src/Account/TSAccountManager.h | 8 +++----- src/Account/TSAccountManager.m | 2 ++ src/Account/TSPrivacyPreferences.h | 7 +++++-- src/Account/TSPrivacyPreferences.m | 7 +++++-- src/Contacts/ContactsUpdater.m | 13 +++++++++++++ src/Contacts/PhoneNumberUtil.m | 2 ++ src/Messages/OWSMessageSender.h | 7 +++++-- src/Messages/OWSMessageSender.m | 2 ++ src/Network/API/TSNetworkManager.h | 2 ++ src/Network/API/TSNetworkManager.m | 2 ++ 10 files changed, 41 insertions(+), 11 deletions(-) diff --git a/src/Account/TSAccountManager.h b/src/Account/TSAccountManager.h index 63673a450..a9ca71119 100644 --- a/src/Account/TSAccountManager.h +++ b/src/Account/TSAccountManager.h @@ -1,9 +1,5 @@ // -// TSAccountManagement.h -// TextSecureKit -// -// Created by Frederic Jacobs on 27/10/14. -// Copyright (c) 2014 Open Whisper Systems. All rights reserved. +// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // #import @@ -21,6 +17,8 @@ static NSString *const TSRegistrationErrorUserInfoHTTPStatus = @"TSHTTPStatus"; #pragma mark - Initializers +- (instancetype)init NS_UNAVAILABLE; + - (instancetype)initWithNetworkManager:(TSNetworkManager *)networkManager storageManager:(TSStorageManager *)storageManager; diff --git a/src/Account/TSAccountManager.m b/src/Account/TSAccountManager.m index 0fbc7d8b7..63125df58 100644 --- a/src/Account/TSAccountManager.m +++ b/src/Account/TSAccountManager.m @@ -35,6 +35,8 @@ NS_ASSUME_NONNULL_BEGIN _networkManager = networkManager; _storageManager = storageManager; + OWSSingletonAssert(); + return self; } diff --git a/src/Account/TSPrivacyPreferences.h b/src/Account/TSPrivacyPreferences.h index c334db853..47c9af719 100644 --- a/src/Account/TSPrivacyPreferences.h +++ b/src/Account/TSPrivacyPreferences.h @@ -1,5 +1,6 @@ -// Created by Michael Kirk on 11/7/16. -// Copyright © 2016 Open Whisper Systems. All rights reserved. +// +// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// #import "TSYapDatabaseObject.h" @@ -7,6 +8,8 @@ NS_ASSUME_NONNULL_BEGIN @interface TSPrivacyPreferences : TSYapDatabaseObject +- (instancetype)init NS_UNAVAILABLE; + + (instancetype)sharedInstance; @property BOOL shouldBlockOnIdentityChange; diff --git a/src/Account/TSPrivacyPreferences.m b/src/Account/TSPrivacyPreferences.m index 635e8097a..fe3aa7054 100644 --- a/src/Account/TSPrivacyPreferences.m +++ b/src/Account/TSPrivacyPreferences.m @@ -1,5 +1,6 @@ -// Created by Michael Kirk on 11/7/16. -// Copyright © 2016 Open Whisper Systems. All rights reserved. +// +// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// #import "TSPrivacyPreferences.h" @@ -37,6 +38,8 @@ NSString *const TSPrivacyPreferencesSingletonKey = @"TSPrivacyPreferences"; _shouldBlockOnIdentityChange = shouldBlockOnIdentityChange; + OWSSingletonAssert(); + return self; } diff --git a/src/Contacts/ContactsUpdater.m b/src/Contacts/ContactsUpdater.m index c2c22ce7f..daae4123b 100644 --- a/src/Contacts/ContactsUpdater.m +++ b/src/Contacts/ContactsUpdater.m @@ -25,6 +25,19 @@ NS_ASSUME_NONNULL_BEGIN return sharedInstance; } + +- (instancetype)init +{ + self = [super init]; + if (!self) { + return self; + } + + OWSSingletonAssert(); + + return self; +} + - (nullable SignalRecipient *)synchronousLookup:(NSString *)identifier error:(NSError **)error { dispatch_semaphore_t sema = dispatch_semaphore_create(0); diff --git a/src/Contacts/PhoneNumberUtil.m b/src/Contacts/PhoneNumberUtil.m index 63783da23..a54921d64 100644 --- a/src/Contacts/PhoneNumberUtil.m +++ b/src/Contacts/PhoneNumberUtil.m @@ -23,6 +23,8 @@ if (self) { _nbPhoneNumberUtil = [[NBPhoneNumberUtil alloc] init]; + + OWSSingletonAssert(); } return self; diff --git a/src/Messages/OWSMessageSender.h b/src/Messages/OWSMessageSender.h index 76b0a4ba4..7d8c865bf 100644 --- a/src/Messages/OWSMessageSender.h +++ b/src/Messages/OWSMessageSender.h @@ -1,5 +1,6 @@ -// Created by Michael Kirk on 10/7/16. -// Copyright © 2016 Open Whisper Systems. All rights reserved. +// +// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// NS_ASSUME_NONNULL_BEGIN @@ -23,6 +24,8 @@ NS_SWIFT_NAME(MessageSender) ContactsUpdater *_contactsUpdater; } +- (instancetype)init NS_UNAVAILABLE; + - (instancetype)initWithNetworkManager:(TSNetworkManager *)networkManager storageManager:(TSStorageManager *)storageManager contactsManager:(id)contactsManager diff --git a/src/Messages/OWSMessageSender.m b/src/Messages/OWSMessageSender.m index c1c168c73..136f59c9b 100644 --- a/src/Messages/OWSMessageSender.m +++ b/src/Messages/OWSMessageSender.m @@ -288,6 +288,8 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; _dbConnection = storageManager.newDatabaseConnection; _disappearingMessagesJob = [[OWSDisappearingMessagesJob alloc] initWithStorageManager:storageManager]; + OWSSingletonAssert(); + return self; } diff --git a/src/Network/API/TSNetworkManager.h b/src/Network/API/TSNetworkManager.h index 08da37b94..62f06e3d3 100644 --- a/src/Network/API/TSNetworkManager.h +++ b/src/Network/API/TSNetworkManager.h @@ -28,6 +28,8 @@ NS_ASSUME_NONNULL_BEGIN @interface TSNetworkManager : NSObject +- (instancetype)init NS_UNAVAILABLE; + + (id)sharedManager; - (void)makeRequest:(TSRequest *)request diff --git a/src/Network/API/TSNetworkManager.m b/src/Network/API/TSNetworkManager.m index b79bb609a..e5e5bbc85 100644 --- a/src/Network/API/TSNetworkManager.m +++ b/src/Network/API/TSNetworkManager.m @@ -43,6 +43,8 @@ typedef void (^failureBlock)(NSURLSessionDataTask *task, NSError *error); _signalService = signalService; + OWSSingletonAssert(); + return self; } From f1e770fa0a3ee31aab43d476fc5301d84e5e12a0 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Mon, 3 Apr 2017 14:23:25 -0400 Subject: [PATCH 3/3] Respond to CR. // FREEBIE --- src/Messages/Attachments/TSAttachmentPointer.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Messages/Attachments/TSAttachmentPointer.h b/src/Messages/Attachments/TSAttachmentPointer.h index becece41d..cb8143fdb 100644 --- a/src/Messages/Attachments/TSAttachmentPointer.h +++ b/src/Messages/Attachments/TSAttachmentPointer.h @@ -17,13 +17,11 @@ typedef NS_ENUM(NSUInteger, TSAttachmentPointerState) { */ @interface TSAttachmentPointer : TSAttachment -- (instancetype)init NS_UNAVAILABLE; - - (instancetype)initWithServerId:(UInt64)serverId key:(NSData *)key digest:(nullable NSData *)digest contentType:(NSString *)contentType - relay:(NSString *)relay; + relay:(NSString *)relay NS_DESIGNATED_INITIALIZER; @property (nonatomic, readonly) NSString *relay; @property (atomic) TSAttachmentPointerState state;