Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 52 additions & 68 deletions Package.swift

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ SwiftNIO | Minimum Swift Version
`2.60.0 ..< 2.65.0` | 5.7
`2.65.0 ..< 2.76.0` | 5.8
`2.76.0 ..< 2.83.0` | 5.9
`2.83.0 ...` | 5.10
`2.83.0 ..< 2.87.0` | 5.10
`2.87.0 ... ` | 6.0

### SwiftNIO 1
SwiftNIO 1 is considered end of life - it is strongly recommended that you move to a newer version. The Core NIO team does not actively work on this version. No new features will be added to this version but PRs which fix bugs or security vulnerabilities will be accepted until the end of May 2022.
Expand Down
13 changes: 0 additions & 13 deletions Sources/NIOConcurrencyHelpers/NIOAtomic.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import CNIOAtomics
/// **Do not add conformance to this protocol for arbitrary types**. Only a small range
/// of types have appropriate atomic operations supported by the CPU, and those types
/// already have conformances implemented.
#if compiler(>=6.0)
@preconcurrency
public protocol NIOAtomicPrimitive {
associatedtype AtomicWrapper
Expand All @@ -35,18 +34,6 @@ public protocol NIOAtomicPrimitive {
static var nio_atomic_load: @Sendable (UnsafeMutablePointer<AtomicWrapper>) -> Self { get }
static var nio_atomic_store: @Sendable (UnsafeMutablePointer<AtomicWrapper>, Self) -> Void { get }
}
#else
public protocol NIOAtomicPrimitive {
associatedtype AtomicWrapper
static var nio_atomic_create_with_existing_storage: (UnsafeMutablePointer<AtomicWrapper>, Self) -> Void { get }
static var nio_atomic_compare_and_exchange: (UnsafeMutablePointer<AtomicWrapper>, Self, Self) -> Bool { get }
static var nio_atomic_add: (UnsafeMutablePointer<AtomicWrapper>, Self) -> Self { get }
static var nio_atomic_sub: (UnsafeMutablePointer<AtomicWrapper>, Self) -> Self { get }
static var nio_atomic_exchange: (UnsafeMutablePointer<AtomicWrapper>, Self) -> Self { get }
static var nio_atomic_load: (UnsafeMutablePointer<AtomicWrapper>) -> Self { get }
static var nio_atomic_store: (UnsafeMutablePointer<AtomicWrapper>, Self) -> Void { get }
}
#endif

extension Bool: NIOAtomicPrimitive {
public typealias AtomicWrapper = catmc_nio_atomic__Bool
Expand Down
13 changes: 0 additions & 13 deletions Sources/NIOConcurrencyHelpers/atomics.swift
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,6 @@ extension Atomic: @unchecked Sendable where T: Sendable {}
/// **Do not add conformance to this protocol for arbitrary types**. Only a small range
/// of types have appropriate atomic operations supported by the CPU, and those types
/// already have conformances implemented.
#if compiler(>=6.0)
@preconcurrency
public protocol AtomicPrimitive {
static var atomic_create: @Sendable (Self) -> OpaquePointer { get }
Expand All @@ -309,18 +308,6 @@ public protocol AtomicPrimitive {
static var atomic_load: @Sendable (OpaquePointer) -> Self { get }
static var atomic_store: @Sendable (OpaquePointer, Self) -> Void { get }
}
#else
public protocol AtomicPrimitive {
static var atomic_create: (Self) -> OpaquePointer { get }
static var atomic_destroy: (OpaquePointer) -> Void { get }
static var atomic_compare_and_exchange: (OpaquePointer, Self, Self) -> Bool { get }
static var atomic_add: (OpaquePointer, Self) -> Self { get }
static var atomic_sub: (OpaquePointer, Self) -> Self { get }
static var atomic_exchange: (OpaquePointer, Self) -> Self { get }
static var atomic_load: (OpaquePointer) -> Self { get }
static var atomic_store: (OpaquePointer, Self) -> Void { get }
}
#endif

extension Bool: AtomicPrimitive {
public static let atomic_create = catmc_atomic__Bool_create
Expand Down
23 changes: 9 additions & 14 deletions Sources/NIOCore/AsyncChannel/AsyncChannel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -323,19 +323,18 @@ public struct NIOAsyncChannel<Inbound: Sendable, Outbound: Sendable>: Sendable {
return result
}

#if compiler(>=6.0)
// Note: Whitespace changes are used to workaround compiler bug
// Remove when compiler version 5.10 is no longer supported.
// https://github.com/swiftlang/swift/issues/79285
// swift-format-ignore
/// Provides scoped access to the inbound and outbound side of the underlying ``Channel``.
///
/// - Important: After this method returned the underlying ``Channel`` will be closed.
///
/// - Parameters:
/// - actor: actor where this function should be isolated to
/// - body: A closure that gets scoped access to the inbound and outbound.
public func executeThenClose<Result>(isolation actor: isolated (any Actor)? = #isolation, _ body: (_ inbound: NIOAsyncChannelInboundStream<Inbound>, _ outbound: NIOAsyncChannelOutboundWriter<Outbound>) async throws -> sending Result) async throws -> sending Result {
public func executeThenClose<Result>(
isolation actor: isolated (any Actor)? = #isolation,
_ body: (_ inbound: NIOAsyncChannelInboundStream<Inbound>, _ outbound: NIOAsyncChannelOutboundWriter<Outbound>)
async throws -> sending Result
) async throws -> sending Result {
let result: Result
do {
result = try await body(self._inbound, self._outbound)
Expand Down Expand Up @@ -370,7 +369,6 @@ public struct NIOAsyncChannel<Inbound: Sendable, Outbound: Sendable>: Sendable {

return result
}
#endif
}

// swift-format-ignore: AmbiguousTrailingClosureOverload
Expand Down Expand Up @@ -419,19 +417,17 @@ extension NIOAsyncChannel {
return result
}

#if compiler(>=6.0)
// Note: Whitespace changes are used to workaround compiler bug
// Remove when compiler version 5.10 is no longer supported.
// https://github.com/swiftlang/swift/issues/79285
// swift-format-ignore
/// Provides scoped access to the inbound side of the underlying ``Channel``.
///
/// - Important: After this method returned the underlying ``Channel`` will be closed.
///
/// - Parameters:
/// - actor: actor where this function should be isolated to
/// - body: A closure that gets scoped access to the inbound.
public func executeThenClose<Result>(isolation actor: isolated (any Actor)? = #isolation, _ body: (_ inbound: NIOAsyncChannelInboundStream<Inbound>) async throws -> sending Result) async throws -> sending Result where Outbound == Never {
public func executeThenClose<Result>(
isolation actor: isolated (any Actor)? = #isolation,
_ body: (_ inbound: NIOAsyncChannelInboundStream<Inbound>) async throws -> sending Result
) async throws -> sending Result where Outbound == Never {
let result: Result
do {
result = try await body(self._inbound)
Expand Down Expand Up @@ -466,7 +462,6 @@ extension NIOAsyncChannel {

return result
}
#endif
}

extension Channel {
Expand Down
6 changes: 0 additions & 6 deletions Sources/NIOCore/BSDSocketAPI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -102,15 +102,9 @@ private let sysInet_pton: @convention(c) (CInt, UnsafePointer<CChar>?, UnsafeMut
#endif

#if os(Android)
#if compiler(>=6.0)
@usableFromInline let IFF_BROADCAST: CUnsignedInt = numericCast(Android.IFF_BROADCAST.rawValue)
@usableFromInline let IFF_POINTOPOINT: CUnsignedInt = numericCast(Android.IFF_POINTOPOINT.rawValue)
@usableFromInline let IFF_MULTICAST: CUnsignedInt = numericCast(Android.IFF_MULTICAST.rawValue)
#else
@usableFromInline let IFF_BROADCAST: CUnsignedInt = numericCast(SwiftGlibc.IFF_BROADCAST.rawValue)
@usableFromInline let IFF_POINTOPOINT: CUnsignedInt = numericCast(SwiftGlibc.IFF_POINTOPOINT.rawValue)
@usableFromInline let IFF_MULTICAST: CUnsignedInt = numericCast(SwiftGlibc.IFF_MULTICAST.rawValue)
#endif
#if arch(arm)
@usableFromInline let SO_RCVTIMEO = SO_RCVTIMEO_OLD
@usableFromInline let SO_TIMESTAMP = SO_TIMESTAMP_OLD
Expand Down
2 changes: 0 additions & 2 deletions Sources/NIOCore/ByteBuffer-aux.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1003,7 +1003,6 @@ extension Optional where Wrapped == ByteBuffer {
}
}

#if compiler(>=6)
extension ByteBuffer {
/// Get the string at `index` from this `ByteBuffer` decoding using the UTF-8 encoding. Does not move the reader index.
/// The selected bytes must be readable or else `nil` will be returned.
Expand Down Expand Up @@ -1077,4 +1076,3 @@ extension ByteBuffer {
try self.getUTF8ValidatedString(at: self.readerIndex, length: length)
}
}
#endif // compiler(>=6)
12 changes: 5 additions & 7 deletions Sources/NIOCore/NIOLoopBound.swift
Original file line number Diff line number Diff line change
Expand Up @@ -139,17 +139,16 @@ public final class NIOLoopBoundBox<Value>: @unchecked Sendable {
.init(_value: value, uncheckedEventLoop: eventLoop)
}

#if compiler(>=6.0)
// Note: Whitespace changes are used to workaround compiler bug
// Remove when compiler version 5.10 is no longer supported.
// https://github.com/swiftlang/swift/issues/79285
// swift-format-ignore
/// Initialise a ``NIOLoopBoundBox`` by sending a value, validly callable off `eventLoop`.
///
/// Contrary to ``init(_:eventLoop:)``, this method can be called off `eventLoop` because `value` is moved into the box and can no longer be accessed outside the box.
/// So we don't need to protect `value` itself, we just need to protect the ``NIOLoopBoundBox`` against mutations which we do because the ``value``
/// accessors are checking that we're on `eventLoop`.
public static func makeBoxSendingValue(_ value: sending Value, as: Value.Type = Value.self, eventLoop: EventLoop) -> NIOLoopBoundBox<Value> {
public static func makeBoxSendingValue(
_ value: sending Value,
as: Value.Type = Value.self,
eventLoop: EventLoop
) -> NIOLoopBoundBox<Value> {
// Here, we -- possibly surprisingly -- do not precondition being on the EventLoop. This is okay for a few
// reasons:
// - This function takes its value as `sending` so we don't need to worry about somebody
Expand All @@ -159,7 +158,6 @@ public final class NIOLoopBoundBox<Value>: @unchecked Sendable {
// - The only way to ever write (or read indeed) `self._value` is by proving to be inside the `EventLoop`.
.init(_value: value, uncheckedEventLoop: eventLoop)
}
#endif

/// Access the `value` with the precondition that the code is running on `eventLoop`.
///
Expand Down
4 changes: 2 additions & 2 deletions Sources/NIOCrashTester/CrashTests+EventLoop.swift
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ struct EventLoopCrashTests {
NIOSingletons.groupLoopCountSuggestion = -1
}

#if compiler(>=5.9) && swift(<6.2) // We only support Concurrency executor take-over on those Swift versions, as versions greater than that have not been properly tested.
#if swift(<6.2) // We only support Concurrency executor take-over on those Swift versions, as versions greater than that have not been properly tested.
let testInstallingSingletonMTELGAsConcurrencyExecutorWorksButOnlyOnce = CrashTest(
regex: #"Fatal error: Must be called only once"#
) {
Expand All @@ -207,6 +207,6 @@ struct EventLoopCrashTests {
// This should crash
_ = NIOSingletons.unsafeTryInstallSingletonPosixEventLoopGroupAsConcurrencyGlobalExecutor()
}
#endif // compiler(>=5.9) && swift(<6.2)
#endif // swift(<6.2)
}
#endif // !canImport(Darwin) || os(macOS)
Original file line number Diff line number Diff line change
Expand Up @@ -207,18 +207,20 @@ extension FileDescriptor {
}

// Read and decode.
var buffer = [CChar](repeating: 0, count: capacity)
var buffer = [UInt8](repeating: 0, count: capacity)
return buffer.withUnsafeMutableBufferPointer { pointer in
self.listExtendedAttributes(pointer)
pointer.withMemoryRebound(to: CChar.self) { pointer in
self.listExtendedAttributes(pointer)
}
}.map { size in
// The buffer contains null terminated C-strings.
var attributes = [String]()
var slice = buffer.prefix(size)
while let index = slice.firstIndex(of: 0) {
// TODO: can we do this more cheaply?
let prefix = slice[...index]
attributes.append(String(cString: Array(prefix)))
slice = slice.dropFirst(prefix.count)
let prefix = slice[..<index]
attributes.append(String(decoding: Array(prefix), as: Unicode.UTF8.self))
slice = slice.dropFirst(prefix.count + 1)
}

return attributes
Expand Down
5 changes: 0 additions & 5 deletions Sources/NIOFS/Internal/System Calls/Mocking.swift
Original file line number Diff line number Diff line change
Expand Up @@ -346,11 +346,6 @@ extension String {
try withCString(body)
}

internal init?(_platformString platformString: UnsafePointer<CInterop.PlatformChar>) {
// Need to #if because CChar may be signed
self.init(validatingUTF8: platformString)
}

internal init(
_errorCorrectingPlatformString platformString: UnsafePointer<CInterop.PlatformChar>
) {
Expand Down
9 changes: 6 additions & 3 deletions Sources/NIOFS/Internal/System Calls/Syscall.swift
Original file line number Diff line number Diff line change
Expand Up @@ -364,19 +364,22 @@ public enum Libc: Sendable {

#if !os(Android)
static func constr(_ name: CInt) -> Result<String, Errno> {
var buffer = [CInterop.PlatformChar](repeating: 0, count: 128)
var buffer = [UInt8](repeating: 0, count: 128)

repeat {
let result = valueOrErrno(retryOnInterrupt: false) {
buffer.withUnsafeMutableBufferPointer { pointer in
libc_confstr(name, pointer.baseAddress!, pointer.count)
pointer.withMemoryRebound(to: CInterop.PlatformChar.self) { buffer in
libc_confstr(name, buffer.baseAddress!, buffer.count)
}
}
}

switch result {
case let .success(length):
if length <= buffer.count {
return .success(String(cString: buffer))
let nullTerminationIndex = buffer.firstIndex(of: 0) ?? buffer.endIndex
return .success(String(decoding: buffer[..<nullTerminationIndex], as: Unicode.UTF8.self))
} else {
// The buffer wasn't long enough. Double and try again.
buffer.append(contentsOf: repeatElement(0, count: buffer.capacity))
Expand Down
5 changes: 0 additions & 5 deletions Sources/NIOPosix/Linux.swift
Original file line number Diff line number Diff line change
Expand Up @@ -178,13 +178,8 @@ internal enum Epoll {

internal enum Linux {
#if os(Android)
#if compiler(>=6.0)
static let SOCK_CLOEXEC = Android.SOCK_CLOEXEC
static let SOCK_NONBLOCK = Android.SOCK_NONBLOCK
#else
static let SOCK_CLOEXEC = Glibc.SOCK_CLOEXEC
static let SOCK_NONBLOCK = Glibc.SOCK_NONBLOCK
#endif
#elseif canImport(Musl)
static let SOCK_CLOEXEC = Musl.SOCK_CLOEXEC
static let SOCK_NONBLOCK = Musl.SOCK_NONBLOCK
Expand Down
2 changes: 0 additions & 2 deletions Sources/NIOPosix/MultiThreadedEventLoopGroup.swift
Original file line number Diff line number Diff line change
Expand Up @@ -624,7 +624,6 @@ extension NIODeadline {
}

extension MultiThreadedEventLoopGroup {
#if compiler(>=6.0)
/// Start & automatically shut down a new ``MultiThreadedEventLoopGroup``.
///
/// This method allows to start & automatically dispose of a ``MultiThreadedEventLoopGroup`` following the principle of Structured Concurrency.
Expand Down Expand Up @@ -660,5 +659,4 @@ extension MultiThreadedEventLoopGroup {
}
}
}
#endif
}
2 changes: 1 addition & 1 deletion Sources/NIOPosix/PosixSingletons+ConcurrencyTakeOver.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ extension NIOSingletons {
return false
#else
// Guard between the minimum and maximum supported version for the hook
#if compiler(>=5.9) && compiler(<6.3)
#if compiler(<6.3)
guard #available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *) else {
return false
}
Expand Down
43 changes: 3 additions & 40 deletions Sources/NIOPosix/StructuredConcurrencyHelpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,14 @@
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
// swift-format-ignore
// Note: Whitespace changes are used to workaround compiler bug
// https://github.com/swiftlang/swift/issues/79285

#if compiler(>=6.0)
@inlinable
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
internal func asyncDo<R>(
isolation: isolated (any Actor)? = #isolation,
// DO NOT FIX THE WHITESPACE IN THE NEXT LINE UNTIL 5.10 IS UNSUPPORTED
// https://github.com/swiftlang/swift/issues/79285
_ body: () async throws -> sending R, finally: sending @escaping ((any Error)?) async throws -> Void) async throws -> sending R {
_ body: () async throws -> sending R,
finally: sending @escaping ((any Error)?) async throws -> Void
) async throws -> sending R {
let result: R
do {
result = try await body()
Expand All @@ -62,36 +58,3 @@ internal func asyncDo<R>(
}.value
return result
}
#else
@inlinable
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
internal func asyncDo<R: Sendable>(
_ body: () async throws -> R,
finally: @escaping @Sendable ((any Error)?) async throws -> Void
) async throws -> R {
let result: R
do {
result = try await body()
} catch {
// `body` failed, we need to invoke `finally` with the `error`.

// This _looks_ unstructured but isn't really because we unconditionally always await the return.
// We need to have an uncancelled task here to assure this is actually running in case we hit a
// cancellation error.
try await Task {
try await finally(error)
}.value
throw error
}

// `body` succeeded, we need to invoke `finally` with `nil` (no error).

// This _looks_ unstructured but isn't really because we unconditionally always await the return.
// We need to have an uncancelled task here to assure this is actually running in case we hit a
// cancellation error.
try await Task {
try await finally(nil)
}.value
return result
}
#endif
Loading
Loading