Files
swift-mirror/lib/SILGen/ExecutorBreadcrumb.h
Kavon Farvardin 814fb42554 fix nested suspension issue with objc async calls
when two objc async functions are composed with each other,
i.e., f(g()), then the clean-ups for g() would get emitted
at an unexpected time, namely, during the suspension for
the call to f(). This means that using a clean-up to emit
the executor-hop breadcrumb was incorrect. The hop could
appear between a get_async continuation and its matching
await_continuation, which is an unsupported nested suspension.

This commit fixes that by removing the use of the breadcrumb
clean-up in favor of providing that breadcrumb directly to
the result plan, so that it may be emitted later on when the
result plan sees fit.

Fixes rdar://91502776
2022-05-02 18:20:59 -07:00

54 lines
1.6 KiB
C++

//===--- ExecutorBreadcrumb.h - executor hop tracking for SILGen ----------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_SILGEN_EXECUTORBREADCRUMB_H
#define SWIFT_SILGEN_EXECUTORBREADCRUMB_H
#include "swift/SIL/SILValue.h"
namespace swift {
class SILLocation;
namespace Lowering {
class SILGenFunction;
/// Represents the information necessary to return to a caller's own
/// active executor after making a hop to an actor for actor-isolated calls.
class ExecutorBreadcrumb {
bool mustReturnToExecutor;
public:
// An empty breadcrumb, indicating no hop back is necessary.
ExecutorBreadcrumb() : mustReturnToExecutor(false) {}
// A breadcrumb representing the need to hop back to the expected
// executor of the current function.
explicit ExecutorBreadcrumb(bool mustReturnToExecutor)
: mustReturnToExecutor(mustReturnToExecutor) {}
// Emits the hop back sequence, if any, necessary to get back to
// the executor represented by this breadcrumb.
void emit(SILGenFunction &SGF, SILLocation loc);
#ifndef NDEBUG
// FOR ASSERTS ONLY: returns true if calling `emit` will emit a hop-back.
bool needsEmit() const { return mustReturnToExecutor; }
#endif
};
} // namespace Lowering
} // namespace swift
#endif