diff --git a/native/ios/Comm.xcodeproj/project.pbxproj b/native/ios/Comm.xcodeproj/project.pbxproj --- a/native/ios/Comm.xcodeproj/project.pbxproj +++ b/native/ios/Comm.xcodeproj/project.pbxproj @@ -46,6 +46,8 @@ B7BEE749279B3FB6009CCA35 /* GRPCStreamHostObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B7BEE744279B3E20009CCA35 /* GRPCStreamHostObject.cpp */; }; CB1648AD27CFBBBB00394D9D /* ClientGetReadReactor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2DDA00CA889DFF0ECB7E338D /* ClientGetReadReactor.cpp */; }; CB1648AF27CFBE6A00394D9D /* CryptoModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 71BF5B7B26BBDA6100EDE27D /* CryptoModule.cpp */; }; + CB38B48228771C7A00171182 /* NonBlockingLock.mm in Sources */ = {isa = PBXBuildFile; fileRef = CB38B47B287718A200171182 /* NonBlockingLock.mm */; }; + CB38B48328771C8300171182 /* NonBlockingLock.mm in Sources */ = {isa = PBXBuildFile; fileRef = CB38B47B287718A200171182 /* NonBlockingLock.mm */; }; CB38F2B1286C6C870010535C /* MessageOperationsUtilities.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CB38F2AF286C6C870010535C /* MessageOperationsUtilities.cpp */; }; CB38F2C0286C6CDF0010535C /* MessageOperationsUtilities.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CB38F2AF286C6C870010535C /* MessageOperationsUtilities.cpp */; }; CB3C621127CE4A320054F24C /* Logger.mm in Sources */ = {isa = PBXBuildFile; fileRef = 71CA4A63262DA8E500835C89 /* Logger.mm */; }; @@ -189,6 +191,7 @@ CB1648B027CFD07E00394D9D /* CommRelease.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = CommRelease.entitlements; path = Comm/CommRelease.entitlements; sourceTree = ""; }; CB30C12327D0ACF700FBE8DE /* NotificationService.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = NotificationService.entitlements; sourceTree = ""; }; CB38B4792877179A00171182 /* NonBlockingLock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NonBlockingLock.h; path = Comm/TemporaryMessageStorage/NonBlockingLock.h; sourceTree = ""; }; + CB38B47B287718A200171182 /* NonBlockingLock.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; name = NonBlockingLock.mm; path = Comm/TemporaryMessageStorage/NonBlockingLock.mm; sourceTree = ""; }; CB38F2AE286C6C870010535C /* MessageSpecs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MessageSpecs.h; path = PersistentStorageUtilities/MessageOperationsUtilities/MessageSpecs.h; sourceTree = ""; }; CB38F2AF286C6C870010535C /* MessageOperationsUtilities.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MessageOperationsUtilities.cpp; path = PersistentStorageUtilities/MessageOperationsUtilities/MessageOperationsUtilities.cpp; sourceTree = ""; }; CB38F2B0286C6C870010535C /* MessageOperationsUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MessageOperationsUtilities.h; path = PersistentStorageUtilities/MessageOperationsUtilities/MessageOperationsUtilities.h; sourceTree = ""; }; @@ -519,6 +522,7 @@ CB38B4782877177B00171182 /* TemporaryMessageStorage */ = { isa = PBXGroup; children = ( + CB38B47B287718A200171182 /* NonBlockingLock.mm */, CB38B4792877179A00171182 /* NonBlockingLock.h */, ); name = TemporaryMessageStorage; @@ -918,6 +922,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + CB38B48228771C7A00171182 /* NonBlockingLock.mm in Sources */, 71009A7826FDCA67002C8453 /* tunnelbroker.grpc.pb.cc in Sources */, B7BEE749279B3FB6009CCA35 /* GRPCStreamHostObject.cpp in Sources */, 718DE99E2653D41C00365824 /* WorkerThread.cpp in Sources */, @@ -957,6 +962,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + CB38B48328771C8300171182 /* NonBlockingLock.mm in Sources */, CB38F2C0286C6CDF0010535C /* MessageOperationsUtilities.cpp in Sources */, CB1648AF27CFBE6A00394D9D /* CryptoModule.cpp in Sources */, CB1648AD27CFBBBB00394D9D /* ClientGetReadReactor.cpp in Sources */, diff --git a/native/ios/Comm/TemporaryMessageStorage/NonBlockingLock.mm b/native/ios/Comm/TemporaryMessageStorage/NonBlockingLock.mm new file mode 100644 --- /dev/null +++ b/native/ios/Comm/TemporaryMessageStorage/NonBlockingLock.mm @@ -0,0 +1,78 @@ +#import "NonBlockingLock.h" +#import + +@implementation NonBlockingLock +- (instancetype)initWithName:(NSString *)lockName { + self = [super init]; + if (self) { + _lockName = [lockName cStringUsingEncoding:NSUTF8StringEncoding]; + _lockHandle = nil; + } + return self; +} + +- (BOOL)tryAcquireLock:(NSError **)err { + if (_lockHandle) { + *err = [NSError errorWithDomain:@"app.comm" + code:EBUSY + userInfo:@{ + NSLocalizedDescriptionKey : + @"Attempt to acquire already held lock." + }]; + return NO; + } + sem_t *lock = sem_open(self.lockName, O_CREAT, 0644, 1); + if (lock == SEM_FAILED) { + *err = [NSError errorWithDomain:@"app.comm" + code:errno + userInfo:@{ + NSLocalizedDescriptionKey : [NSString + stringWithCString:strerror(errno) + encoding:NSUTF8StringEncoding] + }]; + sem_close(lock); + return NO; + } + if (sem_trywait(lock)) { + *err = [NSError errorWithDomain:@"app.comm" + code:errno + userInfo:@{ + NSLocalizedDescriptionKey : [NSString + stringWithCString:strerror(errno) + encoding:NSUTF8StringEncoding] + }]; + sem_close(lock); + return NO; + } + _lockHandle = lock; + return YES; +} + +- (void)releaseLock:(NSError **)err { + if (!self.lockHandle) { + *err = + [NSError errorWithDomain:@"app.comm" + code:ENODATA + userInfo:@{ + NSLocalizedDescriptionKey : + @"Attempt to release lock that was not acquired." + }]; + return; + } + sem_post(_lockHandle); + sem_close(_lockHandle); + _lockHandle = nil; +} + +- (void)destroyLock:(NSError **)err { + if (sem_unlink(_lockName)) { + *err = [NSError errorWithDomain:@"app.comm" + code:errno + userInfo:@{ + NSLocalizedDescriptionKey : [NSString + stringWithCString:strerror(errno) + encoding:NSUTF8StringEncoding] + }]; + }; +} +@end