released memory.
Because the waitAll() group method is called before the group returns
from withTaskGroup and is used to ensure all tasks have completed before
we destroy the task group, this method is then immediately followed by
calling TaskGroup::destroy.
If we, as previously, first resume the waiting task and then attempt to
unlock the lock held by the group, we are in an unsafe situation with
racing the task group destroy() and the unlock().
Therefore, we must release the lock before we resume the waiting task.
# Motivation
For AsyncStream we created a custom internal Deque implementation to use for the buffering. This implementation was relatively bare-bones compared to the one in swift-collections. Furthermore, it lacked some methods that we need to implement the new `AsyncStream` APIs that support producer backpressure.
# Modification
This PR copies over the Deque implementation of swift-collections and makes it internal and non-inlinable.
# Result
We now have a fully functional Deque.
withTaskCancellationHandler gets called with the task status record lock held, so care needs to be taken if the cancellation handler acquires any locks of its own. Update the docs comment to describe this.
rdar://111686260
As of CMake 3.25, there are now global variables `LINUX=1`, `ANDROID=1`,
etc. These conflict with expressions that used these names as unquoted
strings in positions where CMake accepts 'variable|string', for example:
- `if(sdk STREQUAL LINUX)` would fail, because `LINUX` is now defined and
expands to 1, where it would previously coerce to a string.
- `if(${sdk} STREQUAL "LINUX")` would fail if `sdk=LINUX`, because the
left-hand side expands twice.
In this patch, I looked for a number of patterns to fix up, sometimes a
little defensively:
- Quoted right-hand side of `STREQUAL` where I was confident it was
intended to be a string literal.
- Removed manual variable expansion on left-hand side of `STREQUAL`,
`MATCHES` and `IN_LIST` where I was confident it was unintended.
Fixes#65028.
* Use the longer name ThreadSanitizer rather than TSan for the new files.
* Don't implement `tsan::consume` at all for now.
* Do the `tsan::release` for `ulock_unlock()` at the head of the function,
not at the tail.
* Add a comment to test/Sanitizers/tsan/once.swift to explain the test a
little more clearly.
rdar://110665213
Move the TSan functionality from Concurrency into Threading. Use it
in the Linux `ulock` implementation so that TSan knows about `ulock`
and will tolerate the newer `swift_once` implementation that uses it.
rdar://110665213
Since https://github.com/apple/swift/pull/65613, DiscardingTG started to
accept `() -> Void` instead of `() -> T`, but it also changed the number
of arguments accepted by the closure from 3 to 2. So it should use
`non_future_adapter` instead of `future_adapter` to avoid runtime signature
mismatch.
Have the Concurrency runtime register a struct containing pointers to all of its type descriptors with standard manglings. Then have the runtime use that struct to quickly look up those types, instead of using the standard, slower type lookup code.
rdar://109783861
Once we have transitioned the actor into a new state, we report the
state change as a trace event so it can be noted by tools (e.g.,
Instruments). However, the act of transitioning to a new state can mean
that there is an opportunity for another thread to deallocate the
actor. This means that the tracing call cannot depend on dereferencing
the actor pointer.
A refactoring a few months ago to move the bit that indicates when a
distributed actor is remote from inside the atomic actor state out to a
separate field (because it's constant for a given actor instance),
which introduced a dereference of the actor instance in forming the
tracing call. This introduced a narrow window in which a race
condition could occur: the actor transitions to an idle state, and is
then deallocate before the trace event for the actor transition occurs,
leading to a use-after-free.
Fetch this bit of information earlier in the process, before any state
changes and when we know the actor is still allocated, and pass it
through to the tracing code.
Fixes rdar://108497870.
All compilers that must be able to compile the standard library's textual
interface accept the following:
- back deployed functions declared without `@available`
- `@inlinable` back deployed functions
- `defer` blocks in back deployed functions
We can therefore revert the workarounds added in
https://github.com/apple/swift/pull/62946/ and
https://github.com/apple/swift/pull/62928/.
Resolves rdar://104085810
Discarding task groups aren't available in the 5.8-aligned OS's,
resulting in a loader error at launch if you try to use them.
Bumping the availability attributes to 5.9 on everything in
DiscardingTaskGroup.swift
These metatypes are a gateway to more incorrect
uses of these noncopyable values because we don't
yet have the corresponding runtime support yet.
The other use cases of using metatypes of
noncopyable types in generics is not high enough to
warrant people using them yet.
resolves rdar://106452518
Revert a few unnecessary changes have been made to the _Concurrency module
recently that make its swiftinterface un-parseable by older compilers that we
need to support.
- The `consume` keyword is not understood by older compilers, so including it
in inlinable code is a problem. It has no actual effect on lifetimes where it
was used, so just omit it.
- Don't build the _Concurrency module with -enable-experimental-feature
MoveOnly. The MoveOnly feature is now enabled by default in recent compilers,
so the flag is superfluous when building the dylib. When emitting the
interface, having the feature enabled explicitly exposes code guarded by
`$MoveOnly` to older compilers that do not accept all of the code.
Resolves rdar://108793606
Because `_taskLocalValuePush` and `_taskLocalValuePop` can result in calls
to `swift_task_alloc` and `swift_task_dealloc` respectively, and because
the compiler hasn't been taught about that (e.g.
`SILInstruction::isAllocatingStack`,
`SILInstruction::isDeallocatingStack`, etc), calling them (push and pop)
from a function which makes use the stack for dynamically sized
allocations can result in violations of stack discipline of the form
```
swift_task_alloc // allocates %ptr_1
copy_value_witness // copies into %ptr_1
swift_task_localValuePush // calls swift_task_alloc and allocates %ptr_2
swift_task_dealloc // deallocates %ptr_1
swift_task_localValuePop // calls swift_task_dealloc and deallocates %ptr_2
```
Avoid the problem by not allocating dynamically sized stack space in the
function which calls `_taskLocalValuePush` and `_taskLocalValuePop`.
Split the calls to those functions into `withValueImpl` function which
takes its argument `__owned`. Call that function from `withValue`,
ensuring that the necessary copy (to account for the fact that withValue
takes its argument `__guaranteed` but `_taskLocalValuePush` takes its
`__owned`) and associated stack traffic occur in `withValue`.
Still, allow `withValueImpl` to be inlined. The stack nesting will be
preserved across it.
rdar://107275872