File tree Expand file tree Collapse file tree 2 files changed +48
-3
lines changed Expand file tree Collapse file tree 2 files changed +48
-3
lines changed Original file line number Diff line number Diff line change @@ -41,15 +41,27 @@ public class ReadWriteLock {
41
41
pthread_rwlock_init ( & lock, nil )
42
42
}
43
43
44
+ func readLock( ) {
45
+ pthread_rwlock_rdlock ( & lock)
46
+ }
47
+
48
+ func writeLock( ) {
49
+ pthread_rwlock_wrlock ( & lock)
50
+ }
51
+
52
+ func unlock( ) {
53
+ pthread_rwlock_unlock ( & lock)
54
+ }
55
+
44
56
/// Execute the given block while holding the lock.
45
57
public func withLock< T> ( type lockType: LockType = . exclusive, _ body: ( ) throws -> T ) rethrows -> T {
46
58
switch lockType {
47
59
case . shared:
48
- pthread_rwlock_rdlock ( & lock )
60
+ readLock ( )
49
61
case . exclusive:
50
- pthread_rwlock_wrlock ( & lock )
62
+ writeLock ( )
51
63
}
52
- defer { pthread_rwlock_unlock ( & lock ) }
64
+ defer { unlock ( ) }
53
65
return try body ( )
54
66
}
55
67
Original file line number Diff line number Diff line change @@ -48,4 +48,37 @@ class LockTests: XCTestCase {
48
48
}
49
49
}
50
50
}
51
+
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
+
51
84
}
You can’t perform that action at this time.
0 commit comments