use to NIO 2 (from master branch) and Swift 5 (#18)

Motivation:

SwiftPM from Swift 5.0 brings targets that only support certain systems
which is really handy for this package as it only support macOS 10.14+
and iOS/tvOS 12+

Modifications:

- made use of the Swift 5.0 manifests which can have restrictions on the
  supported platforms
- adapted to NIO 2

Result:

- better development story
- using the latest & greatest
This commit is contained in:
Johannes Weiss 2019-01-18 13:03:21 +00:00 committed by Cory Benfield
parent ea5ba9bd25
commit 9fa52bd443
13 changed files with 76 additions and 63 deletions

View File

@ -1,4 +1,4 @@
// swift-tools-version:4.0
// swift-tools-version:5.0
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftNIO open source project
@ -17,13 +17,16 @@ import PackageDescription
let package = Package(
name: "swift-nio-transport-services",
platforms: [
.macOS(.v10_14), .iOS(.v12), .tvOS(.v12),
],
products: [
.library(name: "NIOTransportServices", targets: ["NIOTransportServices"]),
.executable(name: "NIOTSHTTPClient", targets: ["NIOTSHTTPClient"]),
.executable(name: "NIOTSHTTPServer", targets: ["NIOTSHTTPServer"]),
],
dependencies: [
.package(url: "https://github.com/apple/swift-nio.git", from: "1.11.0"),
.package(url: "https://github.com/apple/swift-nio.git", .branch("master")),
],
targets: [
.target(name: "NIOTransportServices",

View File

@ -16,24 +16,21 @@ Network.framework is Apple's reference implementation of the [proposed post-sock
## How to Use?
Today, the easiest way to use SwiftNIO Transport Services is through CocoaPods:
Today, the easiest way to use SwiftNIO Transport Services in an iOS project is through CocoaPods:
pod 'SwiftNIO'
pod 'SwiftNIOTransportServices'
You can also use the Swift Package Manager, however Network.framework is only available on macOS 10.14+, iOS 12+, and tvOS 12+. This does not match the current minimum deployment target for Swift Package Manager, so building this repository with Swift Package Manager requires that you pass custom build flags, e.g:
You can also use the Swift Package Manager:
```
swift build -Xswiftc -target -Xswiftc x86_64-apple-macosx10.14
swift build
```
Alternatively, if you want to use Xcode to build this repository, you can use the following xcconfig:
and add the project as a sub-project by dragging it into your iOS project and adding the frameworks (such as `NIO.framework`) in 'Build Phases' -> 'Link Binary Libraries'.
```
MACOSX_DEPLOYMENT_TARGET = 10.14
```
Do note however that Network.framework requires macOS 10.14+, iOS 12+, or tvOS 12+.
For support in iOS or tvOS, change the targets as necessary.
## Versioning

View File

@ -103,7 +103,7 @@ public final class NIOTSConnectionBootstrap {
/// - returns: An `EventLoopFuture<Channel>` to deliver the `Channel` when connected.
public func connect(host: String, port: Int) -> EventLoopFuture<Channel> {
guard let actualPort = NWEndpoint.Port(rawValue: UInt16(port)) else {
return self.group.next().newFailedFuture(error: NIOTSErrors.InvalidPort(port: port))
return self.group.next().makeFailedFuture(error: NIOTSErrors.InvalidPort(port: port))
}
return self.connect(endpoint: NWEndpoint.hostPort(host: .init(host), port: actualPort))
}
@ -129,7 +129,7 @@ public final class NIOTSConnectionBootstrap {
let address = try SocketAddress(unixDomainSocketPath: unixDomainSocketPath)
return connect(to: address)
} catch {
return group.next().newFailedFuture(error: error)
return group.next().makeFailedFuture(error: error)
}
}
@ -146,7 +146,7 @@ public final class NIOTSConnectionBootstrap {
qos: self.qos,
tcpOptions: self.tcpOptions,
tlsOptions: self.tlsOptions)
let initializer = self.channelInitializer ?? { _ in conn.eventLoop.newSucceededFuture(result: ()) }
let initializer = self.channelInitializer ?? { _ in conn.eventLoop.makeSucceededFuture(result: ()) }
let channelOptions = self.channelOptions
return conn.eventLoop.submit {
@ -155,14 +155,14 @@ public final class NIOTSConnectionBootstrap {
}.then {
conn.register()
}.then {
let connectPromise: EventLoopPromise<Void> = conn.eventLoop.newPromise()
let connectPromise: EventLoopPromise<Void> = conn.eventLoop.makePromise()
connectAction(conn, connectPromise)
let cancelTask = conn.eventLoop.scheduleTask(in: self.connectTimeout) {
connectPromise.fail(error: ChannelError.connectTimeout(self.connectTimeout))
conn.close(promise: nil)
}
connectPromise.futureResult.whenComplete {
connectPromise.futureResult.whenComplete { (_: Result<Void, Error>) in
cancelTask.cancel()
}
return connectPromise.futureResult
@ -200,7 +200,7 @@ internal struct ChannelOptionStorage {
}
func applyAll(channel: Channel) -> EventLoopFuture<Void> {
let applyPromise: EventLoopPromise<Void> = channel.eventLoop.newPromise()
let applyPromise: EventLoopPromise<Void> = channel.eventLoop.makePromise()
var it = self.storage.makeIterator()
func applyNext() {

View File

@ -210,7 +210,7 @@ internal final class NIOTSConnectionChannel {
tcpOptions: NWProtocolTCP.Options,
tlsOptions: NWProtocolTLS.Options?) {
self.tsEventLoop = eventLoop
self.closePromise = eventLoop.newPromise()
self.closePromise = eventLoop.makePromise()
self.parent = parent
self.connectionQueue = eventLoop.channelQueue(label: "nio.nioTransportServices.connectionchannel", qos: qos)
self.tcpOptions = tcpOptions
@ -273,7 +273,7 @@ extension NIOTSConnectionChannel: Channel {
public func setOption<T>(option: T, value: T.OptionType) -> EventLoopFuture<Void> where T : ChannelOption {
if eventLoop.inEventLoop {
let promise: EventLoopPromise<Void> = eventLoop.newPromise()
let promise: EventLoopPromise<Void> = eventLoop.makePromise()
executeAndComplete(promise) { try setOption0(option: option, value: value) }
return promise.futureResult
} else {
@ -325,7 +325,7 @@ extension NIOTSConnectionChannel: Channel {
public func getOption<T>(option: T) -> EventLoopFuture<T.OptionType> where T : ChannelOption {
if eventLoop.inEventLoop {
let promise: EventLoopPromise<T.OptionType> = eventLoop.newPromise()
let promise: EventLoopPromise<T.OptionType> = eventLoop.makePromise()
executeAndComplete(promise) { try getOption0(option: option) }
return promise.futureResult
} else {

View File

@ -104,7 +104,7 @@ internal class NIOTSEventLoop: QoSEventLoop {
}
public func scheduleTask<T>(in time: TimeAmount, qos: DispatchQoS, _ task: @escaping () throws -> T) -> Scheduled<T> {
let p: EventLoopPromise<T> = self.newPromise()
let p: EventLoopPromise<T> = self.makePromise()
guard self.state != .closed else {
p.fail(error: EventLoopError.shutdown)
@ -153,7 +153,7 @@ extension NIOTSEventLoop {
extension NIOTSEventLoop {
internal func closeGently() -> EventLoopFuture<Void> {
let p: EventLoopPromise<Void> = self.newPromise()
let p: EventLoopPromise<Void> = self.makePromise()
self.taskQueue.async {
guard self.open else {
p.fail(error: EventLoopError.shutdown)
@ -181,7 +181,7 @@ extension NIOTSEventLoop {
// event loop it will be forbidden from doing so.
let completionFuture = EventLoopFuture<Void>.andAll(futures, eventLoop: self)
completionFuture.cascade(promise: p)
completionFuture.whenComplete {
completionFuture.whenComplete { (_: Result<Void, Error>) in
self.state = .closed
}
}

View File

@ -68,7 +68,7 @@ public final class NIOTSEventLoopGroup: EventLoopGroup {
g.enter()
loop.closeGently().mapIfError { err in
q.sync { error = err }
}.whenComplete {
}.whenComplete { (_: Result<Void, Error>) in
g.leave()
}
}
@ -77,4 +77,8 @@ public final class NIOTSEventLoopGroup: EventLoopGroup {
callback(error)
}
}
public func makeIterator() -> EventLoopIterator {
return EventLoopIterator(self.eventLoops)
}
}

View File

@ -145,12 +145,12 @@ public final class NIOTSListenerBootstrap {
/// - port: The port to bind on.
public func bind(host: String, port: Int) -> EventLoopFuture<Channel> {
return self.bind0 { channel in
let p: EventLoopPromise<Void> = channel.eventLoop.newPromise()
let p: EventLoopPromise<Void> = channel.eventLoop.makePromise()
do {
// NWListener does not actually resolve hostname-based NWEndpoints
// for use with requiredLocalEndpoint, so we fall back to
// SocketAddress for this.
let address = try SocketAddress.newAddressResolving(host: host, port: port)
let address = try SocketAddress.makeAddressResolvingHost(host, port: port)
channel.bind(to: address, promise: p)
} catch {
p.fail(error: error)
@ -175,7 +175,7 @@ public final class NIOTSListenerBootstrap {
/// - unixDomainSocketPath: The _Unix domain socket_ path to bind to. `unixDomainSocketPath` must not exist, it will be created by the system.
public func bind(unixDomainSocketPath: String) -> EventLoopFuture<Channel> {
return self.bind0 { channel in
let p: EventLoopPromise<Void> = channel.eventLoop.newPromise()
let p: EventLoopPromise<Void> = channel.eventLoop.makePromise()
do {
let address = try SocketAddress(unixDomainSocketPath: unixDomainSocketPath)
channel.bind(to: address, promise: p)
@ -199,7 +199,7 @@ public final class NIOTSListenerBootstrap {
private func bind0(_ binder: @escaping (Channel) -> EventLoopFuture<Void>) -> EventLoopFuture<Channel> {
let eventLoop = self.group.next() as! NIOTSEventLoop
let childEventLoopGroup = self.childGroup as! NIOTSEventLoopGroup
let serverChannelInit = self.serverChannelInit ?? { _ in eventLoop.newSucceededFuture(result: ()) }
let serverChannelInit = self.serverChannelInit ?? { _ in eventLoop.makeSucceededFuture(result: ()) }
let childChannelInit = self.childChannelInit
let serverChannelOptions = self.serverChannelOptions
let childChannelOptions = self.childChannelOptions
@ -227,7 +227,7 @@ public final class NIOTSListenerBootstrap {
serverChannel as Channel
}.thenIfError { error in
serverChannel.close0(error: error, mode: .all, promise: nil)
return eventLoop.newFailedFuture(error: error)
return eventLoop.makeFailedFuture(error: error)
}
}.then {
$0
@ -265,7 +265,7 @@ private class AcceptHandler: ChannelInboundHandler {
let conn = self.unwrapInboundIn(data)
let childLoop = self.childGroup.next() as! NIOTSEventLoop
let ctxEventLoop = ctx.eventLoop
let childInitializer = self.childChannelInitializer ?? { _ in childLoop.newSucceededFuture(result: ()) }
let childInitializer = self.childChannelInitializer ?? { _ in childLoop.makeSucceededFuture(result: ()) }
let newChannel = NIOTSConnectionChannel(wrapping: conn,
on: childLoop,
parent: ctx.channel,
@ -292,7 +292,7 @@ private class AcceptHandler: ChannelInboundHandler {
}
}
ctx.fireChannelRead(self.wrapInboundOut(newChannel))
return ctx.eventLoop.newSucceededFuture(result: ())
return ctx.eventLoop.makeSucceededFuture(result: ())
}.whenFailure { error in
ctx.eventLoop.assertInEventLoop()
_ = newChannel.close()

View File

@ -85,7 +85,7 @@ internal final class NIOTSListenerChannel {
tcpOptions: NWProtocolTCP.Options,
tlsOptions: NWProtocolTLS.Options?) {
self.tsEventLoop = eventLoop
self.closePromise = eventLoop.newPromise()
self.closePromise = eventLoop.makePromise()
self.connectionQueue = eventLoop.channelQueue(label: "nio.transportservices.listenerchannel", qos: qos)
self.tcpOptions = tcpOptions
self.tlsOptions = tlsOptions
@ -134,7 +134,7 @@ extension NIOTSListenerChannel: Channel {
public func setOption<T>(option: T, value: T.OptionType) -> EventLoopFuture<Void> where T : ChannelOption {
if eventLoop.inEventLoop {
let promise: EventLoopPromise<Void> = eventLoop.newPromise()
let promise: EventLoopPromise<Void> = eventLoop.makePromise()
executeAndComplete(promise) { try setOption0(option: option, value: value) }
return promise.futureResult
} else {
@ -173,7 +173,7 @@ extension NIOTSListenerChannel: Channel {
public func getOption<T>(option: T) -> EventLoopFuture<T.OptionType> where T : ChannelOption {
if eventLoop.inEventLoop {
let promise: EventLoopPromise<T.OptionType> = eventLoop.newPromise()
let promise: EventLoopPromise<T.OptionType> = eventLoop.makePromise()
executeAndComplete(promise) { try getOption0(option: option) }
return promise.futureResult
} else {
@ -269,6 +269,8 @@ extension NIOTSListenerChannel: StateManagedChannel {
parameters.requiredLocalEndpoint = target
case .service(_, _, _, let interface):
parameters.requiredInterface = interface
@unknown default:
()
}
// Network.framework munges REUSEADDR and REUSEPORT together, so we turn this on if we need
@ -342,7 +344,7 @@ extension NIOTSListenerChannel: StateManagedChannel {
self.eventLoop.assertInEventLoop()
let channel = self.unwrapData(data, as: NIOTSConnectionChannel.self)
let p: EventLoopPromise<Void> = channel.eventLoop.newPromise()
let p: EventLoopPromise<Void> = channel.eventLoop.makePromise()
channel.eventLoop.execute {
channel.registerAlreadyConfigured0(promise: p)
p.futureResult.whenFailure { (_: Error) in

View File

@ -18,7 +18,7 @@ import Foundation
import NIO
import Network
internal extension IPv4Address {
extension IPv4Address {
/// Create an `IPv4Address` object from a `sockaddr_in`.
internal init(fromSockAddr sockAddr: sockaddr_in) {
var localAddr = sockAddr
@ -30,7 +30,7 @@ internal extension IPv4Address {
}
}
internal extension IPv6Address {
extension IPv6Address {
internal init(fromSockAddr sockAddr: sockaddr_in6) {
var localAddr = sockAddr
@ -44,7 +44,7 @@ internal extension IPv6Address {
}
}
internal extension NWEndpoint {
extension NWEndpoint {
/// Create an `NWEndpoint` value from a NIO `SocketAddress`.
internal init(fromSocketAddress socketAddress: SocketAddress) {
switch socketAddress {
@ -57,11 +57,11 @@ internal extension NWEndpoint {
self = NWEndpoint.unix(path: path)
case .v4(let v4Addr):
let v4Address = IPv4Address(fromSockAddr: v4Addr.address)
let port = NWEndpoint.Port(rawValue: socketAddress.port!)!
let port = NWEndpoint.Port(rawValue: UInt16(socketAddress.port!))!
self = NWEndpoint.hostPort(host: .ipv4(v4Address), port: port)
case .v6(let v6Addr):
let v6Address = IPv6Address(fromSockAddr: v6Addr.address)
let port = NWEndpoint.Port(rawValue: socketAddress.port!)!
let port = NWEndpoint.Port(rawValue: UInt16(socketAddress.port!))!
self = NWEndpoint.hostPort(host: .ipv6(v6Address), port: port)
}
}
@ -69,7 +69,7 @@ internal extension NWEndpoint {
// TODO: We'll want to get rid of this when we support returning NWEndpoint directly from
// the various address-handling functions.
internal extension SocketAddress {
extension SocketAddress {
internal init(fromNWEndpoint endpoint: NWEndpoint) throws {
switch endpoint {
case .hostPort(.ipv4(let host), let port):
@ -96,8 +96,10 @@ internal extension SocketAddress {
self = try .init(unixDomainSocketPath: path)
case .service:
preconditionFailure("Cannot represent service addresses in SocketAddress")
case .hostPort(.name, _):
preconditionFailure("Cannot represent host by name only as SocketAddress")
case .hostPort(_, _):
preconditionFailure("Cannot represent unknown host in SocketAddress")
@unknown default:
preconditionFailure("cannot create SocketAddress from unknown representation")
}
}
}

View File

@ -74,8 +74,13 @@ final class DisableWaitingAfterConnect: ChannelOutboundHandler {
typealias OutboundOut = Any
func connect(ctx: ChannelHandlerContext, to address: SocketAddress, promise: EventLoopPromise<Void>?) {
ctx.connect(to: address, promise: promise)
ctx.channel.setOption(option: NIOTSChannelOptions.waitForActivity, value: false)
let f = ctx.channel.setOption(option: NIOTSChannelOptions.waitForActivity, value: false).then {
ctx.connect(to: address)
}
if let promise = promise {
f.cascade(promise: promise)
}
}
}
@ -151,7 +156,7 @@ class NIOTSConnectionChannelTests: XCTestCase {
try connection.eventLoop.submit {
XCTAssertEqual(connectRecordingHandler.connectTargets, [])
XCTAssertEqual(connectRecordingHandler.endpointTargets, [NWEndpoint.hostPort(host: "localhost", port: NWEndpoint.Port(rawValue: listener.localAddress!.port!)!)])
XCTAssertEqual(connectRecordingHandler.endpointTargets, [NWEndpoint.hostPort(host: "localhost", port: NWEndpoint.Port(rawValue: UInt16(listener.localAddress!.port!))!)])
}.wait()
}
@ -168,7 +173,7 @@ class NIOTSConnectionChannelTests: XCTestCase {
XCTAssertEqual(connectRecordingHandler.connectTargets, [])
XCTAssertEqual(connectRecordingHandler.endpointTargets, [])
let target = NWEndpoint.hostPort(host: "localhost", port: NWEndpoint.Port(rawValue: listener.localAddress!.port!)!)
let target = NWEndpoint.hostPort(host: "localhost", port: NWEndpoint.Port(rawValue: UInt16(listener.localAddress!.port!))!)
let connection = try connectBootstrap.connect(endpoint: target).wait()
defer {
@ -306,7 +311,7 @@ class NIOTSConnectionChannelTests: XCTestCase {
// Write a. After this write, we are still writable. When this write
// succeeds, we'll still be not writable.
connection.write(buffer.getSlice(at: 0, length: 1)).whenComplete {
connection.write(buffer.getSlice(at: 0, length: 1)).whenComplete { (_: Result<Void, Error>) in
XCTAssertEqual(writabilities, [false])
XCTAssertFalse(connection.isWritable)
}
@ -315,7 +320,7 @@ class NIOTSConnectionChannelTests: XCTestCase {
// Write b. After this write we are still writable. When this write
// succeeds we'll still be not writable.
connection.write(buffer.getSlice(at: 0, length: 1)).whenComplete {
connection.write(buffer.getSlice(at: 0, length: 1)).whenComplete { (_: Result<Void, Error>) in
XCTAssertEqual(writabilities, [false])
XCTAssertFalse(connection.isWritable)
}
@ -324,7 +329,7 @@ class NIOTSConnectionChannelTests: XCTestCase {
// Write c. After this write we are still writable (2047 bytes written).
// When this write succeeds we'll still be not writable (2 bytes outstanding).
connection.write(buffer.getSlice(at: 0, length: 2045)).whenComplete {
connection.write(buffer.getSlice(at: 0, length: 2045)).whenComplete { (_: Result<Void, Error>) in
XCTAssertEqual(writabilities, [false])
XCTAssertFalse(connection.isWritable)
}
@ -334,7 +339,7 @@ class NIOTSConnectionChannelTests: XCTestCase {
// Write d. After this write we are still writable (2048 bytes written).
// When this write succeeds we'll become writable, but critically the promise fires before
// the state change, so we'll *appear* to be unwritable.
connection.write(buffer.getSlice(at: 0, length: 1)).whenComplete {
connection.write(buffer.getSlice(at: 0, length: 1)).whenComplete { (_: Result<Void, Error>) in
XCTAssertEqual(writabilities, [false])
XCTAssertFalse(connection.isWritable)
}
@ -344,7 +349,7 @@ class NIOTSConnectionChannelTests: XCTestCase {
// Write e. After this write we are now not writable (2049 bytes written).
// When this write succeeds we'll have already been writable, thanks to the previous
// write.
connection.write(buffer.getSlice(at: 0, length: 1)).whenComplete {
connection.write(buffer.getSlice(at: 0, length: 1)).whenComplete { (_: Result<Void, Error>) in
XCTAssertEqual(writabilities, [false, true])
XCTAssertTrue(connection.isWritable)
@ -502,7 +507,7 @@ class NIOTSConnectionChannelTests: XCTestCase {
}
let connectFuture = NIOTSConnectionBootstrap(group: self.group)
.channelInitializer { channel in channel.eventLoop.newFailedFuture(error: MyError()) }
.channelInitializer { channel in channel.eventLoop.makeFailedFuture(error: MyError()) }
.connect(to: listener.localAddress!)
do {
@ -581,7 +586,7 @@ class NIOTSConnectionChannelTests: XCTestCase {
XCTAssertNoThrow(try listener.close().wait())
}
let activePromise: EventLoopPromise<Void> = self.group.next().newPromise()
let activePromise: EventLoopPromise<Void> = self.group.next().makePromise()
let channel = try NIOTSConnectionBootstrap(group: self.group)
.channelInitializer { channel in

View File

@ -52,7 +52,7 @@ final class ReadExpecter: ChannelInboundHandler {
}
func handlerAdded(ctx: ChannelHandlerContext) {
self.readPromise = ctx.eventLoop.newPromise()
self.readPromise = ctx.eventLoop.makePromise()
}
func handlerRemoved(ctx: ChannelHandlerContext) {
@ -248,7 +248,7 @@ class NIOTSEndToEndTests: XCTestCase {
closeFutures.append(channel.closeFuture)
}
closeFutureGroup.leave()
return channel.eventLoop.newSucceededFuture(result: ())
return channel.eventLoop.makeSucceededFuture(result: ())
}
.bind(host: "localhost", port: 0).wait()
defer {
@ -279,7 +279,7 @@ class NIOTSEndToEndTests: XCTestCase {
}
func testAgreeOnRemoteLocalAddresses() throws {
let serverSideConnectionPromise: EventLoopPromise<Channel> = self.group.next().newPromise()
let serverSideConnectionPromise: EventLoopPromise<Channel> = self.group.next().makePromise()
let listener = try NIOTSListenerBootstrap(group: self.group)
.childChannelInitializer { channel in
serverSideConnectionPromise.succeed(result: channel)
@ -303,7 +303,7 @@ class NIOTSEndToEndTests: XCTestCase {
}
func testHalfClosureSupported() throws {
let halfClosedPromise: EventLoopPromise<Void> = self.group.next().newPromise()
let halfClosedPromise: EventLoopPromise<Void> = self.group.next().makePromise()
let listener = try NIOTSListenerBootstrap(group: self.group)
.childChannelInitializer { channel in
channel.pipeline.add(handler: EchoHandler()).then { _ in

View File

@ -51,7 +51,7 @@ class NIOTSEventLoopTest: XCTestCase {
firstTask.cancel()
}
let thirdTask = loop.scheduleTask(in: .milliseconds(50)) { }
firstTask.futureResult.whenComplete {
firstTask.futureResult.whenComplete { (_: Result<Void, Error>) in
let newNow = DispatchTime.now()
XCTAssertLessThan(newNow.uptimeNanoseconds - now.uptimeNanoseconds,
300 * 1000 * 1000)

View File

@ -56,7 +56,7 @@ class NIOTSListenerChannelTests: XCTestCase {
func testBindingToSocketAddressTraversesPipeline() throws {
let bindRecordingHandler = BindRecordingHandler()
let target = try SocketAddress.newAddressResolving(host: "localhost", port: 0)
let target = try SocketAddress.makeAddressResolvingHost("localhost", port: 0)
let bindBootstrap = NIOTSListenerBootstrap(group: self.group)
.serverChannelInitializer { channel in channel.pipeline.add(handler: bindRecordingHandler)}
@ -88,7 +88,7 @@ class NIOTSListenerChannelTests: XCTestCase {
}
try self.group.next().submit {
XCTAssertEqual(bindRecordingHandler.bindTargets, [try SocketAddress.newAddressResolving(host: "localhost", port: 0)])
XCTAssertEqual(bindRecordingHandler.bindTargets, [try SocketAddress.makeAddressResolvingHost("localhost", port: 0)])
XCTAssertEqual(bindRecordingHandler.endpointTargets, [])
}.wait()
}
@ -143,7 +143,7 @@ class NIOTSListenerChannelTests: XCTestCase {
struct MyError: Error { }
let listenerFuture = NIOTSListenerBootstrap(group: self.group)
.serverChannelInitializer { channel in channel.eventLoop.newFailedFuture(error: MyError()) }
.serverChannelInitializer { channel in channel.eventLoop.makeFailedFuture(error: MyError()) }
.bind(host: "localhost", port: 0)
do {
@ -160,8 +160,8 @@ class NIOTSListenerChannelTests: XCTestCase {
func testCanSafelyInvokeChannelsAcrossThreads() throws {
// This is a test that aims to trigger TSAN violations.
let childGroup = NIOTSEventLoopGroup(loopCount: 2)
let childChannelPromise: EventLoopPromise<Channel> = childGroup.next().newPromise()
let activePromise: EventLoopPromise<Void> = childGroup.next().newPromise()
let childChannelPromise: EventLoopPromise<Channel> = childGroup.next().makePromise()
let activePromise: EventLoopPromise<Void> = childGroup.next().makePromise()
let listener = try NIOTSListenerBootstrap(group: self.group, childGroup: childGroup)
.childChannelInitializer { channel in