From 8df105aad45ca4a230dd011f4e1d78ccad28d03e Mon Sep 17 00:00:00 2001 From: Joe Heck Date: Mon, 10 May 2021 11:14:04 -0700 Subject: [PATCH] replacing os_unfair_lock with NSLock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit learned that os_unfair_lock with & was quite unsafe when used within swift. Apparently in swift, &foo in Swift means "make a copy of foo and pass it inout to a function, then overwrite its value with whatever the function did to it when that function returns." And if you're using it within a struct, it's apparently even more dangerous. because the address of self can change from call to call — self might not even have an address, it might be contained in registers only. Using NSlock will be a smidge less performant, but notably more safe. --- Articles/Sources/Articles/DatabaseID.swift | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Articles/Sources/Articles/DatabaseID.swift b/Articles/Sources/Articles/DatabaseID.swift index 86b6dc5de..32918a7ee 100644 --- a/Articles/Sources/Articles/DatabaseID.swift +++ b/Articles/Sources/Articles/DatabaseID.swift @@ -14,13 +14,12 @@ import RSCore // * Collisions aren’t going to happen with feed data private var databaseIDCache = [String: String]() -private var databaseIDCacheLock = os_unfair_lock_s() - +private var databaseIDCacheLock = NSLock() public func databaseIDWithString(_ s: String) -> String { - os_unfair_lock_lock(&databaseIDCacheLock) - defer { - os_unfair_lock_unlock(&databaseIDCacheLock) - } + databaseIdCacheLock.lock() + defer { + databaseIdCacheLock.unlock() + } if let identifier = databaseIDCache[s] { return identifier