Skip to content

Commit f3fc317

Browse files
dgrove-ossdas
authored andcommitted
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. Signed-off-by: Daniel A. Steffen <dsteffen@apple.com>
1 parent 13dd2ef commit f3fc317

File tree

2 files changed

+35
-7
lines changed

2 files changed

+35
-7
lines changed

src/swift/DispatchStubs.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,12 @@ _swift_dispatch_sync(dispatch_queue_t queue, dispatch_block_t block) {
159159
dispatch_sync(queue, block);
160160
}
161161

162+
SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE
163+
extern "C" void
164+
_swift_dispatch_release(dispatch_object_t obj) {
165+
dispatch_release(obj);
166+
}
167+
162168
// DISPATCH_RUNTIME_STDLIB_INTERFACE
163169
// extern "C" dispatch_queue_t
164170
// _swift_apply_current_root_queue() {

src/swift/Wrapper.swift

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@ import CDispatch
1616
// importer via Dispatch.apinote when the platform has Objective-C support
1717

1818
public class DispatchObject {
19-
// TODO: add deinit method to invoke dispatch_release on wrapped()
2019

2120
internal func wrapped() -> dispatch_object_t {
22-
assert(false, "should be override in subclass")
21+
fatalError("should be overriden in subclass")
2322
}
2423

2524
public func setTarget(queue:DispatchQueue) {
@@ -43,14 +42,18 @@ public class DispatchObject {
4342
public class DispatchGroup : DispatchObject {
4443
internal let __wrapped:dispatch_group_t;
4544

46-
internal override func wrapped() -> dispatch_object_t {
45+
final internal override func wrapped() -> dispatch_object_t {
4746
return unsafeBitCast(__wrapped, to: dispatch_object_t.self)
4847
}
4948

5049
public override init() {
5150
__wrapped = dispatch_group_create()
5251
}
5352

53+
deinit {
54+
_swift_dispatch_release(wrapped())
55+
}
56+
5457
public func enter() {
5558
dispatch_group_enter(__wrapped)
5659
}
@@ -63,19 +66,23 @@ public class DispatchGroup : DispatchObject {
6366
public class DispatchSemaphore : DispatchObject {
6467
internal let __wrapped: dispatch_semaphore_t;
6568

66-
internal override func wrapped() -> dispatch_object_t {
69+
final internal override func wrapped() -> dispatch_object_t {
6770
return unsafeBitCast(__wrapped, to: dispatch_object_t.self)
6871
}
6972

7073
public init(value: Int) {
7174
__wrapped = dispatch_semaphore_create(value)
7275
}
76+
77+
deinit {
78+
_swift_dispatch_release(wrapped())
79+
}
7380
}
7481

7582
public class DispatchIO : DispatchObject {
7683
internal let __wrapped:dispatch_io_t
7784

78-
internal override func wrapped() -> dispatch_object_t {
85+
final internal override func wrapped() -> dispatch_object_t {
7986
return unsafeBitCast(__wrapped, to: dispatch_object_t.self)
8087
}
8188

@@ -98,6 +105,10 @@ public class DispatchIO : DispatchObject {
98105
__wrapped = queue
99106
}
100107

108+
deinit {
109+
_swift_dispatch_release(wrapped())
110+
}
111+
101112
public func barrier(execute: () -> ()) {
102113
dispatch_io_barrier(self.__wrapped, execute)
103114
}
@@ -118,7 +129,7 @@ public class DispatchIO : DispatchObject {
118129
public class DispatchQueue : DispatchObject {
119130
internal let __wrapped:dispatch_queue_t;
120131

121-
internal override func wrapped() -> dispatch_object_t {
132+
final internal override func wrapped() -> dispatch_object_t {
122133
return unsafeBitCast(__wrapped, to: dispatch_object_t.self)
123134
}
124135

@@ -134,6 +145,10 @@ public class DispatchQueue : DispatchObject {
134145
__wrapped = queue
135146
}
136147

148+
deinit {
149+
_swift_dispatch_release(wrapped())
150+
}
151+
137152
public func sync(execute workItem: @noescape ()->()) {
138153
dispatch_sync(self.__wrapped, workItem)
139154
}
@@ -146,13 +161,17 @@ public class DispatchSource : DispatchObject,
146161
DispatchSourceWrite {
147162
internal let __wrapped:dispatch_source_t
148163

149-
internal override func wrapped() -> dispatch_object_t {
164+
final internal override func wrapped() -> dispatch_object_t {
150165
return unsafeBitCast(__wrapped, to: dispatch_object_t.self)
151166
}
152167

153168
internal init(source:dispatch_source_t) {
154169
__wrapped = source
155170
}
171+
172+
deinit {
173+
_swift_dispatch_release(wrapped())
174+
}
156175
}
157176

158177
#if HAVE_MACH
@@ -295,3 +314,6 @@ internal enum _OSQoSClass : UInt32 {
295314
}
296315
}
297316
}
317+
318+
@_silgen_name("_swift_dispatch_release")
319+
internal func _swift_dispatch_release(_ obj: dispatch_object_t) -> Void

0 commit comments

Comments
 (0)