Support preconditionInEventLoop. (#11)
Motivation: In SwiftNIO 1.11 we shipped improved interfaces for Channels to support asserting being in the event loop. This is necessary because Dispatch provides no non-precondition way to 100% guarantee that you are on a specific queue, which is a requirement for accurate behaviour of inEventLoop. Modifications: - Added an implementation of preconditionInEventLoop. - Changed all assertions to use new interface. - Required NIO 1.11. Result: Accurate assertions
This commit is contained in:
parent
9e8685be61
commit
a9cece8a6d
|
|
@ -23,7 +23,7 @@ let package = Package(
|
|||
.executable(name: "NIOTSHTTPServer", targets: ["NIOTSHTTPServer"]),
|
||||
],
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/apple/swift-nio.git", from: "1.8.0"),
|
||||
.package(url: "https://github.com/apple/swift-nio.git", from: "1.11.0"),
|
||||
],
|
||||
targets: [
|
||||
.target(name: "NIOTransportServices",
|
||||
|
|
|
|||
|
|
@ -276,7 +276,7 @@ extension NIOTSConnectionChannel: Channel {
|
|||
}
|
||||
|
||||
private func setOption0<T: ChannelOption>(option: T, value: T.OptionType) throws {
|
||||
assert(eventLoop.inEventLoop)
|
||||
self.eventLoop.assertInEventLoop()
|
||||
|
||||
guard !self.closed else {
|
||||
throw ChannelError.ioOnClosedChannel
|
||||
|
|
@ -320,7 +320,7 @@ extension NIOTSConnectionChannel: Channel {
|
|||
}
|
||||
|
||||
func getOption0<T: ChannelOption>(option: T) throws -> T.OptionType {
|
||||
assert(eventLoop.inEventLoop)
|
||||
self.eventLoop.assertInEventLoop()
|
||||
|
||||
guard !self.closed else {
|
||||
throw ChannelError.ioOnClosedChannel
|
||||
|
|
|
|||
|
|
@ -71,6 +71,12 @@ internal class NIOTSEventLoop: QoSEventLoop {
|
|||
return self.state == .active
|
||||
}
|
||||
|
||||
/// Returns whether the currently executing code is on the event loop.
|
||||
///
|
||||
/// Due to limitations in Dispatch's API, this check is pessimistic: there are circumstances where a perfect
|
||||
/// implementation *could* return `true`, but this version will be unable to prove that and will return `false`.
|
||||
/// If you need to write an assertion about being in the event loop that must be correct, use SwiftNIO 1.11 or
|
||||
/// later and call `preconditionInEventLoop` and `assertInEventLoop`.
|
||||
public var inEventLoop: Bool {
|
||||
return DispatchQueue.getSpecific(key: self.inQueueKey) == self.loopID
|
||||
}
|
||||
|
|
@ -127,6 +133,10 @@ internal class NIOTSEventLoop: QoSEventLoop {
|
|||
queue.async { callback(error) }
|
||||
}
|
||||
}
|
||||
|
||||
func preconditionInEventLoop(file: StaticString, line: UInt) {
|
||||
dispatchPrecondition(condition: .onQueue(self.loop))
|
||||
}
|
||||
}
|
||||
|
||||
extension NIOTSEventLoop {
|
||||
|
|
|
|||
|
|
@ -276,16 +276,16 @@ private class AcceptHandler: ChannelInboundHandler {
|
|||
@inline(__always)
|
||||
func setupChildChannel() -> EventLoopFuture<Void> {
|
||||
return self.childChannelOptions.applyAll(channel: newChannel).then { () -> EventLoopFuture<Void> in
|
||||
assert(childLoop.inEventLoop)
|
||||
childLoop.assertInEventLoop()
|
||||
return childInitializer(newChannel)
|
||||
}
|
||||
}
|
||||
|
||||
@inline(__always)
|
||||
func fireThroughPipeline(_ future: EventLoopFuture<Void>) {
|
||||
assert(ctxEventLoop.inEventLoop)
|
||||
ctxEventLoop.assertInEventLoop()
|
||||
future.then { (_) -> EventLoopFuture<Void> in
|
||||
assert(ctxEventLoop.inEventLoop)
|
||||
ctxEventLoop.assertInEventLoop()
|
||||
guard ctx.channel.isActive else {
|
||||
return newChannel.close().thenThrowing {
|
||||
throw ChannelError.ioOnClosedChannel
|
||||
|
|
@ -294,7 +294,7 @@ private class AcceptHandler: ChannelInboundHandler {
|
|||
ctx.fireChannelRead(self.wrapInboundOut(newChannel))
|
||||
return ctx.eventLoop.newSucceededFuture(result: ())
|
||||
}.whenFailure { error in
|
||||
assert(ctx.eventLoop.inEventLoop)
|
||||
ctx.eventLoop.assertInEventLoop()
|
||||
_ = newChannel.close()
|
||||
ctx.fireErrorCaught(error)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ extension NIOTSListenerChannel: Channel {
|
|||
}
|
||||
|
||||
private func setOption0<T: ChannelOption>(option: T, value: T.OptionType) throws {
|
||||
assert(eventLoop.inEventLoop)
|
||||
self.eventLoop.assertInEventLoop()
|
||||
|
||||
guard !self.closed else {
|
||||
throw ChannelError.ioOnClosedChannel
|
||||
|
|
@ -178,7 +178,7 @@ extension NIOTSListenerChannel: Channel {
|
|||
}
|
||||
|
||||
func getOption0<T: ChannelOption>(option: T) throws -> T.OptionType {
|
||||
assert(eventLoop.inEventLoop)
|
||||
self.eventLoop.assertInEventLoop()
|
||||
|
||||
guard !self.closed else {
|
||||
throw ChannelError.ioOnClosedChannel
|
||||
|
|
|
|||
Loading…
Reference in New Issue