From 11ee0a39d741a37fc6485402297b2e4237171e39 Mon Sep 17 00:00:00 2001 From: David Grove Date: Tue, 5 Jul 2016 16:30:25 -0400 Subject: [PATCH] release wrapped C objects when Swift object deinitialized ARC support in wrapping overlay. Add deinit methods to wrapping Swift classes that call dispatch_release on the wrapped C objects. --- src/swift/DispatchStubs.cc | 6 ++++++ src/swift/Wrapper.swift | 36 +++++++++++++++++++++++++++++------- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/swift/DispatchStubs.cc b/src/swift/DispatchStubs.cc index 62a53ef6b..1e5ec74f7 100644 --- a/src/swift/DispatchStubs.cc +++ b/src/swift/DispatchStubs.cc @@ -159,6 +159,12 @@ _swift_dispatch_sync(dispatch_queue_t queue, dispatch_block_t block) { dispatch_sync(queue, block); } +SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE +extern "C" void +_swift_dispatch_release(dispatch_object_t obj) { + dispatch_release(obj); +} + // DISPATCH_RUNTIME_STDLIB_INTERFACE // extern "C" dispatch_queue_t // _swift_apply_current_root_queue() { diff --git a/src/swift/Wrapper.swift b/src/swift/Wrapper.swift index a0d1e8e4f..ef7bf30d9 100644 --- a/src/swift/Wrapper.swift +++ b/src/swift/Wrapper.swift @@ -16,10 +16,9 @@ import CDispatch // importer via Dispatch.apinote when the platform has Objective-C support public class DispatchObject { - // TODO: add deinit method to invoke dispatch_release on wrapped() internal func wrapped() -> dispatch_object_t { - assert(false, "should be override in subclass") + fatalError("should be overriden in subclass") } public func setTarget(queue:DispatchQueue) { @@ -43,7 +42,7 @@ public class DispatchObject { public class DispatchGroup : DispatchObject { internal let __wrapped:dispatch_group_t; - internal override func wrapped() -> dispatch_object_t { + final internal override func wrapped() -> dispatch_object_t { return unsafeBitCast(__wrapped, to: dispatch_object_t.self) } @@ -51,6 +50,10 @@ public class DispatchGroup : DispatchObject { __wrapped = dispatch_group_create() } + deinit { + _swift_dispatch_release(wrapped()) + } + public func enter() { dispatch_group_enter(__wrapped) } @@ -63,19 +66,23 @@ public class DispatchGroup : DispatchObject { public class DispatchSemaphore : DispatchObject { internal let __wrapped: dispatch_semaphore_t; - internal override func wrapped() -> dispatch_object_t { + final internal override func wrapped() -> dispatch_object_t { return unsafeBitCast(__wrapped, to: dispatch_object_t.self) } public init(value: Int) { __wrapped = dispatch_semaphore_create(value) } + + deinit { + _swift_dispatch_release(wrapped()) + } } public class DispatchIO : DispatchObject { internal let __wrapped:dispatch_io_t - internal override func wrapped() -> dispatch_object_t { + final internal override func wrapped() -> dispatch_object_t { return unsafeBitCast(__wrapped, to: dispatch_object_t.self) } @@ -98,6 +105,10 @@ public class DispatchIO : DispatchObject { __wrapped = queue } + deinit { + _swift_dispatch_release(wrapped()) + } + public func barrier(execute: () -> ()) { dispatch_io_barrier(self.__wrapped, execute) } @@ -118,7 +129,7 @@ public class DispatchIO : DispatchObject { public class DispatchQueue : DispatchObject { internal let __wrapped:dispatch_queue_t; - internal override func wrapped() -> dispatch_object_t { + final internal override func wrapped() -> dispatch_object_t { return unsafeBitCast(__wrapped, to: dispatch_object_t.self) } @@ -134,6 +145,10 @@ public class DispatchQueue : DispatchObject { __wrapped = queue } + deinit { + _swift_dispatch_release(wrapped()) + } + public func sync(execute workItem: @noescape ()->()) { dispatch_sync(self.__wrapped, workItem) } @@ -146,13 +161,17 @@ public class DispatchSource : DispatchObject, DispatchSourceWrite { internal let __wrapped:dispatch_source_t - internal override func wrapped() -> dispatch_object_t { + final internal override func wrapped() -> dispatch_object_t { return unsafeBitCast(__wrapped, to: dispatch_object_t.self) } internal init(source:dispatch_source_t) { __wrapped = source } + + deinit { + _swift_dispatch_release(wrapped()) + } } #if HAVE_MACH @@ -295,3 +314,6 @@ internal enum _OSQoSClass : UInt32 { } } } + +@_silgen_name("_swift_dispatch_release") +internal func _swift_dispatch_release(_ obj: dispatch_object_t) -> Void