|
14 | 14 | //limitations under the License. |
15 | 15 | //===----------------------------------------------------------------------===// |
16 | 16 |
|
17 | | - |
18 | | - |
19 | | - |
20 | | - |
21 | 17 | ////////////////////////////////////////////////////////////////////////// |
22 | 18 | //This file is a temporary solution, just until Dispatch will run on Mac// |
23 | 19 | ////////////////////////////////////////////////////////////////////////// |
24 | 20 | #if os(Linux) |
25 | 21 |
|
26 | 22 | import Foundation |
27 | | - import CoreFoundation |
28 | 23 | import Result |
29 | 24 | #if os(Linux) |
30 | 25 | import Glibc |
|
35 | 30 | pthread.task?() |
36 | 31 | return nil |
37 | 32 | } |
38 | | - |
39 | | - private extension NSString { |
40 | | - var cfString: CFString { return unsafeBitCast(self, CFString.self) } |
41 | | - } |
42 | 33 |
|
43 | 34 | private class PThread { |
44 | 35 | let thread: UnsafeMutablePointer<pthread_t> |
|
58 | 49 | } |
59 | 50 | } |
60 | 51 |
|
61 | | - |
62 | | - private class RunLoopFinalizer { |
63 | | - private let rl: CFRunLoop! |
64 | | - init(_ runLoop: CFRunLoop!) { |
65 | | - self.rl = runLoop |
66 | | - } |
67 | | - deinit { |
68 | | - CFRunLoopStop(rl) |
69 | | - } |
70 | | - } |
71 | | - |
72 | | - private class RunLoopObject { |
73 | | - private var cfObject:AnyObject? = nil |
74 | | - private let task:SafeTask |
75 | | - private let finalizer:RunLoopFinalizer? |
76 | | - |
77 | | - init(_ task:SafeTask, runLoopFinalizer: RunLoopFinalizer?) { |
78 | | - self.task = task |
79 | | - self.finalizer = runLoopFinalizer |
80 | | - } |
81 | | - |
82 | | - func addToRunLoop(runLoop:CFRunLoop, mode: CFString) { |
83 | | - if cfObject == nil { |
84 | | - self.cfObject = createCFObject() |
85 | | - } |
86 | | - addCFObject(runLoop, mode: mode) |
87 | | - } |
88 | | - |
89 | | - func signal() {} |
90 | | - |
91 | | - private func createCFObject() -> AnyObject? { return nil } |
92 | | - |
93 | | - private func addCFObject(runLoop:CFRunLoop, mode: CFString) {} |
94 | | - } |
95 | | - |
96 | | - private func sourceMain(rls: UnsafeMutablePointer<Void>) { |
97 | | - let runLoopSource = Unmanaged<RunLoopObject>.fromOpaque(COpaquePointer(rls)).takeUnretainedValue() |
98 | | - runLoopSource.cfObject = nil |
99 | | - runLoopSource.task() |
100 | | - } |
101 | | - |
102 | | - private func sourceCancel(rls: UnsafeMutablePointer<Void>, rL: CFRunLoop!, mode:CFString!) { |
103 | | - let runLoopSource = Unmanaged<RunLoopObject>.fromOpaque(COpaquePointer(rls)).takeUnretainedValue() |
104 | | - runLoopSource.cfObject = nil |
105 | | - } |
106 | | - |
107 | | - private func sourceRetain(rls: UnsafePointer<Void>) -> UnsafePointer<Void> { |
108 | | - Unmanaged<RunLoopObject>.fromOpaque(COpaquePointer(rls)).retain() |
109 | | - return rls |
110 | | - } |
111 | | - |
112 | | - private func sourceRelease(rls: UnsafePointer<Void>) { |
113 | | - Unmanaged<RunLoopObject>.fromOpaque(COpaquePointer(rls)).release() |
114 | | - } |
115 | | - |
116 | | - private class RunLoopSource : RunLoopObject { |
117 | | - private let priority:Int |
118 | | - |
119 | | - init(_ task: SafeTask, priority: Int = 0, finalizer: RunLoopFinalizer?) { |
120 | | - self.priority = priority |
121 | | - super.init(task, runLoopFinalizer: finalizer) |
122 | | - } |
123 | | - |
124 | | - deinit { |
125 | | - if let s = cfObject as! CFRunLoopSource? { |
126 | | - if CFRunLoopSourceIsValid(s) { CFRunLoopSourceInvalidate(s) } |
127 | | - } |
128 | | - } |
129 | | - |
130 | | - private override func createCFObject() -> AnyObject? { |
131 | | - var context = CFRunLoopSourceContext( |
132 | | - version: 0, |
133 | | - info: UnsafeMutablePointer<Void>(Unmanaged.passUnretained(self).toOpaque()), |
134 | | - retain: sourceRetain, |
135 | | - release: sourceRelease, |
136 | | - copyDescription: nil, |
137 | | - equal: nil, |
138 | | - hash: nil, |
139 | | - schedule: nil, |
140 | | - cancel: sourceCancel, |
141 | | - perform: sourceMain |
142 | | - ) |
143 | | - return CFRunLoopSourceCreate(nil, priority, &context) |
144 | | - } |
145 | | - |
146 | | - private override func addCFObject(runLoop:CFRunLoop, mode: CFString) { |
147 | | - CFRunLoopAddSource(runLoop, (cfObject as! CFRunLoopSource?)!, mode) |
148 | | - } |
149 | | - |
150 | | - override func signal() { |
151 | | - if let s = cfObject as! CFRunLoopSource? { |
152 | | - CFRunLoopSourceSignal(s) |
153 | | - } |
154 | | - } |
155 | | - } |
156 | | - |
157 | | - private func timerCallback(timer: CFRunLoopTimer!, rlt: UnsafeMutablePointer<Void>) { |
158 | | - sourceMain(rlt) |
159 | | - } |
160 | | - |
161 | | - private class RunLoopDelay : RunLoopObject { |
162 | | - private let delay:CFTimeInterval |
163 | | - |
164 | | - init(_ task: SafeTask, delay: CFTimeInterval, finalizer: RunLoopFinalizer?) { |
165 | | - self.delay = delay |
166 | | - super.init(task, runLoopFinalizer: finalizer) |
167 | | - } |
168 | | - |
169 | | - deinit { |
170 | | - if let t = cfObject as! CFRunLoopTimer? { |
171 | | - if CFRunLoopTimerIsValid(t) { CFRunLoopTimerInvalidate(t) } |
172 | | - } |
173 | | - } |
174 | | - |
175 | | - private override func createCFObject() -> AnyObject? { |
176 | | - var context = CFRunLoopTimerContext( |
177 | | - version: 0, |
178 | | - info: UnsafeMutablePointer<Void>(Unmanaged.passUnretained(self).toOpaque()), |
179 | | - retain: sourceRetain, |
180 | | - release: sourceRelease, |
181 | | - copyDescription: nil |
182 | | - ) |
183 | | - return CFRunLoopTimerCreate(nil, CFAbsoluteTimeGetCurrent()+delay, -1, 0, 0, timerCallback, &context) |
184 | | - } |
185 | | - |
186 | | - private override func addCFObject(runLoop:CFRunLoop, mode: CFString) { |
187 | | - CFRunLoopAddTimer(runLoop, (cfObject as! CFRunLoopTimer?)!, mode) |
188 | | - } |
189 | | - } |
190 | | - |
191 | 52 | private class ParallelContext : ExecutionContextBase, ExecutionContextType { |
192 | 53 | func async(task:SafeTask) { |
193 | 54 | let thread = PThread(task: task) |
|
207 | 68 | } |
208 | 69 | } |
209 | 70 |
|
210 | | -#if !os(Linux) |
211 | | - let defaultMode:CFString = "kCFRunLoopDefaultMode" as NSString |
212 | | -#else |
213 | | - let defaultMode:CFString = "kCFRunLoopDefaultMode".bridge().cfString |
214 | | -#endif |
215 | | - |
216 | 71 | private class SerialContext : ExecutionContextBase, ExecutionContextType { |
217 | | - private let rl:CFRunLoop! |
218 | | - private let finalizer: RunLoopFinalizer? |
| 72 | + private let rl:RunLoop |
219 | 73 |
|
220 | 74 | override init() { |
221 | | - var runLoop:CFRunLoop? |
| 75 | + var runLoop:RunLoop? |
222 | 76 | let cond = NSCondition() |
223 | 77 | cond.lock() |
224 | | - let thread = PThread(task: { |
225 | | - runLoop = CFRunLoopGetCurrent() |
| 78 | + PThread(task: { |
| 79 | + runLoop = RunLoop.currentRunLoop(true) |
226 | 80 | cond.signal() |
227 | | - SerialContext.defaultLoop() |
228 | | - }) |
229 | | - thread.start() |
| 81 | + RunLoop.run() |
| 82 | + }).start() |
230 | 83 | cond.wait() |
231 | 84 | cond.unlock() |
232 | 85 | self.rl = runLoop! |
233 | | - finalizer = RunLoopFinalizer(self.rl) |
234 | 86 | } |
235 | 87 |
|
236 | | - init(runLoop:CFRunLoop!) { |
| 88 | + init(runLoop:RunLoop) { |
237 | 89 | rl = runLoop |
238 | | - finalizer = nil |
239 | | - } |
240 | | - |
241 | | - #if !os(Linux) |
242 | | - static func defaultLoop() { |
243 | | - while CFRunLoopRunInMode(defaultMode, 0, true) != .Stopped {} |
244 | | - } |
245 | | - #else |
246 | | - static func defaultLoop() { |
247 | | - while CFRunLoopRunInMode(defaultMode, 0, true) != Int32(kCFRunLoopRunStopped) {} |
248 | | - } |
249 | | - #endif |
250 | | - |
251 | | - private func performRunLoopObject(rlo: RunLoopObject) { |
252 | | - rlo.addToRunLoop(rl, mode: defaultMode) |
253 | | - rlo.signal() |
254 | | - CFRunLoopWakeUp(rl) |
255 | 90 | } |
256 | 91 |
|
257 | 92 | func async(task:SafeTask) { |
258 | | - performRunLoopObject(RunLoopSource(task, finalizer: finalizer)) |
| 93 | + rl.addSource(RunLoopSource(task), mode: RunLoop.defaultMode) |
259 | 94 | } |
260 | 95 |
|
261 | 96 | func async(after:Double, task:SafeTask) { |
262 | | - performRunLoopObject(RunLoopDelay(task, delay: after, finalizer: finalizer)) |
| 97 | + rl.addDelay(RunLoopDelay(task, delay: after), mode: RunLoop.defaultMode) |
263 | 98 | } |
264 | 99 |
|
265 | 100 | func sync<ReturnType>(task:() throws -> ReturnType) throws -> ReturnType { |
266 | | - if rl === CFRunLoopGetCurrent() { |
| 101 | + if rl.isCurrent() { |
267 | 102 | return try task() |
268 | 103 | } else { |
269 | 104 | return try syncThroughAsync(task) |
|
297 | 132 | inner.async(after, task: task) |
298 | 133 | } |
299 | 134 |
|
300 | | - public static let main:ExecutionContextType = PThreadExecutionContext(inner: SerialContext(runLoop: CFRunLoopGetMain())) |
| 135 | + public static let main:ExecutionContextType = PThreadExecutionContext(inner: SerialContext(runLoop: RunLoop.mainRunLoop())) |
301 | 136 | public static let global:ExecutionContextType = PThreadExecutionContext(kind: .Parallel) |
302 | 137 | } |
303 | 138 |
|
|
0 commit comments