Skip to content

Commit 73b25c5

Browse files
lilyballgribozavr
authored andcommitted
Use shims for all calls to Dispatch APIs that take blocks
This ensures that blocks that come from `DispatchWorkItem`s will function correctly. The only exception is __dispatch_barrier_sync() as the block passed to that call is not `@convention(block)` so it doesn't matter. Fixes SR-2246.
1 parent fda6d4e commit 73b25c5

File tree

6 files changed

+110
-22
lines changed

6 files changed

+110
-22
lines changed

stdlib/public/SDK/Dispatch/Dispatch.swift

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
@_exported import Dispatch
14+
import SwiftShims
1415

1516
/// dispatch_assert
1617

@@ -132,15 +133,15 @@ public extension DispatchGroup {
132133
public func notify(qos: DispatchQoS = .unspecified, flags: DispatchWorkItemFlags = [], queue: DispatchQueue, execute work: @escaping @convention(block) () -> ()) {
133134
if #available(OSX 10.10, iOS 8.0, *), qos != .unspecified || !flags.isEmpty {
134135
let item = DispatchWorkItem(qos: qos, flags: flags, block: work)
135-
__dispatch_group_notify(self, queue, item._block)
136+
_swift_dispatch_group_notify(self, queue, item._block)
136137
} else {
137-
__dispatch_group_notify(self, queue, work)
138+
_swift_dispatch_group_notify(self, queue, work)
138139
}
139140
}
140141

141142
@available(OSX 10.10, iOS 8.0, *)
142143
public func notify(queue: DispatchQueue, work: DispatchWorkItem) {
143-
__dispatch_group_notify(self, queue, work._block)
144+
_swift_dispatch_group_notify(self, queue, work._block)
144145
}
145146

146147
public func wait() {

stdlib/public/SDK/Dispatch/Queue.swift

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,10 @@ public extension DispatchQueue {
200200
if group == nil && qos == .unspecified {
201201
// Fast-path route for the most common API usage
202202
if flags.isEmpty {
203-
__dispatch_async(self, work)
203+
_swift_dispatch_async(self, work)
204204
return
205205
} else if flags == .barrier {
206-
__dispatch_barrier_async(self, work)
206+
_swift_dispatch_barrier_async(self, work)
207207
return
208208
}
209209
}
@@ -215,9 +215,9 @@ public extension DispatchQueue {
215215
}
216216

217217
if let g = group {
218-
__dispatch_group_async(g, self, block)
218+
_swift_dispatch_group_async(g, self, block)
219219
} else {
220-
__dispatch_async(self, block)
220+
_swift_dispatch_async(self, block)
221221
}
222222
}
223223

@@ -292,9 +292,9 @@ public extension DispatchQueue {
292292
{
293293
if #available(OSX 10.10, iOS 8.0, *), qos != .unspecified || !flags.isEmpty {
294294
let item = DispatchWorkItem(qos: qos, flags: flags, block: work)
295-
__dispatch_after(deadline.rawValue, self, item._block)
295+
_swift_dispatch_after(deadline.rawValue, self, item._block)
296296
} else {
297-
__dispatch_after(deadline.rawValue, self, work)
297+
_swift_dispatch_after(deadline.rawValue, self, work)
298298
}
299299
}
300300

@@ -306,20 +306,20 @@ public extension DispatchQueue {
306306
{
307307
if #available(OSX 10.10, iOS 8.0, *), qos != .unspecified || !flags.isEmpty {
308308
let item = DispatchWorkItem(qos: qos, flags: flags, block: work)
309-
__dispatch_after(wallDeadline.rawValue, self, item._block)
309+
_swift_dispatch_after(wallDeadline.rawValue, self, item._block)
310310
} else {
311-
__dispatch_after(wallDeadline.rawValue, self, work)
311+
_swift_dispatch_after(wallDeadline.rawValue, self, work)
312312
}
313313
}
314314

315315
@available(OSX 10.10, iOS 8.0, *)
316316
public func asyncAfter(deadline: DispatchTime, execute: DispatchWorkItem) {
317-
__dispatch_after(deadline.rawValue, self, execute._block)
317+
_swift_dispatch_after(deadline.rawValue, self, execute._block)
318318
}
319319

320320
@available(OSX 10.10, iOS 8.0, *)
321321
public func asyncAfter(wallDeadline: DispatchWallTime, execute: DispatchWorkItem) {
322-
__dispatch_after(wallDeadline.rawValue, self, execute._block)
322+
_swift_dispatch_after(wallDeadline.rawValue, self, execute._block)
323323
}
324324

325325
@available(OSX 10.10, iOS 8.0, *)

stdlib/public/SDK/Dispatch/Source.swift

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
// import Foundation
14+
import SwiftShims
1415

1516
public extension DispatchSourceProtocol {
1617
typealias DispatchSourceHandler = @convention(block) () -> Void
@@ -20,47 +21,47 @@ public extension DispatchSourceProtocol {
2021
let h = handler,
2122
qos != .unspecified || !flags.isEmpty {
2223
let item = DispatchWorkItem(qos: qos, flags: flags, block: h)
23-
__dispatch_source_set_event_handler(self as! DispatchSource, item._block)
24+
_swift_dispatch_source_set_event_handler(self as! DispatchSource, item._block)
2425
} else {
25-
__dispatch_source_set_event_handler(self as! DispatchSource, handler)
26+
_swift_dispatch_source_set_event_handler(self as! DispatchSource, handler)
2627
}
2728
}
2829

2930
@available(OSX 10.10, iOS 8.0, *)
3031
public func setEventHandler(handler: DispatchWorkItem) {
31-
__dispatch_source_set_event_handler(self as! DispatchSource, handler._block)
32+
_swift_dispatch_source_set_event_handler(self as! DispatchSource, handler._block)
3233
}
3334

3435
public func setCancelHandler(qos: DispatchQoS = .unspecified, flags: DispatchWorkItemFlags = [], handler: DispatchSourceHandler?) {
3536
if #available(OSX 10.10, iOS 8.0, *),
3637
let h = handler,
3738
qos != .unspecified || !flags.isEmpty {
3839
let item = DispatchWorkItem(qos: qos, flags: flags, block: h)
39-
__dispatch_source_set_cancel_handler(self as! DispatchSource, item._block)
40+
_swift_dispatch_source_set_cancel_handler(self as! DispatchSource, item._block)
4041
} else {
41-
__dispatch_source_set_cancel_handler(self as! DispatchSource, handler)
42+
_swift_dispatch_source_set_cancel_handler(self as! DispatchSource, handler)
4243
}
4344
}
4445

4546
@available(OSX 10.10, iOS 8.0, *)
4647
public func setCancelHandler(handler: DispatchWorkItem) {
47-
__dispatch_source_set_cancel_handler(self as! DispatchSource, handler._block)
48+
_swift_dispatch_source_set_cancel_handler(self as! DispatchSource, handler._block)
4849
}
4950

5051
public func setRegistrationHandler(qos: DispatchQoS = .unspecified, flags: DispatchWorkItemFlags = [], handler: DispatchSourceHandler?) {
5152
if #available(OSX 10.10, iOS 8.0, *),
5253
let h = handler,
5354
qos != .unspecified || !flags.isEmpty {
5455
let item = DispatchWorkItem(qos: qos, flags: flags, block: h)
55-
__dispatch_source_set_registration_handler(self as! DispatchSource, item._block)
56+
_swift_dispatch_source_set_registration_handler(self as! DispatchSource, item._block)
5657
} else {
57-
__dispatch_source_set_registration_handler(self as! DispatchSource, handler)
58+
_swift_dispatch_source_set_registration_handler(self as! DispatchSource, handler)
5859
}
5960
}
6061

6162
@available(OSX 10.10, iOS 8.0, *)
6263
public func setRegistrationHandler(handler: DispatchWorkItem) {
63-
__dispatch_source_set_registration_handler(self as! DispatchSource, handler._block)
64+
_swift_dispatch_source_set_registration_handler(self as! DispatchSource, handler._block)
6465
}
6566

6667
@available(OSX 10.12, iOS 10.0, tvOS 10.0, watchOS 3.0, *)

stdlib/public/SDK/Dispatch/Time.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
import SwiftShims
14+
1315
public struct DispatchTime : Comparable {
1416
public let rawValue: dispatch_time_t
1517

stdlib/public/SwiftShims/DispatchShims.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,12 @@ namespace swift { extern "C" {
4040

4141
typedef unsigned long __swift_shims_dispatch_block_flags_t;
4242
typedef unsigned int __swift_shims_qos_class_t;
43+
typedef __swift_uint64_t __swift_shims_dispatch_time_t;
4344
typedef void (^__swift_shims_dispatch_block_t)(void);
4445
typedef id __swift_shims_dispatch_queue_t;
4546
typedef id __swift_shims_dispatch_group_t;
4647
typedef id __swift_shims_dispatch_data_t;
48+
typedef id __swift_shims_dispatch_source_t;
4749

4850
SWIFT_RUNTIME_STDLIB_INTERFACE
4951
SWIFT_DISPATCH_RETURNS_RETAINED
@@ -90,12 +92,29 @@ void _swift_dispatch_sync(
9092
__swift_shims_dispatch_queue_t queue,
9193
__swift_shims_dispatch_block_t block);
9294

95+
SWIFT_RUNTIME_STDLIB_INTERFACE
96+
void _swift_dispatch_barrier_async(
97+
__swift_shims_dispatch_queue_t queue,
98+
__swift_shims_dispatch_block_t block);
99+
93100
SWIFT_RUNTIME_STDLIB_INTERFACE
94101
void _swift_dispatch_group_async(
95102
__swift_shims_dispatch_group_t group,
96103
__swift_shims_dispatch_queue_t queue,
97104
__swift_shims_dispatch_block_t block);
98105

106+
SWIFT_RUNTIME_STDLIB_INTERFACE
107+
void _swift_dispatch_group_notify(
108+
__swift_shims_dispatch_group_t group,
109+
__swift_shims_dispatch_queue_t queue,
110+
__swift_shims_dispatch_block_t block);
111+
112+
SWIFT_RUNTIME_STDLIB_INTERFACE
113+
void _swift_dispatch_after(
114+
__swift_shims_dispatch_time_t when,
115+
__swift_shims_dispatch_queue_t queue,
116+
__swift_shims_dispatch_block_t block);
117+
99118
SWIFT_RUNTIME_STDLIB_INTERFACE
100119
void _swift_dispatch_apply_current(
101120
unsigned int iterations,
@@ -118,6 +137,21 @@ _swift_dispatch_data_apply(
118137
__swift_shims_dispatch_data_t data,
119138
__swift_shims_dispatch_data_applier SWIFT_DISPATCH_NOESCAPE applier);
120139

140+
SWIFT_RUNTIME_STDLIB_INTERFACE
141+
void _swift_dispatch_source_set_event_handler(
142+
__swift_shims_dispatch_source_t source,
143+
__swift_shims_dispatch_block_t SWIFT_DISPATCH_NULLABLE block);
144+
145+
SWIFT_RUNTIME_STDLIB_INTERFACE
146+
void _swift_dispatch_source_set_cancel_handler(
147+
__swift_shims_dispatch_source_t source,
148+
__swift_shims_dispatch_block_t SWIFT_DISPATCH_NULLABLE block);
149+
150+
SWIFT_RUNTIME_STDLIB_INTERFACE
151+
void _swift_dispatch_source_set_registration_handler(
152+
__swift_shims_dispatch_source_t source,
153+
__swift_shims_dispatch_block_t SWIFT_DISPATCH_NULLABLE block);
154+
121155
#ifdef __cplusplus
122156
}} // extern "C", namespace swift
123157
#endif

stdlib/public/stubs/DispatchShims.mm

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,14 @@
9494
dispatch_async(cast(queue), cast(block));
9595
}
9696

97+
void
98+
swift::_swift_dispatch_barrier_async(
99+
__swift_shims_dispatch_queue_t queue,
100+
__swift_shims_dispatch_block_t block)
101+
{
102+
dispatch_barrier_async(cast(queue), cast(block));
103+
}
104+
97105
void
98106
swift::_swift_dispatch_group_async(
99107
__swift_shims_dispatch_group_t group,
@@ -103,6 +111,15 @@
103111
dispatch_group_async((dispatch_group_t)group, cast(queue), cast(block));
104112
}
105113

114+
void
115+
swift::_swift_dispatch_group_notify(
116+
__swift_shims_dispatch_group_t group,
117+
__swift_shims_dispatch_queue_t queue,
118+
__swift_shims_dispatch_block_t block)
119+
{
120+
dispatch_group_notify((dispatch_group_t)group, cast(queue), cast(block));
121+
}
122+
106123
void
107124
swift::_swift_dispatch_sync(
108125
__swift_shims_dispatch_queue_t queue,
@@ -111,6 +128,15 @@
111128
dispatch_sync(cast(queue), cast(block));
112129
}
113130

131+
void
132+
swift::_swift_dispatch_after(
133+
__swift_shims_dispatch_time_t when,
134+
__swift_shims_dispatch_queue_t queue,
135+
__swift_shims_dispatch_block_t block)
136+
{
137+
dispatch_after((dispatch_time_t)when, cast(queue), cast(block));
138+
}
139+
114140
void
115141
swift::_swift_dispatch_apply_current(
116142
unsigned int iterations,
@@ -140,3 +166,27 @@ void SWIFT_DISPATCH_NOESCAPE (^block)(long))
140166
return applier(data, off, loc, size);
141167
});
142168
}
169+
170+
void
171+
swift::_swift_dispatch_source_set_event_handler(
172+
__swift_shims_dispatch_source_t source,
173+
__swift_shims_dispatch_block_t block)
174+
{
175+
dispatch_source_set_event_handler((dispatch_source_t)source, cast(block));
176+
}
177+
178+
void
179+
swift::_swift_dispatch_source_set_cancel_handler(
180+
__swift_shims_dispatch_source_t source,
181+
__swift_shims_dispatch_block_t block)
182+
{
183+
dispatch_source_set_cancel_handler((dispatch_source_t)source, cast(block));
184+
}
185+
186+
void
187+
swift::_swift_dispatch_source_set_registration_handler(
188+
__swift_shims_dispatch_source_t source,
189+
__swift_shims_dispatch_block_t block)
190+
{
191+
dispatch_source_set_registration_handler((dispatch_source_t)source, cast(block));
192+
}

0 commit comments

Comments
 (0)