Skip to content

Commit 621d3b7

Browse files
authored
Merge pull request #3827 from mwwa/libdispatch-data-leak
[libdispatch-data-leak] DisaptchData never calls destructor
2 parents 136c8d4 + ea0e8c5 commit 621d3b7

File tree

10 files changed

+67
-43
lines changed

10 files changed

+67
-43
lines changed

lib/ClangImporter/MappedTypes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ MAP_TYPE("dispatch_block_t", Block, 0, "Dispatch", "dispatch_block_t",
138138
true, DoNothing)
139139
MAP_TYPE("__swift_shims_dispatch_block_t", Block, 0, "Dispatch", "_DispatchBlock",
140140
true, DoNothing)
141+
MAP_TYPE("__swift_shims_dispatch_data_t", ObjCId, 0, "Dispatch", "dispatch_data_t",
142+
true, DoNothing)
141143

142144
// Objective-C types.
143145
MAP_TYPE("BOOL", ObjCBool, 8, "ObjectiveC", "ObjCBool", false, DoNothing)

stdlib/public/SDK/Dispatch/Data.swift

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,12 @@ public struct DispatchData : RandomAccessCollection, _ObjectiveCBridgeable {
8484
public func enumerateBytes(
8585
block: @noescape (buffer: UnsafeBufferPointer<UInt8>, byteIndex: Int, stop: inout Bool) -> Void)
8686
{
87-
_swift_dispatch_data_apply(__wrapped) { (data: __DispatchData, offset: Int, ptr: UnsafeRawPointer, size: Int) in
87+
_swift_dispatch_data_apply(__wrapped) { (_, offset: Int, ptr: UnsafeRawPointer, size: Int) in
8888
let bytePtr = ptr.bindMemory(to: UInt8.self, capacity: size)
8989
let bp = UnsafeBufferPointer(start: bytePtr, count: size)
9090
var stop = false
9191
block(buffer: bp, byteIndex: offset, stop: &stop)
92-
return !stop
92+
return stop ? 0 : 1
9393
}
9494
}
9595

@@ -286,11 +286,6 @@ extension DispatchData {
286286
}
287287
}
288288

289-
typealias _swift_data_applier = @convention(block) @noescape (__DispatchData, Int, UnsafeRawPointer, Int) -> Bool
290-
291-
@_silgen_name("_swift_dispatch_data_apply")
292-
internal func _swift_dispatch_data_apply(_ data: __DispatchData, _ block: _swift_data_applier)
293-
294289
@_silgen_name("_swift_dispatch_data_empty")
295290
internal func _swift_dispatch_data_empty() -> __DispatchData
296291

stdlib/public/SDK/Dispatch/Dispatch.mm

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -87,18 +87,6 @@ static void _dispatch_overlay_constructor() {
8787
return _dispatch_data_destructor_munmap;
8888
}
8989

90-
SWIFT_CC(swift) DISPATCH_RUNTIME_STDLIB_INTERFACE
91-
extern "C" bool
92-
_swift_dispatch_data_apply(dispatch_data_t data, bool (^applier)(dispatch_data_t, size_t, const void *, size_t)) {
93-
return dispatch_data_apply(data, applier);
94-
}
95-
96-
// DISPATCH_RUNTIME_STDLIB_INTERFACE
97-
// extern "C" dispatch_queue_t
98-
// _swift_apply_current_root_queue() {
99-
// return DISPATCH_APPLY_CURRENT_ROOT_QUEUE;
100-
// }
101-
10290
#define SOURCE(t) \
10391
SWIFT_CC(swift) \
10492
DISPATCH_RUNTIME_STDLIB_INTERFACE extern "C" dispatch_source_type_t \

stdlib/public/SDK/Dispatch/IO.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ public extension DispatchIO {
8686
}
8787

8888
public func setInterval(interval: DispatchTimeInterval, flags: IntervalFlags = []) {
89-
__dispatch_io_set_interval(self, interval.rawValue, flags.rawValue)
89+
__dispatch_io_set_interval(self, UInt64(interval.rawValue), flags.rawValue)
9090
}
9191

9292
public func close(flags: CloseFlags = []) {

stdlib/public/SDK/Dispatch/Queue.swift

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,3 @@ internal func _swift_dispatch_queue_concurrent() -> __OS_dispatch_queue_attr
354354

355355
@_silgen_name("_swift_dispatch_get_main_queue")
356356
internal func _swift_dispatch_get_main_queue() -> DispatchQueue
357-
358-
@_silgen_name("_swift_dispatch_apply_current_root_queue")
359-
internal func _swift_dispatch_apply_current_root_queue() -> DispatchQueue
360-

stdlib/public/SDK/Dispatch/Source.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -257,23 +257,23 @@ public extension DispatchSourceProcess {
257257

258258
public extension DispatchSourceTimer {
259259
public func scheduleOneshot(deadline: DispatchTime, leeway: DispatchTimeInterval = .nanoseconds(0)) {
260-
__dispatch_source_set_timer(self as! DispatchSource, deadline.rawValue, ~0, UInt64(leeway.rawValue))
260+
__dispatch_source_set_timer(self as! DispatchSource, UInt64(deadline.rawValue), ~0, UInt64(leeway.rawValue))
261261
}
262262

263263
public func scheduleOneshot(wallDeadline: DispatchWallTime, leeway: DispatchTimeInterval = .nanoseconds(0)) {
264-
__dispatch_source_set_timer(self as! DispatchSource, wallDeadline.rawValue, ~0, UInt64(leeway.rawValue))
264+
__dispatch_source_set_timer(self as! DispatchSource, UInt64(wallDeadline.rawValue), ~0, UInt64(leeway.rawValue))
265265
}
266266

267267
public func scheduleRepeating(deadline: DispatchTime, interval: DispatchTimeInterval, leeway: DispatchTimeInterval = .nanoseconds(0)) {
268-
__dispatch_source_set_timer(self as! DispatchSource, deadline.rawValue, interval.rawValue, UInt64(leeway.rawValue))
268+
__dispatch_source_set_timer(self as! DispatchSource, deadline.rawValue, UInt64(interval.rawValue), UInt64(leeway.rawValue))
269269
}
270270

271271
public func scheduleRepeating(deadline: DispatchTime, interval: Double, leeway: DispatchTimeInterval = .nanoseconds(0)) {
272272
__dispatch_source_set_timer(self as! DispatchSource, deadline.rawValue, UInt64(interval * Double(NSEC_PER_SEC)), UInt64(leeway.rawValue))
273273
}
274274

275275
public func scheduleRepeating(wallDeadline: DispatchWallTime, interval: DispatchTimeInterval, leeway: DispatchTimeInterval = .nanoseconds(0)) {
276-
__dispatch_source_set_timer(self as! DispatchSource, wallDeadline.rawValue, interval.rawValue, UInt64(leeway.rawValue))
276+
__dispatch_source_set_timer(self as! DispatchSource, wallDeadline.rawValue, UInt64(interval.rawValue), UInt64(leeway.rawValue))
277277
}
278278

279279
public func scheduleRepeating(wallDeadline: DispatchWallTime, interval: Double, leeway: DispatchTimeInterval = .nanoseconds(0)) {

stdlib/public/SDK/Dispatch/Time.swift

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -85,23 +85,23 @@ public enum DispatchTimeInterval {
8585
case microseconds(Int)
8686
case nanoseconds(Int)
8787

88-
internal var rawValue: UInt64 {
88+
internal var rawValue: Int64 {
8989
switch self {
90-
case .seconds(let s): return UInt64(s) * NSEC_PER_SEC
91-
case .milliseconds(let ms): return UInt64(ms) * NSEC_PER_MSEC
92-
case .microseconds(let us): return UInt64(us) * NSEC_PER_USEC
93-
case .nanoseconds(let ns): return UInt64(ns)
90+
case .seconds(let s): return Int64(s) * Int64(NSEC_PER_SEC)
91+
case .milliseconds(let ms): return Int64(ms) * Int64(NSEC_PER_MSEC)
92+
case .microseconds(let us): return Int64(us) * Int64(NSEC_PER_USEC)
93+
case .nanoseconds(let ns): return Int64(ns)
9494
}
9595
}
9696
}
9797

9898
public func +(time: DispatchTime, interval: DispatchTimeInterval) -> DispatchTime {
99-
let t = __dispatch_time(time.rawValue, Int64(interval.rawValue))
99+
let t = __dispatch_time(time.rawValue, interval.rawValue)
100100
return DispatchTime(rawValue: t)
101101
}
102102

103103
public func -(time: DispatchTime, interval: DispatchTimeInterval) -> DispatchTime {
104-
let t = __dispatch_time(time.rawValue, -Int64(interval.rawValue))
104+
let t = __dispatch_time(time.rawValue, -interval.rawValue)
105105
return DispatchTime(rawValue: t)
106106
}
107107

@@ -116,12 +116,12 @@ public func -(time: DispatchTime, seconds: Double) -> DispatchTime {
116116
}
117117

118118
public func +(time: DispatchWallTime, interval: DispatchTimeInterval) -> DispatchWallTime {
119-
let t = __dispatch_time(time.rawValue, Int64(interval.rawValue))
119+
let t = __dispatch_time(time.rawValue, interval.rawValue)
120120
return DispatchWallTime(rawValue: t)
121121
}
122122

123123
public func -(time: DispatchWallTime, interval: DispatchTimeInterval) -> DispatchWallTime {
124-
let t = __dispatch_time(time.rawValue, -Int64(interval.rawValue))
124+
let t = __dispatch_time(time.rawValue, -interval.rawValue)
125125
return DispatchWallTime(rawValue: t)
126126
}
127127

stdlib/public/SwiftShims/DispatchShims.h

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,14 @@
2525
#include "SwiftStddef.h"
2626
#include "Visibility.h"
2727

28-
#define SWIFT_DISPATCH_RETURNS_RETAINED_BLOCK __attribute__((__ns_returns_retained__))
28+
#define SWIFT_DISPATCH_RETURNS_RETAINED __attribute__((__ns_returns_retained__))
2929
#define SWIFT_DISPATCH_NOESCAPE __attribute__((__noescape__))
30+
#define SWIFT_DISPATCH_NONNULL _Nonnull
31+
#define SWIFT_DISPATCH_NULLABLE _Nullable
32+
#define SWIFT_DISPATCH_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin")
33+
#define SWIFT_DISPATCH_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end")
34+
35+
SWIFT_DISPATCH_ASSUME_NONNULL_BEGIN
3036

3137
#ifdef __cplusplus
3238
namespace swift { extern "C" {
@@ -40,16 +46,16 @@ typedef id __swift_shims_dispatch_group_t;
4046
typedef id __swift_shims_dispatch_data_t;
4147

4248
SWIFT_RUNTIME_STDLIB_INTERFACE
43-
SWIFT_DISPATCH_RETURNS_RETAINED_BLOCK
49+
SWIFT_DISPATCH_RETURNS_RETAINED
4450
__swift_shims_dispatch_block_t
4551
_swift_dispatch_block_create_with_qos_class(
4652
__swift_shims_dispatch_block_flags_t flags,
4753
__swift_shims_qos_class_t qos,
4854
int relative_priority,
49-
__swift_shims_dispatch_block_t block);
55+
__swift_shims_dispatch_block_t SWIFT_DISPATCH_NONNULL block);
5056

5157
SWIFT_RUNTIME_STDLIB_INTERFACE
52-
SWIFT_DISPATCH_RETURNS_RETAINED_BLOCK
58+
SWIFT_DISPATCH_RETURNS_RETAINED
5359
__swift_shims_dispatch_block_t
5460
_swift_dispatch_block_create_noescape(
5561
__swift_shims_dispatch_block_flags_t flags,
@@ -96,17 +102,28 @@ void _swift_dispatch_apply_current(
96102
void SWIFT_DISPATCH_NOESCAPE (^block)(long));
97103

98104
SWIFT_RUNTIME_STDLIB_INTERFACE
105+
SWIFT_DISPATCH_RETURNS_RETAINED
99106
__swift_shims_dispatch_data_t
100107
_swift_dispatch_data_create(
101108
const void *buffer,
102109
__swift_size_t size,
103-
__swift_shims_dispatch_queue_t queue,
104-
__swift_shims_dispatch_block_t destructor);
110+
__swift_shims_dispatch_queue_t SWIFT_DISPATCH_NULLABLE queue,
111+
__swift_shims_dispatch_block_t SWIFT_DISPATCH_NULLABLE destructor);
112+
113+
typedef unsigned int (^__swift_shims_dispatch_data_applier)(__swift_shims_dispatch_data_t, __swift_size_t, const void *, __swift_size_t);
114+
115+
SWIFT_RUNTIME_STDLIB_INTERFACE
116+
unsigned int
117+
_swift_dispatch_data_apply(
118+
__swift_shims_dispatch_data_t data,
119+
__swift_shims_dispatch_data_applier SWIFT_DISPATCH_NOESCAPE applier);
105120

106121
#ifdef __cplusplus
107122
}} // extern "C", namespace swift
108123
#endif
109124

125+
SWIFT_DISPATCH_ASSUME_NONNULL_END
126+
110127
#endif // __OBJC2__
111128

112129
#endif // SWIFT_STDLIB_SHIMS_DISPATCHSHIMS_H

stdlib/public/stubs/DispatchShims.mm

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,3 +131,12 @@ void SWIFT_DISPATCH_NOESCAPE (^block)(long))
131131
return dispatch_data_create(buffer, size, cast(queue), cast(destructor));
132132
}
133133

134+
unsigned int
135+
swift::_swift_dispatch_data_apply(
136+
__swift_shims_dispatch_data_t data,
137+
__swift_shims_dispatch_data_applier SWIFT_DISPATCH_NOESCAPE applier)
138+
{
139+
return dispatch_data_apply(data, ^bool(dispatch_data_t data, size_t off, const void *loc, size_t size){
140+
return applier(data, off, loc, size);
141+
});
142+
}

test/1_stdlib/Dispatch.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,20 @@ DispatchAPI.test("dispatch_data_t enumeration") {
6868
_ = 1
6969
}
7070
}
71+
72+
DispatchAPI.test("dispatch_data_t deallocator") {
73+
let q = DispatchQueue(label: "dealloc queue")
74+
var t = 0
75+
76+
autoreleasepool {
77+
let size = 1024
78+
let p = UnsafeMutablePointer<UInt8>.allocate(capacity: size)
79+
let d = DispatchData(bytesNoCopy: UnsafeBufferPointer(start: p, count: size), deallocator: .custom(q, {
80+
t = 1
81+
}))
82+
}
83+
84+
q.sync {
85+
expectEqual(1, t)
86+
}
87+
}

0 commit comments

Comments
 (0)