Commit Graph

2169 Commits

Author SHA1 Message Date
George Barnett e208367c8e
Allow UDP GRO tests to fail in some circumstances (#2387)
Motivation:

The recently added UDP GRO tests fail on some older Linux Kernel
versions. We believe that UDP GRO support on loopback was limited in
early versions so we should tolerate those failures.

However, we've verified that on 5.15 and newer that GRO is supported so
we should not tolerate failure in those cases.

Modifications:

- Add shims to CNIOLinux to get system info via uname
- Verify GRO works before running GRO tests and if it doesn't then
  validate the kernel version isn't greater than 5.15.

Results:

Less flaky tests.
2023-03-13 11:12:06 +00:00
ser 8193940b9a
Buffer pool for message headers and addresses. (#2378)
* Pool buffers for messages and addresses.

* Revert changes related to controlMessageStorage

* Cosmetic fix.

---------

Co-authored-by: Cory Benfield <lukasa@apple.com>
2023-03-10 16:06:02 +00:00
Franz Busch ef7dc666e8
Rework the `NIOAsyncSequenceProducer` tests to rely less on timings (#2386) 2023-03-07 17:28:34 +00:00
George Barnett d1fa3e29bf
Add support for UDP_GRO (#2385)
Motivation:

Support was added for UDP_SEGMENT in #2372 which allows for large UDP
datagrams to be written to a socket by letting the kernel or NIC segment
the data across multiple datagrams. This reduces traversals across the
network stack which can lead to performance improvements. UDP_GRO is the
receive-side counterpart allowing the kernel/NIC to aggregate datagrams
and reduce network stack traversals.

Modifications:

- Add a function in CNIOLinux to check whether UDP_GRO is supported
- Add the relevant socket and channel options
- Add tests

Result:

- UDP_GRO can be enabled where supported and applications may receive
  large buffers.
2023-03-06 07:12:09 -08:00
Rick Newton-Rogers 5f5fa9a2b2
mark syncShutdownGracefully noasync (#2381)
mark syncShutdownGracefully noasync

Motivation:

The code as-is blocks the calling thread.

Modifications:

* mark `EventLoopGroup.syncShutdownGracefully()` and `NIOThreadPool.syncShutdownGracefully()` noasync on Swift > 5.7
* offer NIOThreadPool.shutdownGracefully()
* add renamed to syncShutdownGracefully()
2023-03-02 06:20:23 -08:00
George Barnett e81bd62fb6
Remove redundant availability guard (#2379)
Motivation:

EventLoopTest has an availability annotation for the various Darwin
platforms. This availability check is repeated in a few tests which
yields warnings.

Modifications:

Remove the class level availability guard.

Result:

Warning free.

Co-authored-by: Cory Benfield <lukasa@apple.com>
2023-03-02 03:25:38 -08:00
George Barnett e2f161ba00
Rebuild the channel when retrying testWriteBufferAtGSOSegmentCountLimit (#2383)
Motivation:

I (foolishly) didn't validate the test fix in #2382, instead I validated
that the original test passed with 61 segments (rather than 64). The
channel needs to be recreated first.

Modifications:

- Rebuild the channel before trying again if 64 segments is too many.

Result:

Test passes.
2023-03-02 02:18:54 -08:00
George Barnett ec6b8ed8c3
Lower the max segment count in tests (#2382)
Motivation:

On older kernel versions testWriteBufferAtGSOSegmentCountLimit fails
because the write fails with EINVAL. This appears to be a kernel bug as
it passes on more recent versions.

Modifications:

- Try again with a lower segment limit if the write fails with EINVAL.

Result:

Less flaky test.
2023-03-01 06:00:24 -08:00
ser 652e01c003
Fix memory binding. (#2376)
* Fix memory binding.

* Cosmetic fix.
2023-03-01 03:54:42 -08:00
Andrew Trick e63326aa50
Fix an upcoming compiler warning on implicit raw pointer casts. (#2377)
setOption forms a raw pointer to a generic argument. The compiler will
warn on this as of:

[proposal] Constrain implicit raw pointer conversion... #1963
https://github.com/apple/swift-evolution/pull/1963

/Sources/NIOPosix/BaseSocket.swift:286:31: warning: forming
'UnsafeRawPointer' to a variable of type 'T'; this is likely incorrect
because 'T' may contain an object reference.

                option_value: &val,
                              ^

Ideally, this would be fixed by adding a BitwiseCopyable constraint to
the 'value' parameter of 'BaseSocker.setOption'. That would not only
eliminate the warning, but would make the API safer. But
BitwiseCopyable isn't quite ready for public use. In the meantime,
this is a reasonable workaround.

Co-authored-by: Cory Benfield <lukasa@apple.com>
2023-02-28 00:23:36 -08:00
Johannes Weiss a296f30e45
OnLoopSendable: Sendable containers if on EventLoop (#2370)
Co-authored-by: Cory Benfield <lukasa@apple.com>
2023-02-27 07:11:37 -08:00
George Barnett 19b878f461
Add support for UDP_SEGMENT (#2372)
Motivation:

On Linux, the UDP_SEGMENT socket option allows for large buffers to be
written to the kernel and segmented by the kernel (or in some cases the
NIC) into smaller datagrams. This can substantially decrease the number
of syscalls.

This can be set on a per message basis on a per socket basis. This
change adds per socket configuration.

Modifications:

- Add a CNIOLinux function to check whether UDP_SEGMENT is supported on
  that particular Linux.
- Add a helper to `System` to check whether UDP_SEGMENT is supported on
  the current platform.
- On Linux only:
  - add the udp socket option level
  - add the udp_segment socket option
- Add the `DatagramSegmentSize` channel option.
- Get/Set the option in `DatagramChannel`

Results:

UDP GSO is supported on Linux.

Co-authored-by: Cory Benfield <lukasa@apple.com>
2023-02-27 13:18:58 +00:00
carolinacass 81e5d344e4
Not Holding OnToRunClosure() test updates (#2375)
Motivation:
swift- nio was failing builds that should pass

Modifications:
Adding available to the necessary sections

* Updating test OnToRunClosure

Motivation:
testCancelledScheduledTasksDoNotHoldOnToRunClosure() was not allowed enough time and timing off at moments, causing it to fail occasionally

Modifications:
Added a ConditionLock throughout the code to make sure it only unlocks when the code has waited enough time for it to not hit the precondition failure
2023-02-23 11:03:03 +00:00
Cory Benfield 108d4646a9
Make our time types transparent (#2374)
Motivation:

Our time types are trivial, and they should be fully transparent. This
produces minor performance improvements in code handling time types, but
is mostly useful in terms of allowing the compiler to observe that these
functions have no side effects, thereby eliding some ARC traffic.

Modifications:

Make our time types inlinable.

Result:

Better performance.
2023-02-21 13:06:06 +00:00
George Barnett 4dfae01cc6
Add a pooled recv buffer allocator (#2362)
Motivation:

Channels can read `ChannelOptions.maxMessagesPerRead` times from a
socket in each read cycle. They typically re-use the same buffer for
each read and rely on it CoWing if necessary. If we read more than once
in a cycle then we may CoW the buffer. Instead of reusing one buffer we
can reuse a pool of buffers limited by `maxMessagesPerRead` and cycle
through each, reducing the chance of CoWing the buffers.

Modifications:

- Extend `RecvByteBufferAllocator` to provide the size of the next
  buffer with a default implementation returning `nil`.
- Add an recv buffer pool which lazily grows up to a fixed size and
  attempts to reuse buffers where possible if doing so avoids CoWing.

Results:

Fewer allocations
2023-02-20 17:00:19 +00:00
Cory Benfield 9afaf801e5
Don't retain a task when all we want is a time (#2373)
Motivation:

To know when we next need to wake up, we keep track of what the next
deadline will be. This works great, but in order to keep track of this
UInt64 we save off an entire ScheduledTask. This object is quite wide (6
pointers wide), and two of those pointers require ARC traffic, so doing
this saving produces unnecessary overhead.

Worse, saving this task plays poorly with task cancellation. If the
saved task is cancelled, this has the effect of "retaining" that task
until the next event loop tick. This is unlikely to produce catastrophic
bugs in real programs, where the loop does tick, but it violates our
tests which rigorously assume that we will always drop a task when it is
cancelled. In specific manufactured cases it's possible to produce leaks
of non-trivial duration.

Modifications:

- Wrote a weirdly complex test.
- Moved the implementation of Task.readyIn to a method on NIODeadline
- Saved a NIODeadline instead of a ScheduledTask

Result:

Minor performance improvement in the core event loop processing, minor
correctness improvement.
2023-02-20 07:27:58 -08:00
carolinacass 5db1dfabb0
Building swift-nio with Swift 5.7 for iOS using Xcode 14.0 at 2.48.0. (#2369)
Motivation:
swift- nio was failing builds that should pass

Modifications:
Adding available to the necessary sections
2023-02-17 10:05:43 -08:00
George Barnett 734a0ba103
Add availability requirements to TCPThroughputBenchmark (#2368)
Motivation:

- Uses Concurrency but missing availability requirements; does not build
  on macOS.

Modifications:

- Add availability requirements/guards

Result:

Compiles on macOS
2023-02-16 11:55:14 +00:00
ser ab43dc6949
TCP channel throughput benchmark. (#2367)
* TCP channel throughput benchmark.

* Cosmetic fixes.

* Add license to the source code.
2023-02-15 16:00:10 +00:00
Cory Benfield 8ccf253641
Clarify on EL semantics (#2366) 2023-02-13 10:10:31 +00:00
Franz Busch b6b62665e9
NIOAsyncWriter: Provide a fast path for single element writes (#2365)
# Motivation
We are currently always allocating a new `Deque` when we get a single element write in the `NIOAsyncWriter`

# Modification
Provide a fast path method on the `NIOAsyncWriterSinkDelegate` protocol which will be called when we receive a single element write and are currently writable.

# Result
Performance win for the single write cases.
2023-02-10 15:16:41 +00:00
Cory Benfield 39047aec7c
Make PooledBuffer safer. (#2363)
Motivation:

PooledBuffer is an inherently unsafe type, but its original incarnation
was less safe than it needed to be. In particular, we can rewrite it to
ensure that it is compatible with automatic reference counting.

Modifications:

- Rewrite PooledBuffer to use ManagedBuffer
- Clean up alignment math
- Use scoped accessors
- Add hooks for future non-scoped access

Result:

Safer, clearer code
2023-02-08 07:59:17 +00:00
ser 1e7ad9a0db
Pool buffers for ivecs and storage refs in the event loop. (#2358)
* Pool buffers for ivecs and storage refs in the event loop.

* Introduce PoolElement for poolable objects and add some bounds checks for the pooled buffers.

* Some polishes.

* Fix build failure with Swift 5.5/5.6

* User raw pointers instead of typed.
2023-02-07 13:48:26 +00:00
George Barnett dfd4bdad89
Add UDP performance tests (#2360)
Motivation:

We don't have any UDP performance tests.

Modifications:

- Add UDP perf tests

Result:

We can measure perf improvements for UDP.
2023-02-06 15:50:47 +00:00
George Barnett 0d6137f250
Remove unused array (#2361)
Motivation:

The `PendingDatagramWritesManager` unconditionally creates an array and
reserves capacity... only to never use it.

Modifications:

Remove the unsued code.

Result:

Fewer allocations.
2023-02-03 09:25:14 +00:00
Franz Busch 45167b8006
Fix flaky testTaskCancel_whenStreaming_andNotSuspended (#2355)
# Motivation
Currently `testTaskCancel_whenStreaming_andNotSuspended` is flaky since `didTerminate` can be called after the iterator is dropped. Fixes https://github.com/apple/swift-nio/issues/2354

# Modification
Let's modify that slightly so we hight the condition we want to hit.

# Result
No more flaky tests.
2023-01-25 14:09:22 +00:00
George Barnett 417278754e
Point docs to Swift Package Index (#2353)
Motivation:

The NIO docs are now published on the Swift Package Index but the README
still refers to GitHub pages.

Modifications:

- Update README and other docs to point to Swift Package Index.

Result:

Documentation links work
2023-01-23 06:09:43 -08:00
Cory Benfield 1a0f46b8cd
Lift alloc counter Package.swift to 5.1 and add platforms (#2352)
Motivation:

Our allocation counter tests still build for 5.0 by default. This isn't
great, but we've been getting away with it because building for 5.7
requires changing the way we express our dependencies. Doing that is a
big breaking pain in the neck that requires changes in multiple repos.

As a shorter-term goal, however, to enable testing in at least one more
repo (swift-nio-ssh), this PR lifts the version to 5.1, which is the
last release compatible with the Package.swift dependency structure we
use but that supports the Platforms we need to express.

Modifications:

- Move allocation counter to 5.1
- Add platforms from swift-nio-ssh

Result:

We can write allocation counter tests for swift-nio-ssh.
2023-01-19 09:37:11 -08:00
Oleksandr Zhurba 555f1db039
Special case EventLoopPromise.succeed() when Value is Void (#2311)
Co-authored-by: OleksandrZhurba <56148913+OleksandrZhurba@users.noreply.github.com>
2023-01-19 09:06:07 -08:00
David Nadoba 3d18e94683
Add Swift 5.8 CI and update nightly CI to Ubuntu 22.04 (#2350)
* Add Swift 5.8 CI

* Update nightly CI to Ubuntu 22.04

* Allow slight allocation variance in `1000_udpconnections` test
2023-01-18 10:17:12 +00:00
Philip Brown 59e1f6f375
Tail allocate mutex and a generic value using ManagedBuffer (#2349)
Motivation:

Currently, NIOLock and NIOLockedValueBox incur unnecessary allocation and indirection costs.

Modifications:

Create namespace LockOperations for organization
Create LockStorage<Value>, a subclass of ManagedBuffer<LockPrimitive, Value>
Store the mutex as the header and the generic value as the first and only element
Update NIOLock and NIOLockedValueBox to use LockStorage

Result:

Optimal lock and value memory layout
Fewer allocations and less indirection
Code generation is excellent
2023-01-17 16:11:10 +00:00
Cory Benfield 4ad2c37338
Avoid integer literals that won't fit. (#2348)
Motivation:

While the "giant buffer" test doesn't run on 32-bit systems, it does
need to compile. That means we can't set a pointer to a value that won't
fit into an Int.

Modifications:

Smaller pointers!

Result:

The compile should work again.
2023-01-13 13:53:17 +00:00
ser c8ec84ef3b
Prepare mmsghdr structure properly. (#2346)
Motivation:

According to the Linux man page the msg_len field supposed to be used to return a number of bytes sent for the particular message.
It does not make a sense to initialize it with a size of the message.

Modifications:

Change msg_leg field initialization, use 0 instead of message size.

Result:

Use sendmmsg() call properly.

Co-authored-by: Cory Benfield <lukasa@apple.com>
2023-01-12 11:22:56 +00:00
Franz Busch 602989b003
Implement `remoteAddress0` and `localAddress0` on `EmbeddedChannel` (#2345)
# Motivation
`EmbeddedChannel` is often used in testing and currently any code under testing that uses `context.localAddress` cannot be mocked, since `EmbeddedChannelCore` is always throwing.

# Modification
Use the same values for `localAddress` in `localAddress0()`. Same for `remoteAddress`

# Result
We can now properly test code that needs local/remote addresses with `EmbeddedChannel`
2023-01-12 02:55:18 -08:00
Cory Benfield 184df88ec6
Avoid actually allocating a giant buffer (#2347)
Motivation:

Our CI system is beginning to struggle with allocating a giant buffer in
testSliceOfMassiveBufferWithAdvancedReaderIndexIsOk. We can work around
this by faking out the allocation.

Modifications:

- Provide a fake allocator that doesn't actually allocate memory.
- Rewrite the test to use it.

Result:

Test still validates the behaviour but doesn't touch memory anymore.
2023-01-12 02:33:54 -08:00
David Nadoba 1ce136b4c3
Fix main nightly CI (#2337)
* Fix nightly CI

* conditionalization of signal for architecture
2023-01-09 18:34:48 +00:00
Ahmad Alhashemi 91e5b3b609
Allow writing and reading empty datagrams (#2341)
Motivation:

Empty UDP datagrams could be used to have a meaning.
Empty datagrams were being silently dropped on write.
Receiving an empty diagram causes an assertion failure (possible DDoS).

Modifications:

Remove early exit when writing empty datagrams and non-empty assertion when reading them.

Result:

We can now write and read empty datagrams.
2023-01-09 02:45:15 -08:00
Cory Benfield d20a0dd472
2023 is real, we should support it (#2342) 2023-01-09 02:21:30 -08:00
Saleem Abdulrasool cd0aa5907b
NIOCore: repair the Windows build of NIOCore (#2339)
The addition of the new IP constant resulted in a build failure on
Windows.  Add the import for the equivalent constant to repair the
build.
2022-12-22 16:37:54 -05:00
thomas-gill-0xff b201ff561d
Remove useless instance variables in the SelectableEventLoop (#2338)
Motivation:

Less code we have - less bugs we have.
The fix remove few lines of code keeping the same functionality.

Modifications:

Just remove some useless instance variables.

Result:

Less code.
2022-12-21 03:41:44 -08:00
David Nadoba 7e3b50b38e
Improve performance of tests (#2336) 2022-12-19 10:14:27 -08:00
Johannes Weiss 86e8b5f5b5
add easier async to future conversion (#2334) 2022-12-19 11:05:47 +00:00
Cory Benfield 0760383b38
Measure allocations applying WS mask (#2333)
Motivation:

We're missing some alloc tests on the WS mask.

Modifications:

- Add extra alloc tests for the WS mask

Result:

We'll have more tests
2022-12-13 18:05:27 +00:00
Cory Benfield a58500af68
Make EventLoopFuture.wait() unavailable from async (#2331)
Motivation:

ELF.wait() waits for a condition variable to become true, which can
frequently lead to extremely long waits. This is a bad thing to call on
a Swift Concurrency thread, especially as we have ELF.get() which is
preferable.

Modifications:

Make ELF.wait() unavailable from async.

Result:

Users are encouraged to use the correct primitive.
2022-12-12 06:13:24 -08:00
Cory Benfield abf2b35e6d
Remove implicit ByteBuffer copy in copyMemory (#2330)
Motivation:

withVeryUnsafeBytes has a reference to `self` that it is using. This
necessarily triggers a copy when we subsequently use `self` inside the
block. The effect of that copy is an extra retain/release pair, and a
call to beginAccess, that we simply don't need.

Modifications:

Replace the call to `_setBytesAssumingUniqueBufferAccess` with a
manually inlined equivalent.

Result:

Avoids the extra copy of `self`, removes a retain/release and a
beginAccess.
2022-12-12 11:58:23 +00:00
Yim Lee b0f5e35b2e
Expand 'documentation_targets' list to fix missing docs (#2329) 2022-12-02 13:22:25 -08:00
David Nadoba 21c22f3535
Fix non Darwin/Linux builds (#2328) 2022-12-02 08:48:54 -08:00
Yim Lee ec72e0acc3
Add .spi.yml for Swift Package Index DocC support (#2324) 2022-12-02 10:36:04 +00:00
David Nadoba 810544ec41
Add `RawSocketBootstrap` (#2320) 2022-12-01 15:35:04 +01:00
Rick Newton-Rogers 00341c9277
cap read+pread POSIX read sizes at Int32.max (#2323)
Cap NonBlockingFileIO reads at Int32.max

Motivation:

We wish to avoid overly large reads resulting in EINVAL signals being
triggered resulting in errors. We workaround the issiue in the
NonBlockingFileIO level to keep the lower levels as simple as possible.

Modifications:

`NonBlockingFileIO` `read0` amends read `byteCount`s to be `Int32.max` if they are larger than that value.

Result:

Large `NonBlockingFileIO` reads no longer result in precondition
failures.
2022-11-28 13:19:12 +00:00