Skip to content

Commit 1731a1c

Browse files
chore: Add synchronized extension for NSLock (#3735)
Add a synchronized extension for NSLock for a convenient way to synchronize a closure call in Swift.
1 parent d0deebd commit 1731a1c

File tree

3 files changed

+84
-0
lines changed

3 files changed

+84
-0
lines changed

Sentry.xcodeproj/project.pbxproj

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@
8484
627E7589299F6FE40085504D /* SentryInternalDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 627E7588299F6FE40085504D /* SentryInternalDefines.h */; };
8585
62862B1C2B1DDBC8009B16E3 /* SentryDelayedFrame.h in Headers */ = {isa = PBXBuildFile; fileRef = 62862B1B2B1DDBC8009B16E3 /* SentryDelayedFrame.h */; };
8686
62862B1E2B1DDC35009B16E3 /* SentryDelayedFrame.m in Sources */ = {isa = PBXBuildFile; fileRef = 62862B1D2B1DDC35009B16E3 /* SentryDelayedFrame.m */; };
87+
62872B5F2BA1B7F300A4FA7D /* NSLock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62872B5E2BA1B7F300A4FA7D /* NSLock.swift */; };
88+
62872B632BA1B86100A4FA7D /* NSLockTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62872B622BA1B86100A4FA7D /* NSLockTests.swift */; };
8789
62885DA729E946B100554F38 /* TestConncurrentModifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62885DA629E946B100554F38 /* TestConncurrentModifications.swift */; };
8890
62950F1029E7FE0100A42624 /* SentryTransactionContextTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62950F0F29E7FE0100A42624 /* SentryTransactionContextTests.swift */; };
8991
629690532AD3E060000185FA /* SentryReachabilitySwiftTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 629690522AD3E060000185FA /* SentryReachabilitySwiftTests.swift */; };
@@ -978,6 +980,8 @@
978980
627E7588299F6FE40085504D /* SentryInternalDefines.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryInternalDefines.h; path = include/SentryInternalDefines.h; sourceTree = "<group>"; };
979981
62862B1B2B1DDBC8009B16E3 /* SentryDelayedFrame.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryDelayedFrame.h; path = include/SentryDelayedFrame.h; sourceTree = "<group>"; };
980982
62862B1D2B1DDC35009B16E3 /* SentryDelayedFrame.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryDelayedFrame.m; sourceTree = "<group>"; };
983+
62872B5E2BA1B7F300A4FA7D /* NSLock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSLock.swift; sourceTree = "<group>"; };
984+
62872B622BA1B86100A4FA7D /* NSLockTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSLockTests.swift; sourceTree = "<group>"; };
981985
62885DA629E946B100554F38 /* TestConncurrentModifications.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestConncurrentModifications.swift; sourceTree = "<group>"; };
982986
62950F0F29E7FE0100A42624 /* SentryTransactionContextTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryTransactionContextTests.swift; sourceTree = "<group>"; };
983987
629690522AD3E060000185FA /* SentryReachabilitySwiftTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryReachabilitySwiftTests.swift; sourceTree = "<group>"; };
@@ -1899,6 +1903,22 @@
18991903
path = Helper;
19001904
sourceTree = "<group>";
19011905
};
1906+
62872B602BA1B84400A4FA7D /* Swift */ = {
1907+
isa = PBXGroup;
1908+
children = (
1909+
62872B612BA1B84C00A4FA7D /* Extensions */,
1910+
);
1911+
path = Swift;
1912+
sourceTree = "<group>";
1913+
};
1914+
62872B612BA1B84C00A4FA7D /* Extensions */ = {
1915+
isa = PBXGroup;
1916+
children = (
1917+
62872B622BA1B86100A4FA7D /* NSLockTests.swift */,
1918+
);
1919+
path = Extensions;
1920+
sourceTree = "<group>";
1921+
};
19021922
630436001EBCB87500C4D3FA /* Networking */ = {
19031923
isa = PBXGroup;
19041924
children = (
@@ -2269,6 +2289,7 @@
22692289
63AA75931EB8AEDB00D153DE /* SentryTests */ = {
22702290
isa = PBXGroup;
22712291
children = (
2292+
62872B602BA1B84400A4FA7D /* Swift */,
22722293
7B3878E92490D90400EBDEA2 /* SentryClient+TestInit.h */,
22732294
D8BC83BA2AFCF08C00A662B7 /* SentryUIApplication+Private.h */,
22742295
84281C652A58A16500EE88F2 /* SentryProfiler+Test.h */,
@@ -3506,6 +3527,7 @@
35063527
isa = PBXGroup;
35073528
children = (
35083529
D8F016B52B962548007B9AFB /* StringExtensions.swift */,
3530+
62872B5E2BA1B7F300A4FA7D /* NSLock.swift */,
35093531
);
35103532
path = Extensions;
35113533
sourceTree = "<group>";
@@ -4233,6 +4255,7 @@
42334255
6304360B1EC0595B00C4D3FA /* NSData+SentryCompression.m in Sources */,
42344256
639889B81EDECFA800EA7442 /* SentryBreadcrumbTracker.m in Sources */,
42354257
84AF45A729A7FFA500FBB177 /* SentryProfiledTracerConcurrency.mm in Sources */,
4258+
62872B5F2BA1B7F300A4FA7D /* NSLock.swift in Sources */,
42364259
7DC8310C2398283C0043DD9A /* SentryCrashIntegration.m in Sources */,
42374260
03F84D3227DD4191008FE43F /* SentryProfiler.mm in Sources */,
42384261
635B3F391EBC6E2500A6176D /* SentryAsynchronousOperation.m in Sources */,
@@ -4525,6 +4548,7 @@
45254548
7BC6EC04255C235F0059822A /* SentryFrameTests.swift in Sources */,
45264549
0AE455AD28F584D2006680E5 /* SentryReachabilityTests.m in Sources */,
45274550
63FE720420DA66EC00CDBAE8 /* SentryCrashString_Tests.m in Sources */,
4551+
62872B632BA1B86100A4FA7D /* NSLockTests.swift in Sources */,
45284552
849AC40029E0C1FF00889C16 /* SentryFormatterTests.swift in Sources */,
45294553
7BDDE3CC2966BD4700EB9177 /* SentryMXManagerTests.swift in Sources */,
45304554
7BC6EC0C255C3DF80059822A /* SentryThreadTests.swift in Sources */,
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import Foundation
2+
3+
extension NSLock {
4+
5+
/// Executes the closure while acquiring the lock.
6+
///
7+
/// - Parameter closure: The closure to run.
8+
func synchronized(_ closure: () throws -> Void) rethrows {
9+
self.lock()
10+
defer { self.unlock() }
11+
try closure()
12+
}
13+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import Nimble
2+
@testable import Sentry
3+
import XCTest
4+
5+
final class NSLockTests: XCTestCase {
6+
7+
func testLockForIncrement() throws {
8+
let lock = NSLock()
9+
10+
var value = 0
11+
12+
testConcurrentModifications(asyncWorkItems: 10, writeLoopCount: 9, writeWork: { _ in
13+
lock.synchronized {
14+
value += 1
15+
}
16+
})
17+
18+
expect(value) == 100
19+
}
20+
21+
func testUnlockWhenThrowing() throws {
22+
let lock = NSLock()
23+
24+
let errorMessage = "It's broken"
25+
do {
26+
try lock.synchronized {
27+
throw NSLockError.runtimeError(errorMessage)
28+
}
29+
} catch NSLockError.runtimeError(let actualErrorMessage) {
30+
expect(actualErrorMessage) == errorMessage
31+
}
32+
33+
let expectation = expectation(description: "Lock should be non blocking")
34+
35+
DispatchQueue.global().async {
36+
lock.synchronized {
37+
expectation.fulfill()
38+
}
39+
}
40+
41+
wait(for: [expectation], timeout: 0.1)
42+
}
43+
44+
enum NSLockError: Error {
45+
case runtimeError(String)
46+
}
47+
}

0 commit comments

Comments
 (0)