Merge pull request #1439 from millenomi/cfrunloop-fix-linux
diff --git a/Foundation/RunLoop.swift b/Foundation/RunLoop.swift
index ce4cf81..522664f 100644
--- a/Foundation/RunLoop.swift
+++ b/Foundation/RunLoop.swift
@@ -43,6 +43,17 @@
extension RunLoopMode {
public static let defaultRunLoopMode = RunLoopMode("kCFRunLoopDefaultMode")
public static let commonModes = RunLoopMode("kCFRunLoopCommonModes")
+
+ // Use this instead of .rawValue._cfObject; this will allow CFRunLoop to use pointer equality internally.
+ fileprivate var _cfStringUniquingKnown: CFString {
+ if self == .defaultRunLoopMode {
+ return kCFRunLoopDefaultMode
+ } else if self == .commonModes {
+ return kCFRunLoopCommonModes
+ } else {
+ return rawValue._cfObject
+ }
+ }
}
internal func _NSRunLoopNew(_ cf: CFRunLoop) -> Unmanaged<AnyObject> {
@@ -81,7 +92,7 @@
}
open func add(_ timer: Timer, forMode mode: RunLoopMode) {
- CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer._cfObject, mode.rawValue._cfObject)
+ CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer._cfObject, mode._cfStringUniquingKnown)
}
open func add(_ aPort: Port, forMode mode: RunLoopMode) {
@@ -135,7 +146,7 @@
if _cfRunLoop !== CFRunLoopGetCurrent() {
return false
}
- let modeArg = mode.rawValue._cfObject
+ let modeArg = mode._cfStringUniquingKnown
if _CFRunLoopFinished(_cfRunLoop, modeArg) {
return false
}
@@ -147,7 +158,7 @@
}
public func perform(inModes modes: [RunLoopMode], block: @escaping () -> Void) {
- CFRunLoopPerformBlock(getCFRunLoop(), (modes.map { $0.rawValue._nsObject })._cfObject, block)
+ CFRunLoopPerformBlock(getCFRunLoop(), (modes.map { $0._cfStringUniquingKnown })._cfObject, block)
}
public func perform(_ block: @escaping () -> Void) {
diff --git a/TestFoundation/TestRunLoop.swift b/TestFoundation/TestRunLoop.swift
index 27668a2..931af8d 100644
--- a/TestFoundation/TestRunLoop.swift
+++ b/TestFoundation/TestRunLoop.swift
@@ -21,6 +21,7 @@
return [
("test_constants", test_constants),
("test_runLoopInit", test_runLoopInit),
+ ("test_commonModes", test_commonModes),
// these tests do not work the same as Darwin https://bugs.swift.org/browse/SR-399
// ("test_runLoopRunMode", test_runLoopRunMode),
// ("test_runLoopLimitDate", test_runLoopLimitDate),
@@ -90,4 +91,16 @@
XCTAssertLessThan(abs(timerTickInterval - expectedTimeInterval), 0.01)
}
+
+ func test_commonModes() {
+ let runLoop = RunLoop.current
+ let done = expectation(description: "The timer has fired")
+ let timer = Timer(timeInterval: 1, repeats: false) { (_) in
+ done.fulfill()
+ }
+
+ runLoop.add(timer, forMode: .commonModes)
+
+ waitForExpectations(timeout: 10)
+ }
}