85 lines
3.5 KiB
Swift
85 lines
3.5 KiB
Swift
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This source file is part of the SwiftNIO open source project
|
|
//
|
|
// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors
|
|
// Licensed under Apache License v2.0
|
|
//
|
|
// See LICENSE.txt for license information
|
|
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
|
|
// swift-tools-version:4.0
|
|
//
|
|
// swift-tools-version:4.0
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
import Foundation
|
|
import NIO
|
|
import NIOConcurrencyHelpers
|
|
import Dispatch
|
|
import Network
|
|
|
|
|
|
/// An `EventLoopGroup` containing `EventLoop`s specifically designed for use with
|
|
/// Network.framework's post-sockets networking API.
|
|
///
|
|
/// These `EventLoop`s provide highly optimised and powerful networking tools for
|
|
/// the Darwin platforms. They have a number of advantages over the regular
|
|
/// `SelectableEventLoop` that NIO uses on other platforms. In particular:
|
|
///
|
|
/// - The use of `DispatchQueue`s to schedule tasks allows the Darwin kernels to make
|
|
/// intelligent scheduling decisions, as well as to maintain QoS and ensure that
|
|
/// tasks required to handle networking in your application are given appropriate
|
|
/// priority by the system.
|
|
/// - Network.framework provides powerful tools for observing network state and managing
|
|
/// connections on devices with highly fluid networking environments, such as laptops
|
|
/// and mobile devices. These tools can be exposed to `Channel`s using this backend.
|
|
/// - Network.framework brings the networking stack into userspace, reducing the overhead
|
|
/// of most network operations by removing syscalls, and greatly increasing the safety
|
|
/// and security of the network stack.
|
|
/// - The applications networking needs are more effectively communicated to the kernel,
|
|
/// allowing mobile devices to change radio configuration and behaviour as needed to
|
|
/// take advantage of the various interfaces available on mobile devices.
|
|
///
|
|
/// In general, when building applications whose primary purpose is to be deployed on Darwin
|
|
/// platforms, the `NIOTSEventLoopGroup` should be preferred over the
|
|
/// `MultiThreadedEventLoopGroup`. In particular, on iOS, the `NIOTSEventLoopGroup` is the
|
|
/// preferred networking backend.
|
|
public final class NIOTSEventLoopGroup: EventLoopGroup {
|
|
private let index = Atomic<Int>(value: 0)
|
|
private let eventLoops: [NIOTSEventLoop]
|
|
|
|
public init(loopCount: Int = 1, defaultQoS: DispatchQoS = .default) {
|
|
precondition(loopCount > 0)
|
|
self.eventLoops = (0..<loopCount).map { _ in NIOTSEventLoop(qos: defaultQoS) }
|
|
}
|
|
|
|
public func next() -> EventLoop {
|
|
return self.eventLoops[abs(index.add(1) % self.eventLoops.count)]
|
|
}
|
|
|
|
/// Shuts down all of the event loops, rendering them unable to perform further work.
|
|
public func shutdownGracefully(queue: DispatchQueue, _ callback: @escaping (Error?) -> Void) {
|
|
let g = DispatchGroup()
|
|
let q = DispatchQueue(label: "nio.transportservices.shutdowngracefullyqueue", target: queue)
|
|
var error: Error? = nil
|
|
|
|
for loop in self.eventLoops {
|
|
g.enter()
|
|
loop.closeGently().mapIfError { err in
|
|
q.sync { error = err }
|
|
}.whenComplete { (_: Result<Void, Error>) in
|
|
g.leave()
|
|
}
|
|
}
|
|
|
|
g.notify(queue: q) {
|
|
callback(error)
|
|
}
|
|
}
|
|
|
|
public func makeIterator() -> EventLoopIterator {
|
|
return EventLoopIterator(self.eventLoops)
|
|
}
|
|
}
|