From cf15e294931d99260fb9a0862f8f69d2eee5c4a5 Mon Sep 17 00:00:00 2001 From: buff Date: Fri, 6 Oct 2017 16:46:24 +0200 Subject: [PATCH] IOSAD-49 first session for thread approach. --- pEpObjCAdapter.xcodeproj/project.pbxproj | 6 ++ pEpObjCAdapter/PEPCopyableThread.h | 17 +++- pEpObjCAdapter/PEPCopyableThread.m | 16 +++- pEpObjCAdapter/PEPObjCAdapter.m | 32 ++----- pEpObjCAdapter/PEPSessionProvider.h | 19 +++++ pEpObjCAdapter/PEPSessionProvider.m | 102 +++++++++++++++++++++++ 6 files changed, 163 insertions(+), 29 deletions(-) create mode 100644 pEpObjCAdapter/PEPSessionProvider.h create mode 100644 pEpObjCAdapter/PEPSessionProvider.m diff --git a/pEpObjCAdapter.xcodeproj/project.pbxproj b/pEpObjCAdapter.xcodeproj/project.pbxproj index b2eab6d..a478947 100644 --- a/pEpObjCAdapter.xcodeproj/project.pbxproj +++ b/pEpObjCAdapter.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ 1508AEAF1F8792AC001D5230 /* PEPCopyableThread.m in Sources */ = {isa = PBXBuildFile; fileRef = 1508AEAE1F8792AC001D5230 /* PEPCopyableThread.m */; }; + 15206CAA1F8BA183003FF880 /* PEPSessionProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 15206CA91F8BA183003FF880 /* PEPSessionProvider.m */; }; 43209B3D1ECC2DA7007E7E2E /* NSArray+Extension.m in Sources */ = {isa = PBXBuildFile; fileRef = 43209B271ECC2ACD007E7E2E /* NSArray+Extension.m */; }; 43209B3E1ECC2DAB007E7E2E /* PEPCSVScanner.m in Sources */ = {isa = PBXBuildFile; fileRef = 43209B291ECC2ACD007E7E2E /* PEPCSVScanner.m */; }; 43209B3F1ECC2DB0007E7E2E /* PEPLanguage.m in Sources */ = {isa = PBXBuildFile; fileRef = 43209B2B1ECC2ACD007E7E2E /* PEPLanguage.m */; }; @@ -106,6 +107,8 @@ /* Begin PBXFileReference section */ 1508AEAD1F8792AC001D5230 /* PEPCopyableThread.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PEPCopyableThread.h; sourceTree = ""; }; 1508AEAE1F8792AC001D5230 /* PEPCopyableThread.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PEPCopyableThread.m; sourceTree = ""; }; + 15206CA81F8BA183003FF880 /* PEPSessionProvider.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PEPSessionProvider.h; sourceTree = ""; }; + 15206CA91F8BA183003FF880 /* PEPSessionProvider.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PEPSessionProvider.m; sourceTree = ""; }; 352988AA1AEF964100FA7E2E /* libpEpObjCAdapter.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libpEpObjCAdapter.a; sourceTree = BUILT_PRODUCTS_DIR; }; 35FB0ABB1B57F97E00377032 /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; 35FB0ABD1B57F99D00377032 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; @@ -225,6 +228,8 @@ 43D27DE51F5DA7B700795687 /* NSDictionary+Extension.m */, 1508AEAD1F8792AC001D5230 /* PEPCopyableThread.h */, 1508AEAE1F8792AC001D5230 /* PEPCopyableThread.m */, + 15206CA81F8BA183003FF880 /* PEPSessionProvider.h */, + 15206CA91F8BA183003FF880 /* PEPSessionProvider.m */, ); path = pEpObjCAdapter; sourceTree = ""; @@ -407,6 +412,7 @@ buildActionMask = 2147483647; files = ( 1508AEAF1F8792AC001D5230 /* PEPCopyableThread.m in Sources */, + 15206CAA1F8BA183003FF880 /* PEPSessionProvider.m in Sources */, 43209B411ECC2DB8007E7E2E /* PEPObjCAdapter.m in Sources */, 43D27DE61F5DA7B700795687 /* NSDictionary+Extension.m in Sources */, 43209B431ECC2DC0007E7E2E /* PEPSession.m in Sources */, diff --git a/pEpObjCAdapter/PEPCopyableThread.h b/pEpObjCAdapter/PEPCopyableThread.h index 5d1de7f..0cdfac7 100644 --- a/pEpObjCAdapter/PEPCopyableThread.h +++ b/pEpObjCAdapter/PEPCopyableThread.h @@ -8,14 +8,27 @@ #import +@class PEPCopyableThread; + /** Wrapper around NSThread. Created solely to be able to use a thread as key in a NSDIctionary (e.g. conform to NSCopying). */ @interface PEPCopyableThread : NSObject -@property (atomic, strong, readonly) NSThread *thread; +@property (atomic, strong, readonly) NSThread * _Nullable thread; + +- (instancetype _Nonnull )initWithThread:(NSThread * _Nonnull)thread; -- (instancetype)initWithThread:(NSThread * _Nonnull)thread; +/** + A Boolean value that indicates whether the receiver has finished execution. + @return YES if the receiver has finished execution, otherwise NO. + */ +- (BOOL)isFinished; + +/** + Changes the cancelled state of the receiver to indicate that it should exit. + */ +- (void)cancel; @end diff --git a/pEpObjCAdapter/PEPCopyableThread.m b/pEpObjCAdapter/PEPCopyableThread.m index 6db49e8..f116484 100644 --- a/pEpObjCAdapter/PEPCopyableThread.m +++ b/pEpObjCAdapter/PEPCopyableThread.m @@ -14,6 +14,16 @@ @implementation PEPCopyableThread +- (BOOL)isFinished +{ + return self.thread.isFinished || !self.thread; +} + +- (void)cancel +{ + [self.thread cancel]; +} + #pragma mark - Life Cycle - (instancetype)init @@ -22,7 +32,7 @@ return nil; } -- (instancetype)initWithThread:(NSThread * _Nonnull)thread +- (instancetype)initWithThread:(NSThread * _Nonnull)thread; { self = [super init]; if (self) { @@ -31,6 +41,8 @@ return self; } +#pragma mark - NSObject + - (BOOL)isEqual:(PEPCopyableThread *)object { return [self.thread isEqual:object.thread]; @@ -54,6 +66,4 @@ return copy; } - - @end diff --git a/pEpObjCAdapter/PEPObjCAdapter.m b/pEpObjCAdapter/PEPObjCAdapter.m index 42c8c91..e2bd1d7 100644 --- a/pEpObjCAdapter/PEPObjCAdapter.m +++ b/pEpObjCAdapter/PEPObjCAdapter.m @@ -11,7 +11,9 @@ #import "PEPObjCAdapter.h" #import "PEPObjCAdapter+Internal.h" #import "PEPMessage.h" +#import "PEPSessionProvider.h" #include "keymanagement.h" +#import "PEPCopyableThread.h" /////////////////////////////////////////////////////////////////////////////// // Keyserver and Identity lookup - C part @@ -110,30 +112,12 @@ static NSLock *s_initLock; + (PEPSession * _Nonnull)session { - static NSMutableDictionary *sessionForThreadDict; - static NSObject *lock = nil; - - static dispatch_once_t once; - dispatch_once(&once, ^{ - sessionForThreadDict = [NSMutableDictionary new]; - lock = [NSObject new]; - }); - - @synchronized(lock) { - NSThread *currentThread = [NSThread currentThread]; - PEPSession *session = sessionForThreadDict[currentThread]; - if (!session) { - session = [[PEPSession alloc] initInternal]; - sessionForThreadDict[currentThread] = session; - } - - return session; - } + return [PEPSessionProvider session]; } + (void)cleanup { - // for + [PEPSessionProvider cleanup]; } + (void)initialize @@ -204,8 +188,8 @@ static NSLock *s_initLock; } + (NSString *) copyAssetIntoDocumentsDirectory:(NSBundle *)rootBundle - :(NSString *)bundleName - :(NSString *)fileName{ + :(NSString *)bundleName + :(NSString *)fileName{ NSURL *homeUrl = [PEPObjCAdapter createAndSetHomeDirectory]; NSString *documentsDirectory = [homeUrl path]; @@ -242,8 +226,8 @@ static NSLock *s_initLock; + (void)setupTrustWordsDB:(NSBundle *)rootBundle{ NSString *systemDBPath = [PEPObjCAdapter copyAssetIntoDocumentsDirectory:rootBundle - :@"pEpTrustWords.bundle" - :@"system.db"]; + :@"pEpTrustWords.bundle" + :@"system.db"]; if (SystemDB) { free((void *) SystemDB); } diff --git a/pEpObjCAdapter/PEPSessionProvider.h b/pEpObjCAdapter/PEPSessionProvider.h new file mode 100644 index 0000000..797167d --- /dev/null +++ b/pEpObjCAdapter/PEPSessionProvider.h @@ -0,0 +1,19 @@ +// +// PEPSessionProvider.h +// pEpObjCAdapter +// +// Created by Andreas Buff on 09.10.17. +// Copyright © 2017 p≡p. All rights reserved. +// + +#import + +@class PEPSession; + +@interface PEPSessionProvider : NSObject + ++ (PEPSession * _Nonnull)session; + ++ (void)cleanup; + +@end diff --git a/pEpObjCAdapter/PEPSessionProvider.m b/pEpObjCAdapter/PEPSessionProvider.m new file mode 100644 index 0000000..7e0c9bd --- /dev/null +++ b/pEpObjCAdapter/PEPSessionProvider.m @@ -0,0 +1,102 @@ +// +// PEPSessionProvider.m +// pEpObjCAdapter +// +// Created by Andreas Buff on 09.10.17. +// Copyright © 2017 p≡p. All rights reserved. +// + +#import "PEPSessionProvider.h" + +#import "PEPSession.h" +#import "PEPSession+Internal.h" +#import "PEPCopyableThread.h" + +@implementation PEPSessionProvider + +static NSLock *s_sessionForThreadLock = nil; +static NSMutableDictionary *s_sessionForThreadDict; + +#pragma mark - Public API + ++ (PEPSession * _Nonnull)session +{ + [[self sessionForThreadLock] lock]; + + PEPCopyableThread *currentThread = [[PEPCopyableThread alloc] initWithThread:[NSThread currentThread]]; + NSMutableDictionary *dict = [self sessionForThreadDict]; + PEPSession *session = dict[currentThread]; + if (!session) { + session = [[PEPSession alloc] initInternal]; + dict[currentThread] = session; + } + [self nullifySesssionOfFinishedThreads]; + + [[self sessionForThreadLock] unlock]; + + return session; +} + ++ (void)cleanup +{ + [[self sessionForThreadLock] lock]; + + NSMutableDictionary *dict = [self sessionForThreadDict]; + for (PEPCopyableThread *thread in dict.allKeys) { + [thread cancel]; + [self nullifySessionForThread:thread]; + } + [dict removeAllObjects]; + + [[self sessionForThreadLock] unlock]; +} + +#pragma mark - Life Cycle + ++ (void)initialize +{ + s_sessionForThreadLock = [NSLock new]; + s_sessionForThreadDict = [NSMutableDictionary new]; +} + +#pragma mark - Lock + ++ (NSLock *)sessionForThreadLock +{ + return s_sessionForThreadLock; +} + ++ (NSMutableDictionary *)sessionForThreadDict +{ + return s_sessionForThreadDict; +} + +#pragma mark - + ++ (void)nullifySesssionOfFinishedThreads +{ + NSMutableDictionary *dict = [self sessionForThreadDict]; + for (PEPCopyableThread *thread in dict.allKeys) { + if (thread.isFinished) { + [self nullifySessionForThread:thread]; + } + } +} + ++ (void)nullifySessionForThread:(PEPCopyableThread *)thread +{ + NSMutableDictionary *dict = [self sessionForThreadDict]; + PEPSession *session = dict[thread]; + [self performSelector:@selector(nullifySession:) + onThread:thread.thread + withObject:session + waitUntilDone:NO]; + dict[thread] = nil; +} + ++ (void)nullifySession:(PEPSession *)session +{ + session = nil; +} + +@end