Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ protocol DiagnosticCaching {
/// `com.launchdarkly.DiagnosticCache.diagnosticData`, forming keys of the form
/// `com.launchdarkly.DiagnosticCache.diagnosticData.<mobileKey>`.
final class DiagnosticCache: DiagnosticCaching {
private static let cacheQueueLabel = "com.launchdarkly.DiagnosticCache.cacheQueue"

private let sdkKey: String
private var cacheQueue = DispatchQueue(label: cacheQueueLabel)
/// A lock rather than a queue because a full event store counts every refused evaluation here, on the thread that
/// evaluated, and a `DispatchQueue.sync` costs enough at that rate to be visible.
private let lock = UnfairLock()

private var instanceId: String
private var dataSinceDate: Int64
Expand All @@ -37,13 +37,13 @@ final class DiagnosticCache: DiagnosticCaching {
}

func getDiagnosticId() -> DiagnosticId {
cacheQueue.sync {
lock.withLock {
DiagnosticId(diagnosticId: instanceId, sdkKey: sdkKey)
}
}

func getCurrentStatsAndReset() -> DiagnosticStats {
cacheQueue.sync {
lock.withLock {
let now = Date().millisSince1970
let stats = DiagnosticStats(id: DiagnosticId(diagnosticId: instanceId, sdkKey: sdkKey),
creationDate: now,
Expand All @@ -60,19 +60,19 @@ final class DiagnosticCache: DiagnosticCaching {
}

func incrementDroppedEventCount() {
cacheQueue.sync {
lock.withLock {
droppedEvents += 1
}
}

func recordEventsInLastBatch(eventsInLastBatch: Int) {
cacheQueue.sync {
lock.withLock {
self.eventsInLastBatch = eventsInLastBatch
}
}

func addStreamInit(streamInit: DiagnosticStreamInit) {
cacheQueue.sync {
lock.withLock {
streamInits.append(streamInit)
}
}
Expand Down
16 changes: 16 additions & 0 deletions LaunchDarkly/LaunchDarkly/UnfairLock.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,24 @@ final class UnfairLock {
func unlock() {
os_unfair_lock_unlock(unfairLock)
}

/// Runs `body` holding the lock. Inlined, so it costs the same as calling `lock()` and `unlock()` around it.
@inline(__always)
func withLock<T>(_ body: () throws -> T) rethrows -> T {
lock()
defer { unlock() }
return try body()
}
}
#else
/// `os_unfair_lock` is Darwin only, so elsewhere this is Foundation's mutex.
typealias UnfairLock = NSLock

extension NSLock {
func withLock<T>(_ body: () throws -> T) rethrows -> T {
lock()
defer { unlock() }
return try body()
}
}
#endif
Loading