Skip to content

Commit 721eb5a

Browse files
committed
removed occurrences of pthread_rwlock and NSMapTable since they are not available on windows
1 parent c44e43a commit 721eb5a

File tree

4 files changed

+40
-80
lines changed

4 files changed

+40
-80
lines changed

Sources/TSCBasic/FileSystem.swift

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
import TSCLibc
1212
import Foundation
13+
import Dispatch
1314

1415
public enum FileSystemError: Swift.Error {
1516
/// Access to the path is denied.
@@ -515,7 +516,9 @@ public class InMemoryFileSystem: FileSystem {
515516
/// The root filesytem.
516517
private var root: Node
517518
/// A map that keeps weak references to all locked files.
518-
private let lockMap = NSMapTable<NSString, ReadWriteLock>(keyOptions: .copyIn, valueOptions: .weakMemory)
519+
private var lockFiles = WeakDictionary<AbsolutePath, DispatchQueue>()
520+
/// Used to access lockFiles in a thread safe manner.
521+
private let lockFilesLock = Lock()
519522

520523
public init() {
521524
root = Node(.directory(DirectoryContents()))
@@ -776,19 +779,18 @@ public class InMemoryFileSystem: FileSystem {
776779
}
777780

778781
public func withLock<T>(on path: AbsolutePath, type: LockType = .exclusive, _ body: () throws -> T) throws -> T {
779-
let lock = Lock()
780-
var fileLock: ReadWriteLock
782+
var fileQueue: DispatchQueue
781783

782-
lock.lock()
783-
if let lock = lockMap.object(forKey: path.pathString as NSString) {
784-
fileLock = lock
784+
lockFilesLock.lock()
785+
if let queue = lockFiles[path] {
786+
fileQueue = queue
785787
} else {
786-
fileLock = ReadWriteLock()
787-
lockMap.setObject(fileLock, forKey: path.pathString as NSString)
788+
fileQueue = DispatchQueue(label: "foo", attributes: .concurrent)
789+
lockFiles[path] = fileQueue
788790
}
789-
lock.unlock()
791+
lockFilesLock.unlock()
790792

791-
return try fileLock.withLock(type: type, body)
793+
return try fileQueue.sync(flags: type == .exclusive ? .barrier : .init() , execute: body)
792794
}
793795
}
794796

Sources/TSCBasic/Lock.swift

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -40,44 +40,6 @@ public struct Lock {
4040
}
4141
}
4242

43-
/// A lock that allows multiple readers but only one write at the same time.
44-
public class ReadWriteLock {
45-
private var lock = pthread_rwlock_t()
46-
47-
/// Create a new lock.
48-
public init() {
49-
pthread_rwlock_init(&lock, nil)
50-
}
51-
52-
func readLock() {
53-
pthread_rwlock_rdlock(&lock)
54-
}
55-
56-
func writeLock() {
57-
pthread_rwlock_wrlock(&lock)
58-
}
59-
60-
func unlock() {
61-
pthread_rwlock_unlock(&lock)
62-
}
63-
64-
/// Execute the given block while holding the lock.
65-
public func withLock<T>(type lockType: LockType = .exclusive, _ body: () throws -> T) rethrows -> T {
66-
switch lockType {
67-
case .shared:
68-
readLock()
69-
case .exclusive:
70-
writeLock()
71-
}
72-
defer { unlock() }
73-
return try body()
74-
}
75-
76-
deinit {
77-
pthread_rwlock_destroy(&lock)
78-
}
79-
}
80-
8143
enum ProcessLockError: Swift.Error {
8244
case unableToAquireLock(errno: Int32)
8345
}

Sources/TSCBasic/WeakDictionary.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
This source file is part of the Swift.org open source project
3+
4+
Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
5+
Licensed under Apache License v2.0 with Runtime Library Exception
6+
7+
See http://swift.org/LICENSE.txt for license information
8+
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
9+
*/
10+
11+
/// A dictionary that only keeps weak references to its values.
12+
struct WeakDictionary<Key: Hashable, Value: AnyObject> {
13+
14+
private struct WeakReference<Value: AnyObject> {
15+
weak var reference: Value?
16+
17+
init(_ value: Value?) {
18+
self.reference = value
19+
}
20+
}
21+
22+
private var storage = Dictionary<Key, WeakReference<Value>>()
23+
24+
subscript(key: Key) -> Value? {
25+
get { storage[key]?.reference }
26+
set(newValue) { storage[key] = WeakReference(newValue) }
27+
}
28+
}

Tests/TSCBasicTests/LockTests.swift

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -49,38 +49,6 @@ class LockTests: XCTestCase {
4949
}
5050
}
5151

52-
func testReadWriteLock() throws {
53-
var a = 0
54-
var b = 0
55-
56-
let lock = ReadWriteLock()
57-
58-
let writerThreads = (0..<100).map { _ in
59-
return Thread {
60-
lock.withLock(type: .exclusive) {
61-
a+=1
62-
sched_yield()
63-
b+=1
64-
}
65-
}
66-
}
67-
68-
let readerThreads = (0..<20).map { _ in
69-
return Thread {
70-
lock.withLock(type: .shared) {
71-
XCTAssertEqual(a,b)
72-
sched_yield()
73-
XCTAssertEqual(a,b)
74-
}
75-
}
76-
}
77-
78-
writerThreads.forEach { $0.start() }
79-
readerThreads.forEach { $0.start() }
80-
writerThreads.forEach { $0.join() }
81-
readerThreads.forEach { $0.join() }
82-
}
83-
8452
func testReadWriteFileLock() throws {
8553
try withTemporaryDirectory { tempDir in
8654
let fileA = tempDir.appending(component: "fileA")

0 commit comments

Comments
 (0)