Skip to content

Commit 2ed9bde

Browse files
Seweryn Plażuksewerynplazuk
Seweryn Plażuk
authored andcommitted
Add thread safety to Clock
Signed-off-by: Seweryn Plażuk <[email protected]>
1 parent a46542c commit 2ed9bde

File tree

3 files changed

+59
-3
lines changed

3 files changed

+59
-3
lines changed

Kronos.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
930B39DD2051E6D300360BA2 /* TimeStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 930B39DC2051E6D300360BA2 /* TimeStorage.swift */; };
2424
930B39E02051F26500360BA2 /* TimeStorageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 930B39DE2051F25300360BA2 /* TimeStorageTests.swift */; };
2525
C201748E1BD5509D00E4FE18 /* Kronos.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C20174831BD5509D00E4FE18 /* Kronos.framework */; };
26+
E5481CD32B6BF3010072186E /* UnfairLock.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5481CD22B6BF3010072186E /* UnfairLock.swift */; };
2627
/* End PBXBuildFile section */
2728

2829
/* Begin PBXContainerItemProxy section */
@@ -57,6 +58,7 @@
5758
C2C036D41C2B180D003FB853 /* UniversalFramework_Base.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = UniversalFramework_Base.xcconfig; sourceTree = "<group>"; };
5859
C2C036D51C2B180D003FB853 /* UniversalFramework_Framework.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = UniversalFramework_Framework.xcconfig; sourceTree = "<group>"; };
5960
C2C036D61C2B180D003FB853 /* UniversalFramework_Test.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = UniversalFramework_Test.xcconfig; sourceTree = "<group>"; };
61+
E5481CD22B6BF3010072186E /* UnfairLock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnfairLock.swift; sourceTree = "<group>"; };
6062
/* End PBXFileReference section */
6163

6264
/* Begin PBXFrameworksBuildPhase section */
@@ -122,6 +124,7 @@
122124
26447D7A1D6E54D400159BEE /* NTPProtocol.swift */,
123125
26447D7B1D6E54D400159BEE /* TimeFreeze.swift */,
124126
930B39DC2051E6D300360BA2 /* TimeStorage.swift */,
127+
E5481CD22B6BF3010072186E /* UnfairLock.swift */,
125128
);
126129
path = Sources;
127130
sourceTree = "<group>";
@@ -230,6 +233,7 @@
230233
26447D7C1D6E54D400159BEE /* Clock.swift in Sources */,
231234
26447D7D1D6E54D400159BEE /* DNSResolver.swift in Sources */,
232235
26447D7E1D6E54D400159BEE /* InternetAddress.swift in Sources */,
236+
E5481CD32B6BF3010072186E /* UnfairLock.swift in Sources */,
233237
26447D811D6E54D400159BEE /* NTPClient.swift in Sources */,
234238
26447D7F1D6E54D400159BEE /* Data+Bytes.swift in Sources */,
235239
26447D841D6E54D400159BEE /* TimeFreeze.swift in Sources */,

Sources/Clock.swift

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,38 @@ public typealias AnnotatedTime = (
2525
/// print(Clock.now)
2626
/// ```
2727
public struct Clock {
28+
private static var unfairLock = UnfairLock()
29+
private static var _stableTime: TimeFreeze?
30+
private static var _storage = TimeStorage(storagePolicy: .standard)
31+
2832
private static var stableTime: TimeFreeze? {
29-
didSet {
30-
self.storage.stableTime = self.stableTime
33+
get {
34+
self.unfairLock.synchronized {
35+
return self._stableTime
36+
}
37+
}
38+
set {
39+
self.unfairLock.synchronized {
40+
self._stableTime = newValue
41+
self._storage.stableTime = newValue
42+
}
3143
}
3244
}
3345

3446
/// Determines where the most current stable time is stored. Use TimeStoragePolicy.appGroup to share
3547
/// between your app and an extension.
36-
public static var storage = TimeStorage(storagePolicy: .standard)
48+
public static var storage: TimeStorage {
49+
get {
50+
self.unfairLock.synchronized {
51+
return self._storage
52+
}
53+
}
54+
set {
55+
self.unfairLock.synchronized {
56+
self._storage = newValue
57+
}
58+
}
59+
}
3760

3861
/// The most accurate timestamp that we have so far (nil if no synchronization was done yet)
3962
public static var timestamp: TimeInterval? {

Sources/UnfairLock.swift

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import os.lock
2+
3+
final class UnfairLock {
4+
private let lockPointer: os_unfair_lock_t
5+
6+
init() {
7+
self.lockPointer = .allocate(capacity: 1)
8+
self.lockPointer.initialize(to: os_unfair_lock())
9+
}
10+
11+
deinit {
12+
self.lockPointer.deinitialize(count: 1)
13+
self.lockPointer.deallocate()
14+
}
15+
16+
func lock() {
17+
os_unfair_lock_lock(self.lockPointer)
18+
}
19+
20+
func unlock() {
21+
os_unfair_lock_unlock(self.lockPointer)
22+
}
23+
24+
func synchronized<T>(_ block: () -> T) -> T {
25+
self.lock()
26+
defer { self.unlock() }
27+
return block()
28+
}
29+
}

0 commit comments

Comments
 (0)