Tags: apple/swift-nio
Tags
Retain a ref to NIOAsyncWriter until channel active (#2703) Motivation: NIOAsyncChannel requires users to explicitly close it, this is typically done by calling `executeThenClose`. If a `NIOAsyncChannel` isn't closed then its outbound writer will hit a precondition failure on `deinit`. Not calling `executeThenClose` is a programmer error. However there are some sharp edges: if NIO never returns the `NIOAsyncChannel` to the caller (e.g. if a connect attempt fails) then nothing will finish the writer and precondition will fail in the deinit. Working around this from a user perspective is non-obvious and requires keep tracking of all `NIOAsyncChannel`s created from a connect attempt and closing the unused ones. We still want to maintain the precondition when users don't close the channel, one way of achieving this is by defining a point in time at which NIO hands responsibility of the channel to the user. Modifications: - Retain the writer in the outbound writer handler until channel active - On successful connect attempts, the channel becomes active and the connected channel is returned to the caller. - On failed attempts channel active isn't called so the writer is retained until the handler is removed from the pipeline at which point it is finished. Result: Failed connect attempts don't result in precondition failures when using NIOAsyncChannel.
Fix memory allocations counters on macOS. (#2673) Motivation: Allocation counters are broken on macOS as described [here](#2672). This PR fixes it. Modifications: `AtomicCounter` library is made `.dynamic`. This deduplicates the two (static) copies that used to exist. One embedded in the main binary, and the other in `HookedFunctions` dylib. This deplication fixes the issue, because there is just one copy of the counters in the process address space. Result: All the tests counting allocations and related statistics work on macOS.
use feature-specific guard for @retroactive (#2581) Motivation: We should use the more granular guard for uses of @retroactive rather than coarse swift versions to guard against corner-cases Modifications: Switch `#if compiler(>=5.11)` for `#if hasFeature(RetroactiveAttribute)` Result: No change in most cases, more protected against corner-cases.
Fix exclusive access violation in `NIOAsyncChannelOutboundWriterHandl… …er` (#2580) # Motivation We were setting `self.sink = nil` in the `NIOAsyncChannelOutboundWriterHandler` twice in the same call stack which is an exclusivity violation. This happens because the first `self.sink = nil` triggers the `didTerminate` delegate call which again triggered `self.sink = nil`. # Modification This PR changes the code to only call `self.sink?.finish()` and only sets the `sink` to `nil` in the `didTerminate` implementation. This follows what we do for the inbound handler implementation. I also added a test that triggers this exclusivity violation. # Result No more exclusivity violations in our code.
Fix thread-safety issues in TCPThroughputBenchmark (#2537) Motivation: Several thread-safety issues were missed in code review. This patch fixes them. Modifications: - Removed the use of an unstructured Task, replaced with eventLoop.execute to ServerHandler's EventLoop. - Stopped ClientHandler reaching into the benchmark object without any synchronization, used promises and event loop hops instead. Result: Thread safety is back
Support for custom protocols in DatagramBootstrap (#2516) Motivation This patch adds support for custom protocol families to DatagramBootstrap. In most cases this isn't useful, and will fail, but in many OSes it's a recognised system for non-root processes to get a way to send ICMP echo requests. This is worth supporting. Modifications - Expose the `ProtocolSubtype` type publicly. - Add a `protocolSubtype` setter on `DatagramBootstrap` - Write a test that actually does ICMP as non-root Results Users can send ICMP echo requests without root privileges.
Avoid using deinit to fulfil the protocol negotiation promise (#2497) # Motivation Fixes #2494 # Modification This PR avoids using `deinit` to fulfil the protocol negotiation promise and opts to trap instead when it is being accessed before the handler is added. This allows us to use `handlerAdded` and `handlerRemoved`. # Result No more `deinit` usage that can be observed.
PreviousNext