Skip to content

Ensure NSLock/NSThread don't have stored properties with CoreFoundation types #5117

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 68 additions & 25 deletions Sources/Foundation/NSLock.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,24 +50,37 @@ private typealias _ConditionVariablePointer = UnsafeMutablePointer<pthread_cond_
#endif

open class NSLock: NSObject, NSLocking, @unchecked Sendable {
internal var mutex = _MutexPointer.allocate(capacity: 1)
private let _mutex = UnsafeMutableRawPointer(_MutexPointer.allocate(capacity: 1))

private var mutex: _MutexPointer {
_mutex.assumingMemoryBound(to: _MutexPointer.Pointee.self)
}

#if os(macOS) || os(iOS) || os(Windows)
private var timeoutCond = _ConditionVariablePointer.allocate(capacity: 1)
private var timeoutMutex = _MutexPointer.allocate(capacity: 1)
private let _timeoutCond = UnsafeMutableRawPointer(_ConditionVariablePointer.allocate(capacity: 1))
private let _timeoutMutex = UnsafeMutableRawPointer(_MutexPointer.allocate(capacity: 1))

private var timeoutCond: _ConditionVariablePointer {
_timeoutCond.assumingMemoryBound(to: _ConditionVariablePointer.Pointee.self)
}

private var timeoutMutex: _MutexPointer {
_timeoutMutex.assumingMemoryBound(to: _MutexPointer.Pointee.self)
}
#endif

public override init() {
#if !SWIFT_CORELIBS_FOUNDATION_HAS_THREADS
// noop on no thread platforms
#elseif os(Windows)
InitializeSRWLock(mutex)
InitializeConditionVariable(timeoutCond)
InitializeSRWLock(timeoutMutex)
InitializeSRWLock(_mutex.assumingMemoryBound(to: _MutexPointer.Pointee.self))
InitializeConditionVariable(_timeoutCond.assumingMemoryBound(to: _ConditionVariablePointer.Pointee.self))
InitializeSRWLock(_timeoutMutex.assumingMemoryBound(to: _MutexPointer.Pointee.self))
#else
pthread_mutex_init(mutex, nil)
pthread_mutex_init(_mutex.assumingMemoryBound(to: _MutexPointer.Pointee.self), nil)
#if os(macOS) || os(iOS)
pthread_cond_init(timeoutCond, nil)
pthread_mutex_init(timeoutMutex, nil)
pthread_cond_init(_timeoutCond.assumingMemoryBound(to: _ConditionVariablePointer.Pointee.self), nil)
pthread_mutex_init(_timeoutMutex.assumingMemoryBound(to: _MutexPointer.Pointee.self), nil)
#endif
#endif
}
Expand Down Expand Up @@ -172,7 +185,16 @@ extension NSLock {
open class NSConditionLock : NSObject, NSLocking, @unchecked Sendable {
internal var _cond = NSCondition()
internal var _value: Int
internal var _thread: _swift_CFThreadRef?
internal var __thread: Any?

internal var _thread: _swift_CFThreadRef? {
get {
__thread as! _swift_CFThreadRef?
}
set {
__thread = newValue
}
}

public convenience override init() {
self.init(condition: 0)
Expand Down Expand Up @@ -272,20 +294,33 @@ open class NSConditionLock : NSObject, NSLocking, @unchecked Sendable {
#endif

open class NSRecursiveLock: NSObject, NSLocking, @unchecked Sendable {
internal var mutex = _RecursiveMutexPointer.allocate(capacity: 1)
private let _mutex = UnsafeMutableRawPointer(_MutexPointer.allocate(capacity: 1))

private var mutex: _MutexPointer {
_mutex.assumingMemoryBound(to: _MutexPointer.Pointee.self)
}

#if os(macOS) || os(iOS) || os(Windows)
private var timeoutCond = _ConditionVariablePointer.allocate(capacity: 1)
private var timeoutMutex = _MutexPointer.allocate(capacity: 1)
private let _timeoutCond = UnsafeMutableRawPointer(_ConditionVariablePointer.allocate(capacity: 1))
private let _timeoutMutex = UnsafeMutableRawPointer(_MutexPointer.allocate(capacity: 1))

private var timeoutCond: _ConditionVariablePointer {
_timeoutCond.assumingMemoryBound(to: _ConditionVariablePointer.Pointee.self)
}

private var timeoutMutex: _MutexPointer {
_timeoutMutex.assumingMemoryBound(to: _MutexPointer.Pointee.self)
}
#endif

public override init() {
super.init()
#if !SWIFT_CORELIBS_FOUNDATION_HAS_THREADS
// noop on no thread platforms
#elseif os(Windows)
InitializeCriticalSection(mutex)
InitializeConditionVariable(timeoutCond)
InitializeSRWLock(timeoutMutex)
InitializeCriticalSection(_mutex.assumingMemoryBound(to: _MutexPointer.Pointee.self))
InitializeConditionVariable(_timeoutCond.assumingMemoryBound(to: _ConditionVariablePointer.Pointee.self))
InitializeSRWLock(_timeoutMutex.assumingMemoryBound(to: _MutexPointer.Pointee.self))
#else
#if CYGWIN || os(OpenBSD)
var attrib : pthread_mutexattr_t? = nil
Expand All @@ -300,11 +335,11 @@ open class NSRecursiveLock: NSObject, NSLocking, @unchecked Sendable {
let type = Int32(PTHREAD_MUTEX_RECURSIVE)
#endif
pthread_mutexattr_settype(attrs, type)
pthread_mutex_init(mutex, attrs)
pthread_mutex_init(_mutex.assumingMemoryBound(to: _MutexPointer.Pointee.self), attrs)
}
#if os(macOS) || os(iOS)
pthread_cond_init(timeoutCond, nil)
pthread_mutex_init(timeoutMutex, nil)
pthread_cond_init(_timeoutCond.assumingMemoryBound(to: _ConditionVariablePointer.Pointee.self), nil)
pthread_mutex_init(_timeoutMutex.assumingMemoryBound(to: _MutexPointer.Pointee.self), nil)
#endif
#endif
}
Expand Down Expand Up @@ -398,18 +433,26 @@ open class NSRecursiveLock: NSObject, NSLocking, @unchecked Sendable {
}

open class NSCondition: NSObject, NSLocking, @unchecked Sendable {
internal var mutex = _MutexPointer.allocate(capacity: 1)
internal var cond = _ConditionVariablePointer.allocate(capacity: 1)
private let _mutex = UnsafeMutableRawPointer(_MutexPointer.allocate(capacity: 1))
private let _cond = UnsafeMutableRawPointer(_ConditionVariablePointer.allocate(capacity: 1))

private var mutex: _MutexPointer {
_mutex.assumingMemoryBound(to: _MutexPointer.Pointee.self)
}

private var cond: _ConditionVariablePointer {
_cond.assumingMemoryBound(to: _ConditionVariablePointer.Pointee.self)
}

public override init() {
#if !SWIFT_CORELIBS_FOUNDATION_HAS_THREADS
// noop on no thread platforms
#elseif os(Windows)
InitializeSRWLock(mutex)
InitializeConditionVariable(cond)
InitializeSRWLock(_mutex.assumingMemoryBound(to: _MutexPointer.Pointee.self))
InitializeConditionVariable(_cond.assumingMemoryBound(to: _ConditionVariablePointer.Pointee.self))
#else
pthread_mutex_init(mutex, nil)
pthread_cond_init(cond, nil)
pthread_mutex_init(_mutex.assumingMemoryBound(to: _MutexPointer.Pointee.self), nil)
pthread_cond_init(_cond.assumingMemoryBound(to: _ConditionVariablePointer.Pointee.self), nil)
#endif
}

Expand Down
47 changes: 40 additions & 7 deletions Sources/Foundation/Thread.swift
Original file line number Diff line number Diff line change
Expand Up @@ -210,24 +210,51 @@ open class Thread : NSObject {
}

internal var _main: () -> Void = {}
private var _thread: _swift_CFThreadRef? = nil
private var __thread: Any? = nil

private var _thread: _swift_CFThreadRef? {
get {
__thread as! _swift_CFThreadRef?
}
set {
__thread = newValue
}
}

#if os(Windows) && !CYGWIN
private class NonexportedAttrStorage {
var value = _CFThreadAttributes(dwSizeOfAttributes: DWORD(MemoryLayout<_CFThreadAttributes>.size),
var value: Any = _CFThreadAttributes(dwSizeOfAttributes: DWORD(MemoryLayout<_CFThreadAttributes>.size),
dwThreadStackReservation: 0)
}

private let _attrStorage = NonexportedAttrStorage()

internal final var _attr: _CFThreadAttributes {
get { _attrStorage.value }
get { _attrStorage.value as! _CFThreadAttributes }
set { _attrStorage.value = newValue }
}
#elseif CYGWIN || os(OpenBSD)
internal var _attr : pthread_attr_t? = nil
internal var __attr : Any? = nil

internal var _attr: pthread_attr_t? {
get {
__attr as! pthread_attr_t?
}
set {
__attr = newValue
}
}
#else
internal var _attr = pthread_attr_t()
internal var __attr : Any = pthread_attr_t()

internal var _attr: pthread_attr_t {
get {
__attr as! pthread_attr_t
}
set {
__attr = newValue
}
}
#endif
internal var _status = _NSThreadStatus.initialized
internal var _cancelled = false
Expand All @@ -239,16 +266,22 @@ open class Thread : NSObject {

internal init(thread: _swift_CFThreadRef) {
// Note: even on Darwin this is a non-optional _CFThreadRef; this is only used for valid threads, which are never null pointers.
_thread = thread
__thread = thread
}

public override init() {
#if !os(Windows)
let _ = withUnsafeMutablePointer(to: &_attr) { attr in
#if os(OpenBSD)
var attr: pthread_attr_t? = nil
#else
var attr = pthread_attr_t()
#endif
let _ = withUnsafeMutablePointer(to: &attr) { attr in
pthread_attr_init(attr)
pthread_attr_setscope(attr, Int32(PTHREAD_SCOPE_SYSTEM))
pthread_attr_setdetachstate(attr, Int32(PTHREAD_CREATE_DETACHED))
}
__attr = attr
#endif
}

Expand Down