源码为苹果开源Swift版本的Foundation框架下NSLock.swift 文件
1. NSLock
**open** **class** NSLock: NSObject, NSLocking {
**internal** **var** mutex = _MutexPointer.allocate(capacity: 1)
#if os(macOS) || os(iOS) || os(Windows)
**private** **var** timeoutCond = _ConditionVariablePointer.allocate(capacity: 1)
**private** **var** timeoutMutex = _MutexPointer.allocate(capacity: 1)
#endif
\
**public** **override** **init**() {
#if os(Windows)
InitializeSRWLock(mutex)
InitializeConditionVariable(timeoutCond)
InitializeSRWLock(timeoutMutex)
#else
pthread_mutex_init(mutex, **nil**)
#if os(macOS) || os(iOS)
pthread_cond_init(timeoutCond, **nil**)
pthread_mutex_init(timeoutMutex, **nil**)
#endif
#endif
}
**deinit** {
#if os(Windows)
// SRWLocks do not need to be explicitly destroyed
#else
pthread_mutex_destroy(mutex)
#endif
mutex.deinitialize(count: 1)
mutex.deallocate()
#if os(macOS) || os(iOS) || os(Windows)
deallocateTimedLockData(cond: timeoutCond, mutex: timeoutMutex)
#endif
}
**open** **func** lock() {
#if os(Windows)
AcquireSRWLockExclusive(mutex)
#else
pthread_mutex_lock(mutex)
#endif
}
\
**open** **func** unlock() {
#if os(Windows)
ReleaseSRWLockExclusive(mutex)
AcquireSRWLockExclusive(timeoutMutex)
WakeAllConditionVariable(timeoutCond)
ReleaseSRWLockExclusive(timeoutMutex)
#else
pthread_mutex_unlock(mutex)
#if os(macOS) || os(iOS)
// Wakeup any threads waiting in lock(before:)
pthread_mutex_lock(timeoutMutex)
pthread_cond_broadcast(timeoutCond)
pthread_mutex_unlock(timeoutMutex)
#endif
#endif
}
\
**open** **func** `try`() -> Bool {
#if os(Windows)
**return** TryAcquireSRWLockExclusive(mutex) != 0
#else
**return** pthread_mutex_trylock(mutex) == 0
#endif
}
**open** **func** lock(before limit: Date) -> Bool {
#if os(Windows)
**if** TryAcquireSRWLockExclusive(mutex) != 0 {
**return** **true**
}
#else
**if** pthread_mutex_trylock(mutex) == 0 {
**return** **true**
}
#endif
\
#if os(macOS) || os(iOS) || os(Windows)
**return** timedLock(mutex: mutex, endTime: limit, using: timeoutCond, with: timeoutMutex)
#else
**guard** **var** endTime = timeSpecFrom(date: limit) **else** {
**return** **false**
}
**return** pthread_mutex_timedlock(mutex, &endTime) == 0
#endif
}
\
**open** **var** name: String?
}
**extension** NSLock {
**internal** **func** synchronized<T>(_ closure: () -> T) -> T {
**self**.lock()
**defer** { **self**.unlock() }
**return** closure()
}
}
2. NSConditionLock
**open** **class** NSConditionLock : NSObject, NSLocking {
**internal** **var** _cond = NSCondition()
**internal** **var** _value: Int
**internal** **var** _thread: _swift_CFThreadRef?
**public** **convenience** **override** **init**() {
**self**.init(condition: 0)
}
**public** **init**(condition: Int) {
_value = condition
}
\
**open** **func** lock() {
**let** _ = lock(before: Date.distantFuture)
}
\
**open** **func** unlock() {
_cond.lock()
#if os(Windows)
_thread = INVALID_HANDLE_VALUE
#else
_thread = **nil**
#endif
_cond.broadcast()
_cond.unlock()
}
**open** **var** condition: Int {
**return** _value
}
\
**open** **func** lock(whenCondition condition: Int) {
**let** _ = lock(whenCondition: condition, before: Date.distantFuture)
}
\
**open** **func** `try`() -> Bool {
**return** lock(before: Date.distantPast)
}
**open** **func** tryLock(whenCondition condition: Int) -> Bool {
**return** lock(whenCondition: condition, before: Date.distantPast)
}
\
**open** **func** unlock(withCondition condition: Int) {
_cond.lock()
#if os(Windows)
_thread = INVALID_HANDLE_VALUE
#else
_thread = **nil**
#endif
_value = condition
_cond.broadcast()
_cond.unlock()
}
\
**open** **func** lock(before limit: Date) -> Bool {
_cond.lock()
**while** _thread != **nil** {
**if** !_cond.wait(until: limit) {
_cond.unlock()
**return** **false**
}
}
#if os(Windows)
_thread = GetCurrentThread()
#else
_thread = pthread_self()
#endif
_cond.unlock()
**return** **true**
}
**open** **func** lock(whenCondition condition: Int, before limit: Date) -> Bool {
_cond.lock()
**while** _thread != **nil** || _value != condition {
**if** !_cond.wait(until: limit) {
_cond.unlock()
**return** **false**
}
}
#if os(Windows)
_thread = GetCurrentThread()
#else
_thread = pthread_self()
#endif
_cond.unlock()
**return** **true**
}
**open** **var** name: String?
}
3. NSRecursiveLock
**open** **class** NSRecursiveLock: NSObject, NSLocking {
**internal** **var** mutex = _RecursiveMutexPointer.allocate(capacity: 1)
#if os(macOS) || os(iOS) || os(Windows)
**private** **var** timeoutCond = _ConditionVariablePointer.allocate(capacity: 1)
**private** **var** timeoutMutex = _MutexPointer.allocate(capacity: 1)
#endif
\
**public** **override** **init**() {
**super**.init()
#if os(Windows)
InitializeCriticalSection(mutex)
InitializeConditionVariable(timeoutCond)
InitializeSRWLock(timeoutMutex)
#else
#if CYGWIN
**var** attrib : pthread_mutexattr_t? = **nil**
#else
**var** attrib = pthread_mutexattr_t()
#endif
withUnsafeMutablePointer(to: &attrib) { attrs **in**
pthread_mutexattr_init(attrs)
pthread_mutexattr_settype(attrs, Int32(PTHREAD_MUTEX_RECURSIVE))
pthread_mutex_init(mutex, attrs)
}
#if os(macOS) || os(iOS)
pthread_cond_init(timeoutCond, **nil**)
pthread_mutex_init(timeoutMutex, **nil**)
#endif
#endif
}
**deinit** {
#if os(Windows)
DeleteCriticalSection(mutex)
#else
pthread_mutex_destroy(mutex)
#endif
mutex.deinitialize(count: 1)
mutex.deallocate()
#if os(macOS) || os(iOS) || os(Windows)
deallocateTimedLockData(cond: timeoutCond, mutex: timeoutMutex)
#endif
}
**open** **func** lock() {
#if os(Windows)
EnterCriticalSection(mutex)
#else
pthread_mutex_lock(mutex)
#endif
}
**open** **func** unlock() {
#if os(Windows)
LeaveCriticalSection(mutex)
AcquireSRWLockExclusive(timeoutMutex)
WakeAllConditionVariable(timeoutCond)
ReleaseSRWLockExclusive(timeoutMutex)
#else
pthread_mutex_unlock(mutex)
#if os(macOS) || os(iOS)
// Wakeup any threads waiting in lock(before:)
pthread_mutex_lock(timeoutMutex)
pthread_cond_broadcast(timeoutCond)
pthread_mutex_unlock(timeoutMutex)
#endif
#endif
}
**open** **func** `try`() -> Bool {
#if os(Windows)
**return** TryEnterCriticalSection(mutex)
#else
**return** pthread_mutex_trylock(mutex) == 0
#endif
}
**open** **func** lock(before limit: Date) -> Bool {
#if os(Windows)
**if** TryEnterCriticalSection(mutex) {
**return** **true**
}
#else
**if** pthread_mutex_trylock(mutex) == 0 {
**return** **true**
}
#endif
\
#if os(macOS) || os(iOS) || os(Windows)
**return** timedLock(mutex: mutex, endTime: limit, using: timeoutCond, with: timeoutMutex)
#else
**guard** **var** endTime = timeSpecFrom(date: limit) **else** {
**return** **false**
}
**return** pthread_mutex_timedlock(mutex, &endTime) == 0
#endif
}
\
**open** **var** name: String?
}
4. NSCondition
**open** **class** NSCondition: NSObject, NSLocking {
**internal** **var** mutex = _MutexPointer.allocate(capacity: 1)
**internal** **var** cond = _ConditionVariablePointer.allocate(capacity: 1)
\
**public** **override** **init**() {
#if os(Windows)
InitializeSRWLock(mutex)
InitializeConditionVariable(cond)
#else
pthread_mutex_init(mutex, **nil**)
pthread_cond_init(cond, **nil**)
#endif
}
**deinit** {
#if os(Windows)
// SRWLock do not need to be explicitly destroyed
#else
pthread_mutex_destroy(mutex)
pthread_cond_destroy(cond)
#endif
mutex.deinitialize(count: 1)
cond.deinitialize(count: 1)
mutex.deallocate()
cond.deallocate()
}
**open** **func** lock() {
#if os(Windows)
AcquireSRWLockExclusive(mutex)
#else
pthread_mutex_lock(mutex)
#endif
}
**open** **func** unlock() {
#if os(Windows)
ReleaseSRWLockExclusive(mutex)
#else
pthread_mutex_unlock(mutex)
#endif
}
**open** **func** wait() {
#if os(Windows)
SleepConditionVariableSRW(cond, mutex, WinSDK.INFINITE, 0)
#else
pthread_cond_wait(cond, mutex)
#endif
}
\
**open** **func** wait(until limit: Date) -> Bool {
#if os(Windows)
**return** SleepConditionVariableSRW(cond, mutex, timeoutFrom(date: limit), 0)
#else
**guard** **var** timeout = timeSpecFrom(date: limit) **else** {
**return** **false**
}
**return** pthread_cond_timedwait(cond, mutex, &timeout) == 0
#endif
}
**open** **func** signal() {
#if os(Windows)
WakeConditionVariable(cond)
#else
pthread_cond_signal(cond)
#endif
}
**open** **func** broadcast() {
#if os(Windows)
WakeAllConditionVariable(cond)
#else
// 汇编分析 - 猜 (多看多玩)
pthread_cond_broadcast(cond) // wait signal
#endif
}
**open** **var** name: String?
}