ReadWriteLock 1.0.3

ReadWriteLock 1.0.3

Maintained by Joseph Newton.



  • By
  • Joe Newton

ReadWriteLock

Codacy Badge License MIT CocoaPods Compatible Carthage Compatible Platform Code Coverage

Swift Package Xcode Project Cocoapods Carthage

ReadWriteLock is a lightweight framework of a safe an easy implementation of a read-write lock for iOS, macOS, tvOS, and watchOS.

Installation

ReadWriteLock is available through CocoaPods, Carthage and the Swift Package Manager.

To install via CocoaPods, simply add the following line to your Podfile:

pod 'ReadWriteLock'

To install via Carthage, simply add the following line to your Cartfile:

github "SomeRandomiOSDev/ReadWriteLock"

To install via the Swift Package Manager add the following line to your Package.swift file's dependencies:

.package(url: "https://github.com/SomeRandomiOSDev/ReadWriteLock.git", from: "1.0.0")

Usage

First import ReadWriteLock at the top of your Swift file:

import ReadWriteLock

After importing simply instantiate a ReadWriteLock instance and start acquiring locks:

let lock = ReadWriteLock()
var protectedResource = ...

DispatchQueue.global(qos: .background).async {
    ...

    lock.acquireWriteLock {
        protectedResource = ...
    }
}

...

DispatchQueue.global(qos: .background).async {
    ...
    
    lock.acquireReadLock {
        process(protectedResource)
    }
}

Or you can conditionally attempt to acquire a lock. Acquiring a lock in this way will not block if the lock has already been claimed:

...

lock.attemptAcquireReadLock { isLockAcquired in
    if isLockAcquired {
        process(protectedResource)
    } else {
        // `lock` is currently locked for writing. 
    }
}

Acquiring locks uses Swift closures to scope the lifetime of the read/write lock. This prevents lingering locks when the ReadWriteLock object is deallocated and helps prevent deadlocks. Note that if you attempt to acquire a write lock from inside of the scope of an already acquired read or write lock, or acquiring a read lock from inside of the scope of an already acquired write lock, the thread will deadlock:

// All of these code blocks will deadlock

lock.acquireWriteLock {
    ...
    
    lock.acquireWriteLock {
        // deadlock
    }
}

lock.acquireReadLock {
    ...

    lock.acquireWriteLock {
        // deadlock
    }
}

lock.attemptAcquireWriteLock { isLockAcquired in
    ...

    if isLockAcquired {
        lock.acquireWriteLock {
            // deadlock
        }
    }
}

...

The benefit of read/write locks over traditional locks is that you may have (virtually) unlimited read locks, even nested read locks, without deadlocking:

lock.acquireReadLock {
    ...
    
    lock.acquireReadLock {
        // won't deadlock
    }
    
    lock.attemptAcquireReadLock { isLockAcquired in 
        // isLockAcquired is `true`
    }
}

Read/write locks are ideal for synchronizing access to properties:

struct SynchronizedValue<T> {
    private var lock = ReadWriteLock()
    private var _value: T
    
    var value: T {
        get {
            return lock.acquireReadLock { _value }
        }
        set {
            lock.acquireWriteLock { _value = newValue }
        }
    }
}

Contributing

If you have need for a specific feature or you encounter a bug, please open an issue. If you extend the functionality of ReadWriteLock yourself or you feel like fixing a bug yourself, please submit a pull request.

Author

Joe Newton, [email protected]

License

ReadWriteLock is available under the MIT license. See the LICENSE file for more info.