Commit Graph
8 Commits
Author SHA1 Message Date
George Barnett 663ddc80f2 Dont hold lock over continuation in TokenBucket (#3455)
Motivation:

The various 'withMumbleContinuation' APIs are supposed to be invoked
synchronously with the caller. This assumption allows a lock to be
acquired before the call and released from the body of the
'withMumbleContinuation' after e.g. storing the continuation. However
this isn't the case and the job may be re-enqueued on the executor
meaning that this is pattern is vulnerable to deadlocks.

Modifications:

- Drop and reacquire the lock in TokenBucket.
- Switch to NIOLockedValueBox

Result:

Lower chance of deadlock
2025-12-01 15:46:46 +00:00
George Barnett cda536de37 Dont hold lock over continuation in NIOThrowingAsyncSequenceProducer (#3454)
Motivation:

The various 'withMumbleContinuation' APIs are supposed to be invoked
synchronously with the caller. This assumption allows a lock to be
acquired before the call and released from the body of the
'withMumbleContinuation' after e.g. storing the continuation. However
this isn't the case and the job may be re-enqueued on the executor
meaning that this is pattern is vulnerable to deadlocks.

Modifications:

- Drop and reacquire the lock in the NIOThrowingAsyncSequenceProducer.
- Merge 'next()' and 'next(for:)' methods in the state machine into a
single func; this reduces the amount of duplicated logic across the two
functions.

Result:

Lower chance of deadlock
2025-11-25 09:39:54 +00:00
George Barnett 5bf841dde5 Drop and reacquire lock over continuation call (#3452)
Motivation:

The various 'withMumbleContinuation' APIs are supposed to be invoked
synchronously with the caller. This assumption allows a lock to be
acquired before the call and released from the body of the
'withMumbleContinuation' after e.g. storing the continuation. However
this isn't the case and the job may be re-enqueued on the executor
meaning that this is pattern is vulnerable to deadlocks.

Modifications:

- Drop and reacquire the lock in the NIOAsyncWriter

Result:

Lower chance of deadlock
2025-11-24 11:13:50 +00:00
George BarnettandCory Benfield 664032bdd6 Wrap closures stored in the CallbackList (#3303)
Motivation:

The compiler is better at optimising closures wrapped in nominal types
than raw closures when used as generic parameters. CallbackList is used
a lot and stores an optional closure as well as on optional array of
closures. Wrapping these internally should save some allocations.

Modifications:

- Wrap the element stored in the `CallbackList`.

Result:

Fewer allocs

---------

Co-authored-by: Cory Benfield <lukasa@apple.com>
2025-07-14 16:48:26 +00:00
Fabian FettandCory Benfield c74c3bbabf [SelectableEventLoop] SR-15872; Save allocations when appending task (#2046)
* [SelectableEventLoop] SR-15872; Save allocations when appending task

* Add pr to workaround list

* Update alloc counters

* Update alloc script to include 5.6

* Update alloc counters

Co-authored-by: Cory Benfield <lukasa@apple.com>
2022-02-17 12:18:21 -08:00
Cory BenfieldandGeorge Barnett 06cb3dd096 Update workarounds list with our recent ones (#1962)
Co-authored-by: George Barnett <gbarnett@apple.com>
2021-09-27 09:48:39 +01:00
Johannes Weiss a305518d88 implement CircularBuffer.first: to prevent allocs (#1814)
Motivation:

Due to https://bugs.swift.org/browse/SR-14516 , we sometimes get
allocating (!?) `subscript.read` accessors in the CircularBuffer.first
depending on the `Element` type...

Modifications:

Implement `CircularBuffer.first` instead of inheriting it from
Collection.

Result:

Fewer allocs in some cases.
2021-04-22 13:34:14 +01:00
George Barnett b4483e5c49 Avoid curried thunks (workaround SR-12115) (#1374)
Motivation:

Calling `function(otherFunction)` allocates, but
`function({ otherFunction($0) }` does not.

See: SR-12115 and SR-12116.

Modifications:

Avoid passing functions directly; pass them in new closures instead.

Result:

Fewer allocations.
2020-01-31 17:57:30 +00:00