Skip to content

Commit ad2735c

Browse files
committed
task names review update
1 parent a74a445 commit ad2735c

File tree

6 files changed

+259
-383
lines changed

6 files changed

+259
-383
lines changed

Runtimes/Core/Concurrency/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
add_subdirectory(InternalShims)
22

3+
gyb_expand(Task+init.swift.gyb Task+init.swift)
34
gyb_expand(TaskGroup+addTask.swift.gyb TaskGroup+addTask.swift)
45
gyb_expand(Task+startSynchronously.swift.gyb Task+startSynchronously.swift)
56

stdlib/public/Concurrency/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ add_swift_target_library(swift_Concurrency ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} I
212212
${SWIFT_RUNTIME_CONCURRENCY_NONEMBEDDED_SWIFT_SOURCES}
213213

214214
GYB_SOURCES
215+
Task+init.swift.gyb
215216
TaskGroup+addTask.swift.gyb
216217
Task+startSynchronously.swift.gyb
217218

stdlib/public/Concurrency/Task+TaskExecutor.swift

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -237,10 +237,14 @@ extension Task where Failure == Never {
237237
}
238238
// Set up the job flags for a new task.
239239
let flags = taskCreateFlags(
240-
priority: priority, isChildTask: false, copyTaskLocals: true,
241-
inheritContext: true, enqueueJob: true,
240+
priority: priority,
241+
isChildTask: false,
242+
copyTaskLocals: true,
243+
inheritContext: true,
244+
enqueueJob: true,
242245
addPendingGroupTaskUnconditionally: false,
243-
isDiscardingTask: false, isSynchronousStart: false)
246+
isDiscardingTask: false,
247+
isSynchronousStart: false)
244248

245249
#if $BuiltinCreateAsyncTaskOwnedTaskExecutor
246250
let (task, _) = Builtin.createTask(
@@ -328,7 +332,7 @@ extension Task where Failure == Never {
328332
/// Runs the given nonthrowing operation asynchronously
329333
/// as part of a new top-level task.
330334
///
331-
/// Don't use a detached task if it's possible
335+
/// Don't use a detached unstructured task if it's possible
332336
/// to model the operation using structured concurrency features like child tasks.
333337
/// Child tasks inherit the parent task's priority and task-local storage,
334338
/// and canceling a parent task automatically cancels all of its child tasks.
@@ -389,7 +393,7 @@ extension Task where Failure == Error {
389393
///
390394
/// If the operation throws an error, this method propagates that error.
391395
///
392-
/// Don't use a detached task if it's possible
396+
/// Don't use a detached unstructured task if it's possible
393397
/// to model the operation using structured concurrency features like child tasks.
394398
/// Child tasks inherit the parent task's priority and task-local storage,
395399
/// and canceling a parent task automatically cancels all of its child tasks.
Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2020 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import Swift
14+
15+
// ==== Task.init ------------------------------------------------
16+
17+
% for (METHOD_VARIANTS, ALL_AVAILABILITY, PARAMS) in [
18+
% (
19+
% [ # METHOD_VARIANT
20+
% '',
21+
% 'THROWING',
22+
% ],
23+
% [ # ALL_AVAILABILITY
24+
% '@_alwaysEmitIntoClient',
25+
% '@available(SwiftStdlib 5.1, *)',
26+
% ],
27+
% [ # PARAMS
28+
% 'name: String?',
29+
% 'priority: TaskPriority? = nil',
30+
% '@_inheritActorContext @_implicitSelfCapture operation: sending @escaping @isolated(any) () async throws -> Success',
31+
% ]),
32+
% # ====
33+
% (
34+
% [ # METHOD_VARIANT
35+
% 'DETACHED',
36+
% 'DETACHED THROWING',
37+
% ],
38+
% [
39+
% '@_alwaysEmitIntoClient',
40+
% '@available(SwiftStdlib 5.1, *)',
41+
% ],
42+
% [ # PARAMS
43+
% 'name: String?',
44+
% 'priority: TaskPriority? = nil',
45+
% 'operation: sending @escaping @isolated(any) () async throws -> Success',
46+
% ]),
47+
% ]:
48+
% for METHOD_VARIANT in METHOD_VARIANTS:
49+
50+
% IS_DETACHED = 'DETACHED' in METHOD_VARIANT
51+
% IS_THROWING = 'THROWING' in METHOD_VARIANT
52+
% if IS_THROWING:
53+
% FAILURE_TYPE = 'Error'
54+
% else:
55+
% FAILURE_TYPE = 'Never'
56+
% end
57+
58+
%
59+
% def adjust_params_for_kind(params):
60+
% res = []
61+
% for p in params:
62+
% np = p
63+
% if not IS_THROWING:
64+
% np = np.replace("throws", "")
65+
% res.append(np)
66+
% return res
67+
%
68+
%
69+
% HAS_TASK_PRIORITY = any('priority:' in param for param in PARAMS)
70+
% HAS_TASK_NAME = any('name:' in param for param in PARAMS)
71+
% HAS_TASK_EXECUTOR = any('taskExecutor:' in param for param in PARAMS)
72+
73+
% if IS_DETACHED:
74+
% ARROW_RETURN_TYPE = f'-> Task<Success, {FAILURE_TYPE}>'
75+
% else:
76+
% ARROW_RETURN_TYPE = '' # init does not spell out return type
77+
% end
78+
79+
% if IS_DETACHED:
80+
% THE_FUNC = 'public static func detached'
81+
% else:
82+
% THE_FUNC = 'public init'
83+
% end
84+
85+
% # ====================================================================================================================
86+
@available(SwiftStdlib 5.1, *)
87+
extension Task where Failure == ${FAILURE_TYPE} {
88+
89+
% # --------------------------------------------------------------------------------------------------------------------
90+
#if SWIFT_STDLIB_TASK_TO_THREAD_MODEL_CONCURRENCY
91+
@discardableResult
92+
@_alwaysEmitIntoClient
93+
@available(*, unavailable, message: "Unavailable in task-to-thread concurrency model")
94+
${THE_FUNC}(
95+
${",\n ".join(adjust_params_for_kind(PARAMS))}
96+
) ${ARROW_RETURN_TYPE}{
97+
fatalError("Unavailable in task-to-thread concurrency model.")
98+
}
99+
100+
% # --------------------------------------------------------------------------------------------------------------------
101+
#elseif $Embedded
102+
@discardableResult
103+
@_alwaysEmitIntoClient
104+
@available(SwiftStdlib 5.1, *)
105+
${THE_FUNC}(
106+
${",\n ".join(adjust_params_for_kind(PARAMS))}
107+
) ${ARROW_RETURN_TYPE}{
108+
// Set up the job flags for a new task.
109+
let flags = taskCreateFlags(
110+
priority: priority,
111+
isChildTask: false,
112+
copyTaskLocals: ${'true' if not IS_DETACHED else 'false /* detached */'},
113+
inheritContext: true,
114+
enqueueJob: true,
115+
addPendingGroupTaskUnconditionally: false,
116+
isDiscardingTask: false,
117+
isSynchronousStart: false)
118+
119+
// Create the asynchronous task.
120+
let (task, _) = Builtin.createAsyncTask(flags, operation)
121+
122+
self._task = task
123+
}
124+
125+
% # --------------------------------------------------------------------------------------------------------------------
126+
#else
127+
% if IS_THROWING:
128+
/// Runs the given throwing operation asynchronously
129+
% else:
130+
/// Runs the given nonthrowing operation asynchronously
131+
% end
132+
% if IS_DETACHED:
133+
/// as part of a new _unstructured_ _detached_ top-level task.
134+
% else:
135+
/// as part of a new _unstructured_ top-level task.
136+
% end
137+
///
138+
% if IS_THROWING:
139+
/// If the `operation` throws an error, it is caught by the `Task` and will be
140+
/// rethrown only when the task's `value` is awaited. Take care to not accidentally
141+
/// dismiss errors by not awaiting on the task's resulting value.
142+
% end
143+
///
144+
% if IS_DETACHED:
145+
/// Don't use a detached unstructured task if it's possible
146+
/// to model the operation using structured concurrency features like child tasks.
147+
/// Child tasks inherit the parent task's priority and task-local storage,
148+
/// and canceling a parent task automatically cancels all of its child tasks.
149+
/// You need to handle these considerations manually with a detached task.
150+
% end
151+
///
152+
/// You need to keep a reference to the task
153+
/// if you want to cancel it by calling the `Task.cancel()` method.
154+
/// Discarding your reference to a task
155+
/// doesn't implicitly cancel that task,
156+
/// it only makes it impossible for you to explicitly cancel the task.
157+
///
158+
/// - Parameters:
159+
% if HAS_TASK_NAME:
160+
/// - name: Human readable name of the task.
161+
% end
162+
% if HAS_TASK_NAME:
163+
/// - taskExecutor: the preferred task executor for this task,
164+
/// and any child tasks created by it. Explicitly passing `nil` is
165+
/// interpreted as "no preference".
166+
% end
167+
/// - priority: The priority of the task.
168+
/// - operation: The operation to perform.
169+
///
170+
/// - Returns: A reference to the task.
171+
${"\n ".join(ALL_AVAILABILITY)}
172+
@discardableResult
173+
${THE_FUNC}(
174+
${",\n ".join(adjust_params_for_kind(PARAMS))}
175+
) ${ARROW_RETURN_TYPE}{
176+
177+
// Set up the job flags for a new task.
178+
let flags = taskCreateFlags(
179+
priority: priority,
180+
isChildTask: false,
181+
copyTaskLocals: ${'true' if not IS_DETACHED else 'false'},
182+
inheritContext: false,
183+
enqueueJob: true,
184+
addPendingGroupTaskUnconditionally: false,
185+
isDiscardingTask: false,
186+
isSynchronousStart: false)
187+
188+
// Create the asynchronous task.
189+
let builtinSerialExecutor =
190+
unsafe Builtin.extractFunctionIsolation(operation)?.unownedExecutor.executor
191+
192+
var task: Builtin.NativeObject?
193+
#if $BuiltinCreateAsyncTaskName
194+
if let name {
195+
task =
196+
unsafe name.utf8CString.withUnsafeBufferPointer { nameBytes in
197+
Builtin.createTask(
198+
flags: flags,
199+
initialSerialExecutor: builtinSerialExecutor,
200+
taskName: nameBytes.baseAddress!._rawValue,
201+
operation: operation).0
202+
}
203+
}
204+
#endif
205+
if task == nil {
206+
// either no task name was set, or names are unsupported
207+
task = Builtin.createTask(
208+
flags: flags,
209+
initialSerialExecutor: builtinSerialExecutor,
210+
operation: operation).0
211+
}
212+
213+
% if IS_DETACHED:
214+
return Task(task!)
215+
% else:
216+
self._task = task!
217+
% end
218+
}
219+
220+
#endif
221+
} // extension Task ...
222+
223+
% end
224+
% end

0 commit comments

Comments
 (0)