Skip to content

Commit bf5ef5a

Browse files
committed
undo any changes in backdeploy lib, we don't do any changes there
1 parent 6f33f2a commit bf5ef5a

File tree

3 files changed

+106
-53
lines changed

3 files changed

+106
-53
lines changed

stdlib/public/BackDeployConcurrency/TaskGroup.cpp

Lines changed: 21 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,12 @@ class TaskGroupImpl: public TaskGroupTaskStatusRecord {
114114
/// until a next() call eventually picks it up.
115115
AsyncTask *retainedTask;
116116

117+
bool isStorageAccessible() {
118+
return status == PollStatus::Success ||
119+
status == PollStatus::Error ||
120+
status == PollStatus::Empty;
121+
}
122+
117123
static PollResult get(AsyncTask *asyncTask, bool hadErrorResult) {
118124
auto fragment = asyncTask->futureFragment();
119125
return PollResult{
@@ -127,15 +133,6 @@ class TaskGroupImpl: public TaskGroupTaskStatusRecord {
127133
/*task*/ asyncTask
128134
};
129135
}
130-
131-
static PollResult getEmpty(const Metadata *successType) {
132-
return PollResult{
133-
/*status*/ PollStatus::Success,
134-
/*storage*/ nullptr,
135-
/*successType*/successType,
136-
/*task*/ nullptr
137-
};
138-
}
139136
};
140137

141138
/// An item within the message queue of a group.
@@ -429,17 +426,6 @@ class TaskGroupImpl: public TaskGroupTaskStatusRecord {
429426
/// or a `PollStatus::MustWait` result if there are tasks in flight
430427
/// and the waitingTask eventually be woken up by a completion.
431428
PollResult poll(AsyncTask *waitingTask);
432-
433-
/// A `discardResults` TaskGroup is not able to wait on individual completions,
434-
/// instead, it can only await on "all pending tasks have been processed".
435-
///
436-
///
437-
/// If unable to complete the waiting task immediately (with an readily
438-
/// available completed task), either returns an `PollStatus::Empty`
439-
/// result if it is known that no pending tasks in the group,
440-
/// or a `PollStatus::MustWait` result if there are tasks in flight
441-
/// and the waitingTask eventually be woken up by a completion.
442-
PollResult waitAll(AsyncTask *waitingTask);
443429
};
444430

445431
} // end anonymous namespace
@@ -474,7 +460,7 @@ TaskGroupTaskStatusRecord *TaskGroup::getTaskRecord() {
474460

475461
// Initializes into the preallocated _group an actual TaskGroupImpl.
476462
SWIFT_CC(swift)
477-
static void swift_taskGroup_initializeWithFlagsImpl(size_t flags, TaskGroup *group, const Metadata *T) {
463+
static void swift_taskGroup_initializeImpl(TaskGroup *group, const Metadata *T) {
478464
SWIFT_TASK_DEBUG_LOG("creating task group = %p", group);
479465

480466
TaskGroupImpl *impl = new (group) TaskGroupImpl(T);
@@ -489,12 +475,6 @@ static void swift_taskGroup_initializeWithFlagsImpl(size_t flags, TaskGroup *gro
489475
if (!notCancelled) impl->statusCancel();
490476
}
491477

492-
// Initializes into the preallocated _group an actual TaskGroupImpl.
493-
SWIFT_CC(swift)
494-
static void swift_taskGroup_initializeImpl(TaskGroup *group, const Metadata *T) {
495-
swift_taskGroup_initializeWithFlagsImpl(0, group, T);
496-
}
497-
498478
// =============================================================================
499479
// ==== add / attachChild ------------------------------------------------------
500480

@@ -566,7 +546,7 @@ static void fillGroupNextResult(TaskFutureWaitAsyncContext *context,
566546
}
567547

568548
case PollStatus::Empty: {
569-
// Initialize the result as a .none Optional<Success>.
549+
// Initialize the result as a nil Optional<Success>.
570550
const Metadata *successType = result.successType;
571551
OpaqueValue *destPtr = context->successResultPointer;
572552
successType->vw_storeEnumTagSinglePayload(destPtr, 1, 1);
@@ -575,13 +555,6 @@ static void fillGroupNextResult(TaskFutureWaitAsyncContext *context,
575555
}
576556
}
577557

578-
static void fillGroupNextNilResult(TaskFutureWaitAsyncContext *context) {
579-
/// Fill in the result value with 'nil'
580-
const Metadata *successType = result.successType;
581-
OpaqueValue *destPtr = context->successResultPointer;
582-
successType->vw_storeEnumTagSinglePayload(destPtr, 1, 1);
583-
}
584-
585558
void TaskGroupImpl::offer(AsyncTask *completedTask, AsyncContext *context) {
586559
assert(completedTask);
587560
assert(completedTask->isFuture());
@@ -598,7 +571,6 @@ void TaskGroupImpl::offer(AsyncTask *completedTask, AsyncContext *context) {
598571
// W:n R:0 P:1 -> W:y R:1 P:1 // complete immediately
599572
// W:n R:0 P:1 -> W:y R:1 P:3 // complete immediately, 2 more pending tasks
600573
auto assumed = statusAddReadyAssumeAcquire();
601-
SWIFT_TASK_DEBUG_LOG("offer task %p to group(%p), tasks pending = %d", completedTask, assumed.pendingTasks());
602574

603575
auto asyncContextPrefix = reinterpret_cast<FutureAsyncContextPrefix *>(
604576
reinterpret_cast<char *>(context) - sizeof(FutureAsyncContextPrefix));
@@ -668,7 +640,6 @@ void TaskGroupImpl::offer(AsyncTask *completedTask, AsyncContext *context) {
668640
assert(completedTask == readyItem.getTask());
669641
assert(readyItem.getTask()->isFuture());
670642
readyQueue.enqueue(readyItem);
671-
672643
mutex.unlock(); // TODO: remove fragment lock, and use status for synchronization
673644
return;
674645
}
@@ -713,20 +684,20 @@ static void swift_taskGroup_wait_next_throwingImpl(
713684
waitingTask->ResumeTask = task_group_wait_resume_adapter;
714685
waitingTask->ResumeContext = rawContext;
715686

716-
auto group = asImpl(_group);
717-
assert(group && "swift_taskGroup_wait_next_throwing was passed context without group!");
718-
719687
auto context = static_cast<TaskFutureWaitAsyncContext *>(rawContext);
720688
context->ResumeParent =
721689
reinterpret_cast<TaskContinuationFunction *>(resumeFunction);
722690
context->Parent = callerContext;
723691
context->errorResult = nullptr;
724692
context->successResultPointer = resultPointer;
725693

694+
auto group = asImpl(_group);
695+
assert(group && "swift_taskGroup_wait_next_throwing was passed context without group!");
696+
726697
PollResult polled = group->poll(waitingTask);
727698
switch (polled.status) {
728699
case PollStatus::MustWait:
729-
SWIFT_TASK_DEBUG_LOG("poll group = %p, tasks ready = 0, waiting task = %p",
700+
SWIFT_TASK_DEBUG_LOG("poll group = %p, no ready tasks, waiting task = %p",
730701
group, waitingTask);
731702
// The waiting task has been queued on the channel,
732703
// there were pending tasks so it will be woken up eventually.
@@ -746,8 +717,8 @@ static void swift_taskGroup_wait_next_throwingImpl(
746717

747718
if (auto completedTask = polled.retainedTask) {
748719
// it would be null for PollStatus::Empty, then we don't need to release
749-
group->detachChild(completedTask);
750-
swift_release(completedTask);
720+
group->detachChild(polled.retainedTask);
721+
swift_release(polled.retainedTask);
751722
}
752723
return waitingTask->runInFullyEstablishedContext();
753724
}
@@ -783,13 +754,13 @@ PollResult TaskGroupImpl::poll(AsyncTask *waitingTask) {
783754

784755
// ==== 2) Ready task was polled, return with it immediately -----------------
785756
if (assumed.readyTasks()) {
786-
SWIFT_TASK_DEBUG_LOG("poll group = %p, tasks ready=%d, pending=%d",
787-
this, assumed.readyTasks(), assumed.pendingTasks());
757+
SWIFT_TASK_DEBUG_LOG("poll group = %p, group has ready tasks = %d",
758+
this, assumed.readyTasks());
788759

789760
auto assumedStatus = assumed.status;
790761
auto newStatus = TaskGroupImpl::GroupStatus{assumedStatus};
791762
if (status.compare_exchange_strong(
792-
assumedStatus, newStatus.completingPendingReadyWaiting(this).status,
763+
assumedStatus, newStatus.completingPendingReadyWaiting().status,
793764
/*success*/ std::memory_order_relaxed,
794765
/*failure*/ std::memory_order_acquire)) {
795766

@@ -846,7 +817,7 @@ PollResult TaskGroupImpl::poll(AsyncTask *waitingTask) {
846817
}
847818

848819
// ==== 3) Add to wait queue -------------------------------------------------
849-
assert(assumed.readyTasks(this) == 0);
820+
assert(assumed.readyTasks() == 0);
850821
_swift_tsan_release(static_cast<Job *>(waitingTask));
851822
while (true) {
852823
if (!hasSuspended) {
@@ -868,13 +839,15 @@ PollResult TaskGroupImpl::poll(AsyncTask *waitingTask) {
868839
}
869840

870841
// =============================================================================
871-
// ==== Task Group status and flag checks -------------------------------------
842+
// ==== isEmpty ----------------------------------------------------------------
872843

873844
SWIFT_CC(swift)
874845
static bool swift_taskGroup_isEmptyImpl(TaskGroup *group) {
875846
return asImpl(group)->isEmpty();
876847
}
877848

849+
// =============================================================================
850+
// ==== isCancelled ------------------------------------------------------------
878851
SWIFT_CC(swift)
879852
static bool swift_taskGroup_isCancelledImpl(TaskGroup *group) {
880853
return asImpl(group)->isCancelled();

test/Concurrency/Runtime/async_task_locals_prevent_illegal_use.swift renamed to test/Concurrency/Runtime/async_task_locals_prevent_illegal_use_discarding_taskgroup.swift

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,29 @@ enum TL {
1919

2020
// ==== ------------------------------------------------------------------------
2121

22-
@available(SwiftStdlib 5.1, *)
23-
func bindAroundGroupSpawn() async {
22+
func bindAroundGroupAddTask() async {
2423
await TL.$number.withValue(1111) { // ok
2524
await withTaskGroup(of: Int.self) { group in
2625
// CHECK: error: task-local: detected illegal task-local value binding at {{.*}}illegal_use.swift:[[# @LINE + 1]]
2726
TL.$number.withValue(2222) { // bad!
2827
print("Survived, inside withValue!") // CHECK-NOT: Survived, inside withValue!
29-
group.spawn {
28+
group.addTask {
29+
0 // don't actually perform the read, it would be unsafe.
30+
}
31+
}
32+
33+
print("Survived the illegal call!") // CHECK-NOT: Survived the illegal call!
34+
}
35+
}
36+
}
37+
38+
func bindAroundDiscardingGroupAddTask() async {
39+
await TL.$number.withValue(1111) { // ok
40+
await withDiscardingTaskGroup(of: Int.self) { group in
41+
// CHECK: error: task-local: detected illegal task-local value binding at {{.*}}illegal_use.swift:[[# @LINE + 1]]
42+
TL.$number.withValue(2222) { // bad!
43+
print("Survived, inside withValue!") // CHECK-NOT: Survived, inside withValue!
44+
group.addTask {
3045
0 // don't actually perform the read, it would be unsafe.
3146
}
3247
}
@@ -36,9 +51,12 @@ func bindAroundGroupSpawn() async {
3651
}
3752
}
3853

39-
@available(SwiftStdlib 5.1, *)
4054
@main struct Main {
4155
static func main() async {
42-
await bindAroundGroupSpawn()
56+
if CommandLine.arguments.contains("discarding-task-group") {
57+
await bindAroundGroupAddTask()
58+
} else {
59+
await bindAroundDiscardingGroupAddTask()
60+
}
4361
}
4462
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// RUN: %target-fail-simple-swift( -Xfrontend -disable-availability-checking -parse-as-library %import-libdispatch) 2>&1 | %FileCheck %s
2+
//
3+
// // TODO: could not figure out how to use 'not --crash' it never is used with target-run-simple-swift
4+
// This test is intended to *crash*, so we're using target-fail-simple-swift
5+
// which expects the exit code of the program to be non-zero;
6+
// We then check stderr for the expected error message using filecheck as usual.
7+
8+
// REQUIRES: executable_test
9+
// REQUIRES: concurrency
10+
// REQUIRES: libdispatch
11+
// REQUIRES: concurrency_runtime
12+
// UNSUPPORTED: back_deployment_runtime
13+
14+
@available(SwiftStdlib 5.1, *)
15+
enum TL {
16+
@TaskLocal
17+
static var number: Int = 2
18+
}
19+
20+
// ==== ------------------------------------------------------------------------
21+
22+
func bindAroundGroupAddTask() async {
23+
await TL.$number.withValue(1111) { // ok
24+
await withTaskGroup(of: Int.self) { group in
25+
// CHECK: error: task-local: detected illegal task-local value binding at {{.*}}illegal_use.swift:[[# @LINE + 1]]
26+
TL.$number.withValue(2222) { // bad!
27+
print("Survived, inside withValue!") // CHECK-NOT: Survived, inside withValue!
28+
group.addTask {
29+
0 // don't actually perform the read, it would be unsafe.
30+
}
31+
}
32+
33+
print("Survived the illegal call!") // CHECK-NOT: Survived the illegal call!
34+
}
35+
}
36+
}
37+
38+
func bindAroundDiscardingGroupAddTask() async {
39+
await TL.$number.withValue(1111) { // ok
40+
await withDiscardingTaskGroup(of: Int.self) { group in
41+
// CHECK: error: task-local: detected illegal task-local value binding at {{.*}}illegal_use.swift:[[# @LINE + 1]]
42+
TL.$number.withValue(2222) { // bad!
43+
print("Survived, inside withValue!") // CHECK-NOT: Survived, inside withValue!
44+
group.addTask {
45+
0 // don't actually perform the read, it would be unsafe.
46+
}
47+
}
48+
49+
print("Survived the illegal call!") // CHECK-NOT: Survived the illegal call!
50+
}
51+
}
52+
}
53+
54+
@main struct Main {
55+
static func main() async {
56+
if CommandLine.arguments.contains("discarding-task-group") {
57+
await bindAroundGroupAddTask()
58+
} else {
59+
await bindAroundDiscardingGroupAddTask()
60+
}
61+
}
62+
}

0 commit comments

Comments
 (0)