Skip to content

Commit b902e2f

Browse files
committed
Memory cycle fix
1 parent 469c9a7 commit b902e2f

File tree

2 files changed

+35
-30
lines changed

2 files changed

+35
-30
lines changed

ExecutionContext/PThreadExecutionContext.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,18 +72,18 @@
7272
private let rl:RunLoop
7373

7474
override init() {
75-
var runLoop:RunLoop?
75+
var runLoop:AnyObject?
7676
let sema = Semaphore()
7777

7878
PThread(task: {
79-
runLoop = RunLoop.currentRunLoop(true)
79+
runLoop = RunLoop.currentCFRunLoop()
8080
sema.signal()
8181
RunLoop.run()
8282
}).start()
8383

8484
sema.wait()
8585

86-
self.rl = runLoop!
86+
self.rl = RunLoop(runLoop!, autoStop: true)
8787
}
8888

8989
init(runLoop:RunLoop) {

ExecutionContext/RunLoop.swift

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -37,22 +37,13 @@ import CoreFoundation
3737
}
3838

3939
private func runLoopCallbackInfoRun(i: UnsafeMutablePointer<Void>) {
40-
let info = Unmanaged<RunLoopCallbackInfo>.fromOpaque(COpaquePointer(i)).takeUnretainedValue()
40+
let info = Unmanaged<RunLoopCallbackInfo>.fromOpaque(COpaquePointer(i)).takeRetainedValue()
4141
info.run()
4242
}
4343

44-
private func runLoopCallbackInfoRetain(i: UnsafePointer<Void>) -> UnsafePointer<Void> {
45-
Unmanaged<RunLoopCallbackInfo>.fromOpaque(COpaquePointer(i)).retain()
46-
return i
47-
}
48-
49-
private func runLoopCallbackInfoRelease(i: UnsafePointer<Void>) {
50-
Unmanaged<RunLoopCallbackInfo>.fromOpaque(COpaquePointer(i)).release()
51-
}
52-
5344
private protocol RunLoopCallback {
5445
var info : RunLoopCallbackInfo { get }
55-
var cfObject: AnyObject { mutating get }
46+
var cfObject: AnyObject { get }
5647
}
5748

5849
class RunLoopSource : RunLoopCallback {
@@ -65,9 +56,9 @@ import CoreFoundation
6556
if _source == nil {
6657
var context = CFRunLoopSourceContext(
6758
version: 0,
68-
info: UnsafeMutablePointer<Void>(Unmanaged.passUnretained(info).toOpaque()),
69-
retain: runLoopCallbackInfoRetain,
70-
release: runLoopCallbackInfoRelease,
59+
info: UnsafeMutablePointer<Void>(Unmanaged.passRetained(info).toOpaque()),
60+
retain: nil,
61+
release: nil,
7162
copyDescription: nil,
7263
equal: nil,
7364
hash: nil,
@@ -101,9 +92,9 @@ import CoreFoundation
10192
if _timer == nil {
10293
var context = CFRunLoopTimerContext(
10394
version: 0,
104-
info: UnsafeMutablePointer<Void>(Unmanaged.passUnretained(info).toOpaque()),
105-
retain: runLoopCallbackInfoRetain,
106-
release: runLoopCallbackInfoRelease,
95+
info: UnsafeMutablePointer<Void>(Unmanaged.passRetained(info).toOpaque()),
96+
retain: nil,
97+
release: nil,
10798
copyDescription: nil
10899
)
109100
_timer = CFRunLoopTimerCreate(nil, CFAbsoluteTimeGetCurrent()+delay, -1, 0, 0, timerRunCallback, &context)
@@ -128,9 +119,13 @@ import CoreFoundation
128119
static let defaultMode:NSString = "kCFRunLoopDefaultMode".bridge()
129120
#endif
130121

131-
init(_ runLoop: CFRunLoop, autoStop: Bool = true) {
132-
self.cfRunLoop = runLoop
133-
self.autoStop = autoStop
122+
init(_ cfRunLoop: CFRunLoop, autoStop: Bool = true) {
123+
self.cfRunLoop = cfRunLoop
124+
self.autoStop = autoStop
125+
}
126+
127+
convenience init(_ runLoop: AnyObject, autoStop: Bool = true) {
128+
self.init(unsafeBitCast(runLoop, CFRunLoop.self), autoStop: autoStop)
134129
}
135130

136131
deinit {
@@ -146,6 +141,10 @@ import CoreFoundation
146141
static func mainRunLoop() -> RunLoop {
147142
return RunLoop(CFRunLoopGetMain(), autoStop: false)
148143
}
144+
145+
static func currentCFRunLoop() -> AnyObject {
146+
return CFRunLoopGetCurrent()
147+
}
149148

150149
func isCurrent() -> Bool {
151150
return cfRunLoop === CFRunLoopGetCurrent()
@@ -168,16 +167,22 @@ import CoreFoundation
168167
}
169168

170169
func addSource(rls: RunLoopSource, mode: NSString) {
171-
rls.info.runLoops.append(self)
172-
CFRunLoopAddSource(cfRunLoop, unsafeBitCast(rls.cfObject, CFRunLoopSource.self), mode.cfString)
173-
CFRunLoopSourceSignal(unsafeBitCast(rls.cfObject, CFRunLoopSource.self))
174-
CFRunLoopWakeUp(cfRunLoop)
170+
let crls = unsafeBitCast(rls.cfObject, CFRunLoopSource.self)
171+
if CFRunLoopSourceIsValid(crls) {
172+
CFRunLoopAddSource(cfRunLoop, crls, mode.cfString)
173+
rls.info.runLoops.append(self)
174+
CFRunLoopSourceSignal(unsafeBitCast(rls.cfObject, CFRunLoopSource.self))
175+
CFRunLoopWakeUp(cfRunLoop)
176+
}
175177
}
176178

177179
func addDelay(rld: RunLoopDelay, mode: NSString) {
178-
rld.info.runLoops.append(self)
179-
CFRunLoopAddTimer(cfRunLoop, unsafeBitCast(rld.cfObject, CFRunLoopTimer.self), mode.cfString)
180-
CFRunLoopWakeUp(cfRunLoop)
180+
let crld = unsafeBitCast(rld.cfObject, CFRunLoopTimer.self)
181+
if CFRunLoopTimerIsValid(crld) {
182+
CFRunLoopAddTimer(cfRunLoop, crld, mode.cfString)
183+
rld.info.runLoops.append(self)
184+
CFRunLoopWakeUp(cfRunLoop)
185+
}
181186
}
182187
}
183188
//#endif

0 commit comments

Comments
 (0)