Remove not on eventLoop precondition for NIOPipeBootstrap (#1977)
Motivation: Currently you cannot create a NIOPipeBootstrap when you are on an event loop due to a precondition check. This check seeks to prevent consumers of the API from passing in a file descriptor thats referencing a file on disk or on the network. The method at hand 'validateFileDescriptorIsNotAFile' uses fstat, which potentially could block the event loop especially if the fd is referencing a file over the network. This check however prevents certain use cases of SwiftNIO, where the downsides of a consumer of this api blocking their own event loop do not weigh in against preventing an entire use case from SwiftNIO. Modifications: Removed the precondition Result: After this change it will be possible to feed file descriptors into the bootstrap which potentially block the current event loop. A potential (portable) replacement for fstat still has to be found in order to solve this problem completely.
This commit is contained in:
parent
d906b890d5
commit
787e2287d0
|
@ -1023,8 +1023,6 @@ public final class NIOPipeBootstrap {
|
|||
}
|
||||
|
||||
private func validateFileDescriptorIsNotAFile(_ descriptor: CInt) throws {
|
||||
precondition(MultiThreadedEventLoopGroup.currentEventLoop == nil,
|
||||
"limitation in SwiftNIO: cannot bootstrap PipeChannel on EventLoop")
|
||||
var s: stat = .init()
|
||||
try withUnsafeMutablePointer(to: &s) { ptr in
|
||||
try Posix.fstat(descriptor: descriptor, outStat: ptr)
|
||||
|
|
|
@ -39,6 +39,7 @@ extension BootstrapTest {
|
|||
("testPreConnectedSocketSetsChannelOptionsBeforeChannelInitializer", testPreConnectedSocketSetsChannelOptionsBeforeChannelInitializer),
|
||||
("testDatagramBootstrapSetsChannelOptionsBeforeChannelInitializer", testDatagramBootstrapSetsChannelOptionsBeforeChannelInitializer),
|
||||
("testPipeBootstrapSetsChannelOptionsBeforeChannelInitializer", testPipeBootstrapSetsChannelOptionsBeforeChannelInitializer),
|
||||
("testPipeBootstrapInEventLoop", testPipeBootstrapInEventLoop),
|
||||
("testServerBootstrapAddsAcceptHandlerAfterServerChannelInitialiser", testServerBootstrapAddsAcceptHandlerAfterServerChannelInitialiser),
|
||||
("testClientBootstrapValidatesWorkingELGsCorrectly", testClientBootstrapValidatesWorkingELGsCorrectly),
|
||||
("testClientBootstrapRejectsNotWorkingELGsCorrectly", testClientBootstrapRejectsNotWorkingELGsCorrectly),
|
||||
|
|
|
@ -389,6 +389,32 @@ class BootstrapTest: XCTestCase {
|
|||
})
|
||||
}
|
||||
|
||||
func testPipeBootstrapInEventLoop() {
|
||||
let testGrp = DispatchGroup()
|
||||
testGrp.enter()
|
||||
|
||||
let eventLoop = self.group.next()
|
||||
|
||||
eventLoop.execute {
|
||||
do {
|
||||
let pipe = Pipe()
|
||||
let readHandle = NIOFileHandle(descriptor: pipe.fileHandleForReading.fileDescriptor)
|
||||
let writeHandle = NIOFileHandle(descriptor: pipe.fileHandleForWriting.fileDescriptor)
|
||||
_ = NIOPipeBootstrap(group: self.group)
|
||||
.withPipes(inputDescriptor: try readHandle.takeDescriptorOwnership(), outputDescriptor: try writeHandle.takeDescriptorOwnership())
|
||||
.flatMap({ channel in
|
||||
channel.close()
|
||||
}).always({ _ in
|
||||
testGrp.leave()
|
||||
})
|
||||
} catch {
|
||||
XCTFail("Failed to bootstrap pipechannel in eventloop: \(error)")
|
||||
testGrp.leave()
|
||||
}
|
||||
}
|
||||
testGrp.wait()
|
||||
}
|
||||
|
||||
func testServerBootstrapAddsAcceptHandlerAfterServerChannelInitialiser() {
|
||||
// It's unclear if this is the right solution, see https://github.com/apple/swift-nio/issues/1392
|
||||
let group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
|
||||
|
|
Loading…
Reference in New Issue