         }
     }
 
-    func preconditionInEventLoop(file: StaticString, line: UInt) {
+    public func preconditionInEventLoop(_ message: @autoclosure() -> String, file: StaticString, line: UInt) {
+        /// `dispatchPrecondition(condition:)` is unable to accept an error message for the failure case, and we
+        /// can not safely rely on `self.inEventLoop` in this implementation. Any message provided by the caller
+        /// must therefore be ignored. We do not foresee ever being able to fix this behavior, given the design
+        /// constraints of the respective subsystems.
         dispatchPrecondition(condition: .onQueue(self.loop))
+    }
+
+    public func preconditionNotInEventLoop(_ message: @autoclosure() -> String = "", file: StaticString, line: UInt) {
+        /// As in our counterpart method, we can't do anything with the `message` parameter. See above for details.
+        dispatchPrecondition(condition: .notOnQueue(self.loop))
     }
 }
 

    case closed
}


@available(OSX 10.14, iOS 12.0, tvOS 12.0, watchOS 6.0, *)
internal class NIOTSEventLoop: QoSEventLoop {
    private let loop: DispatchQueue

    /// 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`.
    ///
    /// Further detail: The use of `DispatchQueue.sync(execute:)` to submit a block to a queue synchronously has the
    /// effect of creating a state where the currently executing code is on two queues simultaneously - the one which
    /// submitted the block, and the one on which the block runs. If another synchronous block is dispatched to a
    /// third queue, that block is effectively running all three at once. Unfortunately, libdispatch maintains only
    /// one "current" queue at a time as far as `DispatchQueue.getSpecific(key:)` is concerned, and it's always the
    /// one actually executing code at the time. Therefore the queue belonging to the original event loop can't be
    /// detected using its queue-specific data. No alternative API for the purpose exists (aside from assertions via
    /// `dispatchPrecondition(condition:)`). Under these circumstances, `inEventLoop` will incorrectly be `false`,
    /// even though the current code _is_ actually on the loop's queue. The only way to avoid this is to ensure no
    /// callers ever use synchronous dispatch (which is impossible to enforce), or to hope that a future version of
    /// libdispatch will provide a solution.
    public var inEventLoop: Bool {
        return DispatchQueue.getSpecific(key: self.inQueueKey) == self.loopID
    }
