Skip to content

release wrapped C objects when Swift object deinitialized #98

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 6, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/swift/DispatchStubs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
36 changes: 29 additions & 7 deletions src/swift/Wrapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -43,14 +42,18 @@ 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)
}

public override init() {
__wrapped = dispatch_group_create()
}

deinit {
_swift_dispatch_release(wrapped())
}

public func enter() {
dispatch_group_enter(__wrapped)
}
Expand All @@ -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)
}

Expand All @@ -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)
}
Expand All @@ -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)
}

Expand All @@ -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)
}
Expand All @@ -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
Expand Down Expand Up @@ -295,3 +314,6 @@ internal enum _OSQoSClass : UInt32 {
}
}
}

@_silgen_name("_swift_dispatch_release")
internal func _swift_dispatch_release(_ obj: dispatch_object_t) -> Void