Skip to content

Commit d7cba5f

Browse files
authored
Merge pull request #1439 from millenomi/cfrunloop-fix-linux
2 parents 833f572 + f6b74b8 commit d7cba5f

File tree

2 files changed

+27
-3
lines changed

2 files changed

+27
-3
lines changed

Foundation/RunLoop.swift

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,17 @@ public struct RunLoopMode : RawRepresentable, Equatable, Hashable {
4343
extension RunLoopMode {
4444
public static let defaultRunLoopMode = RunLoopMode("kCFRunLoopDefaultMode")
4545
public static let commonModes = RunLoopMode("kCFRunLoopCommonModes")
46+
47+
// Use this instead of .rawValue._cfObject; this will allow CFRunLoop to use pointer equality internally.
48+
fileprivate var _cfStringUniquingKnown: CFString {
49+
if self == .defaultRunLoopMode {
50+
return kCFRunLoopDefaultMode
51+
} else if self == .commonModes {
52+
return kCFRunLoopCommonModes
53+
} else {
54+
return rawValue._cfObject
55+
}
56+
}
4657
}
4758

4859
internal func _NSRunLoopNew(_ cf: CFRunLoop) -> Unmanaged<AnyObject> {
@@ -81,7 +92,7 @@ open class RunLoop: NSObject {
8192
}
8293

8394
open func add(_ timer: Timer, forMode mode: RunLoopMode) {
84-
CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer._cfObject, mode.rawValue._cfObject)
95+
CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer._cfObject, mode._cfStringUniquingKnown)
8596
}
8697

8798
open func add(_ aPort: Port, forMode mode: RunLoopMode) {
@@ -135,7 +146,7 @@ extension RunLoop {
135146
if _cfRunLoop !== CFRunLoopGetCurrent() {
136147
return false
137148
}
138-
let modeArg = mode.rawValue._cfObject
149+
let modeArg = mode._cfStringUniquingKnown
139150
if _CFRunLoopFinished(_cfRunLoop, modeArg) {
140151
return false
141152
}
@@ -147,7 +158,7 @@ extension RunLoop {
147158
}
148159

149160
public func perform(inModes modes: [RunLoopMode], block: @escaping () -> Void) {
150-
CFRunLoopPerformBlock(getCFRunLoop(), (modes.map { $0.rawValue._nsObject })._cfObject, block)
161+
CFRunLoopPerformBlock(getCFRunLoop(), (modes.map { $0._cfStringUniquingKnown })._cfObject, block)
151162
}
152163

153164
public func perform(_ block: @escaping () -> Void) {

TestFoundation/TestRunLoop.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ class TestRunLoop : XCTestCase {
2121
return [
2222
("test_constants", test_constants),
2323
("test_runLoopInit", test_runLoopInit),
24+
("test_commonModes", test_commonModes),
2425
// these tests do not work the same as Darwin https://bugs.swift.org/browse/SR-399
2526
// ("test_runLoopRunMode", test_runLoopRunMode),
2627
// ("test_runLoopLimitDate", test_runLoopLimitDate),
@@ -90,4 +91,16 @@ class TestRunLoop : XCTestCase {
9091

9192
XCTAssertLessThan(abs(timerTickInterval - expectedTimeInterval), 0.01)
9293
}
94+
95+
func test_commonModes() {
96+
let runLoop = RunLoop.current
97+
let done = expectation(description: "The timer has fired")
98+
let timer = Timer(timeInterval: 1, repeats: false) { (_) in
99+
done.fulfill()
100+
}
101+
102+
runLoop.add(timer, forMode: .commonModes)
103+
104+
waitForExpectations(timeout: 10)
105+
}
93106
}

0 commit comments

Comments
 (0)