Skip to content

Commit 035962e

Browse files
weissiLukasa
authored andcommitted
EventLoop.assertInEventLoop and preconditionInEventLoop (#644)
Motivation: Dispatch can only precondition that code is run from a certain queue, it can't return if code is running on a certain queue. To support that this introduces new EventLoop.assertInEventLoop and EventLoop.preconditionInEventLoop methods instead of assert(eventLoop.inEventLoop). Modifications: add EventLoop.assertInEventLoop and EventLoop.preconditionInEventLoop Result: better support for Network.framework in NIOTS
1 parent 26bee21 commit 035962e

File tree

8 files changed

+125
-108
lines changed

8 files changed

+125
-108
lines changed

Sources/NIO/BaseSocketChannel.swift

Lines changed: 39 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ private struct SocketChannelLifecycleManager {
4343

4444
private var currentState: State = .fresh {
4545
didSet {
46-
assert(self.eventLoop.inEventLoop)
46+
self.eventLoop.assertInEventLoop()
4747
switch (oldValue, self.currentState) {
4848
case (_, .activated):
4949
self.isActiveAtomic.store(true)
@@ -90,7 +90,7 @@ private struct SocketChannelLifecycleManager {
9090
// MARK: private API
9191
@inline(__always) // we need to return a closure here and to not suffer from a potential allocation for that this must be inlined
9292
private mutating func moveState(event: Event, promise: EventLoopPromise<Void>?) -> ((ChannelPipeline) -> Void) {
93-
assert(self.eventLoop.inEventLoop)
93+
self.eventLoop.assertInEventLoop()
9494

9595
switch (self.currentState, event) {
9696
// origin: .fresh
@@ -158,12 +158,12 @@ private struct SocketChannelLifecycleManager {
158158

159159
// MARK: convenience properties
160160
internal var isActive: Bool {
161-
assert(self.eventLoop.inEventLoop)
161+
self.eventLoop.assertInEventLoop()
162162
return self.currentState == .activated
163163
}
164164

165165
internal var isPreRegistered: Bool {
166-
assert(self.eventLoop.inEventLoop)
166+
self.eventLoop.assertInEventLoop()
167167
switch self.currentState {
168168
case .fresh, .closed:
169169
return false
@@ -173,7 +173,7 @@ private struct SocketChannelLifecycleManager {
173173
}
174174

175175
internal var isRegisteredFully: Bool {
176-
assert(self.eventLoop.inEventLoop)
176+
self.eventLoop.assertInEventLoop()
177177
switch self.currentState {
178178
case .fresh, .closed, .preRegistered:
179179
return false
@@ -185,7 +185,7 @@ private struct SocketChannelLifecycleManager {
185185
/// Returns whether the underlying file descriptor is open. This property will always be true (even before registration)
186186
/// until the Channel is closed.
187187
internal var isOpen: Bool {
188-
assert(self.eventLoop.inEventLoop)
188+
self.eventLoop.assertInEventLoop()
189189
return self.currentState != .closed
190190
}
191191
}
@@ -229,13 +229,13 @@ class BaseSocketChannel<T: BaseSocket>: SelectableChannel, ChannelCore {
229229
private var autoRead: Bool = true
230230
private var lifecycleManager: SocketChannelLifecycleManager {
231231
didSet {
232-
assert(self.eventLoop.inEventLoop)
232+
self.eventLoop.assertInEventLoop()
233233
}
234234
}
235235

236236
private var bufferAllocator: ByteBufferAllocator = ByteBufferAllocator() {
237237
didSet {
238-
assert(self.eventLoop.inEventLoop)
238+
self.eventLoop.assertInEventLoop()
239239
self.bufferAllocatorCached.store(Box(self.bufferAllocator))
240240
}
241241
}
@@ -287,12 +287,12 @@ class BaseSocketChannel<T: BaseSocket>: SelectableChannel, ChannelCore {
287287

288288
/// `false` if the whole `Channel` is closed and so no more IO operation can be done.
289289
var isOpen: Bool {
290-
assert(eventLoop.inEventLoop)
290+
self.eventLoop.assertInEventLoop()
291291
return self.lifecycleManager.isOpen
292292
}
293293

294294
var isRegistered: Bool {
295-
assert(self.eventLoop.inEventLoop)
295+
self.eventLoop.assertInEventLoop()
296296
return self.lifecycleManager.isPreRegistered
297297
}
298298

@@ -401,15 +401,15 @@ class BaseSocketChannel<T: BaseSocket>: SelectableChannel, ChannelCore {
401401
}
402402

403403
public final func localAddress0() throws -> SocketAddress {
404-
assert(self.eventLoop.inEventLoop)
404+
self.eventLoop.assertInEventLoop()
405405
guard self.isOpen else {
406406
throw ChannelError.ioOnClosedChannel
407407
}
408408
return try self.socket.localAddress()
409409
}
410410

411411
public final func remoteAddress0() throws -> SocketAddress {
412-
assert(self.eventLoop.inEventLoop)
412+
self.eventLoop.assertInEventLoop()
413413
guard self.isOpen else {
414414
throw ChannelError.ioOnClosedChannel
415415
}
@@ -420,7 +420,7 @@ class BaseSocketChannel<T: BaseSocket>: SelectableChannel, ChannelCore {
420420
///
421421
/// - returns: If this socket should be registered for write notifications. Ie. `IONotificationState.register` if _not_ all data could be written, so notifications are necessary; and `IONotificationState.unregister` if everything was written and we don't need to be notified about writability at the moment.
422422
func flushNow() -> IONotificationState {
423-
assert(self.eventLoop.inEventLoop)
423+
self.eventLoop.assertInEventLoop()
424424
// Guard against re-entry as data that will be put into `pendingWrites` will just be picked up by
425425
// `writeToSocket`.
426426
guard !self.inFlushNow && self.isOpen else {
@@ -475,7 +475,7 @@ class BaseSocketChannel<T: BaseSocket>: SelectableChannel, ChannelCore {
475475
}
476476

477477
func setOption0<T: ChannelOption>(option: T, value: T.OptionType) throws {
478-
assert(eventLoop.inEventLoop)
478+
self.eventLoop.assertInEventLoop()
479479

480480
guard isOpen else {
481481
throw ChannelError.ioOnClosedChannel
@@ -523,7 +523,7 @@ class BaseSocketChannel<T: BaseSocket>: SelectableChannel, ChannelCore {
523523
}
524524

525525
func getOption0<T: ChannelOption>(option: T) throws -> T.OptionType {
526-
assert(eventLoop.inEventLoop)
526+
self.eventLoop.assertInEventLoop()
527527

528528
guard isOpen else {
529529
throw ChannelError.ioOnClosedChannel
@@ -550,7 +550,7 @@ class BaseSocketChannel<T: BaseSocket>: SelectableChannel, ChannelCore {
550550
///
551551
/// - returns: `true` if `readPending` is `true`, `false` otherwise.
552552
@discardableResult func readIfNeeded0() -> Bool {
553-
assert(eventLoop.inEventLoop)
553+
self.eventLoop.assertInEventLoop()
554554
if !self.lifecycleManager.isActive {
555555
return false
556556
}
@@ -563,7 +563,7 @@ class BaseSocketChannel<T: BaseSocket>: SelectableChannel, ChannelCore {
563563

564564
// Methods invoked from the HeadHandler of the ChannelPipeline
565565
public func bind0(to address: SocketAddress, promise: EventLoopPromise<Void>?) {
566-
assert(eventLoop.inEventLoop)
566+
self.eventLoop.assertInEventLoop()
567567

568568
guard self.isOpen else {
569569
promise?.fail(error: ChannelError.ioOnClosedChannel)
@@ -581,7 +581,7 @@ class BaseSocketChannel<T: BaseSocket>: SelectableChannel, ChannelCore {
581581
}
582582

583583
public final func write0(_ data: NIOAny, promise: EventLoopPromise<Void>?) {
584-
assert(eventLoop.inEventLoop)
584+
self.eventLoop.assertInEventLoop()
585585

586586
guard self.isOpen else {
587587
// Channel was already closed, fail the promise and not even queue it.
@@ -598,7 +598,7 @@ class BaseSocketChannel<T: BaseSocket>: SelectableChannel, ChannelCore {
598598
}
599599

600600
private func registerForWritable() {
601-
assert(eventLoop.inEventLoop)
601+
self.eventLoop.assertInEventLoop()
602602

603603
guard !self.interestedEvent.contains(.write) else {
604604
// nothing to do if we were previously interested in write
@@ -608,7 +608,7 @@ class BaseSocketChannel<T: BaseSocket>: SelectableChannel, ChannelCore {
608608
}
609609

610610
func unregisterForWritable() {
611-
assert(eventLoop.inEventLoop)
611+
self.eventLoop.assertInEventLoop()
612612

613613
guard self.interestedEvent.contains(.write) else {
614614
// nothing to do if we were not previously interested in write
@@ -618,7 +618,7 @@ class BaseSocketChannel<T: BaseSocket>: SelectableChannel, ChannelCore {
618618
}
619619

620620
public final func flush0() {
621-
assert(eventLoop.inEventLoop)
621+
self.eventLoop.assertInEventLoop()
622622

623623
guard self.isOpen else {
624624
return
@@ -637,7 +637,7 @@ class BaseSocketChannel<T: BaseSocket>: SelectableChannel, ChannelCore {
637637
}
638638

639639
public func read0() {
640-
assert(eventLoop.inEventLoop)
640+
self.eventLoop.assertInEventLoop()
641641

642642
guard self.isOpen else {
643643
return
@@ -650,15 +650,15 @@ class BaseSocketChannel<T: BaseSocket>: SelectableChannel, ChannelCore {
650650
}
651651

652652
private final func pauseRead0() {
653-
assert(eventLoop.inEventLoop)
653+
self.eventLoop.assertInEventLoop()
654654

655655
if self.lifecycleManager.isPreRegistered {
656656
unregisterForReadable()
657657
}
658658
}
659659

660660
private final func registerForReadable() {
661-
assert(eventLoop.inEventLoop)
661+
self.eventLoop.assertInEventLoop()
662662
assert(self.lifecycleManager.isRegisteredFully)
663663

664664
guard !self.lifecycleManager.hasSeenEOFNotification else {
@@ -674,7 +674,7 @@ class BaseSocketChannel<T: BaseSocket>: SelectableChannel, ChannelCore {
674674
}
675675

676676
internal final func unregisterForReadable() {
677-
assert(eventLoop.inEventLoop)
677+
self.eventLoop.assertInEventLoop()
678678
assert(self.lifecycleManager.isRegisteredFully)
679679

680680
guard self.interestedEvent.contains(.read) else {
@@ -693,7 +693,7 @@ class BaseSocketChannel<T: BaseSocket>: SelectableChannel, ChannelCore {
693693
/// - mode: The close mode, must be `.all` for `BaseSocketChannel`
694694
/// - promise: The promise that gets notified about the result of the deregistration/close operations.
695695
public func close0(error: Error, mode: CloseMode, promise: EventLoopPromise<Void>?) {
696-
assert(eventLoop.inEventLoop)
696+
self.eventLoop.assertInEventLoop()
697697

698698
guard self.isOpen else {
699699
promise?.fail(error: ChannelError.alreadyClosed)
@@ -765,7 +765,7 @@ class BaseSocketChannel<T: BaseSocket>: SelectableChannel, ChannelCore {
765765

766766

767767
public final func register0(promise: EventLoopPromise<Void>?) {
768-
assert(eventLoop.inEventLoop)
768+
self.eventLoop.assertInEventLoop()
769769

770770
guard self.isOpen else {
771771
promise?.fail(error: ChannelError.ioOnClosedChannel)
@@ -792,7 +792,7 @@ class BaseSocketChannel<T: BaseSocket>: SelectableChannel, ChannelCore {
792792
}
793793

794794
public final func registerAlreadyConfigured0(promise: EventLoopPromise<Void>?) {
795-
assert(self.eventLoop.inEventLoop)
795+
self.eventLoop.assertInEventLoop()
796796
assert(self.isOpen)
797797
assert(!self.lifecycleManager.isActive)
798798
let registerPromise: EventLoopPromise<Void> = self.eventLoop.newPromise()
@@ -821,7 +821,7 @@ class BaseSocketChannel<T: BaseSocket>: SelectableChannel, ChannelCore {
821821

822822
// Methods invoked from the EventLoop itself
823823
public final func writable() {
824-
assert(self.eventLoop.inEventLoop)
824+
self.eventLoop.assertInEventLoop()
825825
assert(self.isOpen)
826826

827827
self.finishConnect() // If we were connecting, that has finished.
@@ -832,7 +832,7 @@ class BaseSocketChannel<T: BaseSocket>: SelectableChannel, ChannelCore {
832832
}
833833

834834
private func finishConnect() {
835-
assert(eventLoop.inEventLoop)
835+
self.eventLoop.assertInEventLoop()
836836
assert(self.lifecycleManager.isPreRegistered)
837837

838838
if let connectPromise = self.pendingConnect {
@@ -857,7 +857,7 @@ class BaseSocketChannel<T: BaseSocket>: SelectableChannel, ChannelCore {
857857
}
858858

859859
private func finishWritable() {
860-
assert(eventLoop.inEventLoop)
860+
self.eventLoop.assertInEventLoop()
861861

862862
if self.isOpen {
863863
assert(self.lifecycleManager.isPreRegistered)
@@ -950,7 +950,7 @@ class BaseSocketChannel<T: BaseSocket>: SelectableChannel, ChannelCore {
950950

951951
@discardableResult
952952
private final func readable0() -> ReadStreamState {
953-
assert(eventLoop.inEventLoop)
953+
self.eventLoop.assertInEventLoop()
954954
assert(self.lifecycleManager.isActive)
955955

956956
defer {
@@ -1016,7 +1016,7 @@ class BaseSocketChannel<T: BaseSocket>: SelectableChannel, ChannelCore {
10161016
}
10171017

10181018
internal final func updateCachedAddressesFromSocket(updateLocal: Bool = true, updateRemote: Bool = true) {
1019-
assert(self.eventLoop.inEventLoop)
1019+
self.eventLoop.assertInEventLoop()
10201020
assert(updateLocal || updateRemote)
10211021
let cached = addressesCached.load().value
10221022
let local = updateLocal ? try? self.localAddress0() : cached.local
@@ -1025,12 +1025,12 @@ class BaseSocketChannel<T: BaseSocket>: SelectableChannel, ChannelCore {
10251025
}
10261026

10271027
internal final func unsetCachedAddressesFromSocket() {
1028-
assert(self.eventLoop.inEventLoop)
1028+
self.eventLoop.assertInEventLoop()
10291029
self.addressesCached.store(Box((local: nil, remote: nil)))
10301030
}
10311031

10321032
public final func connect0(to address: SocketAddress, promise: EventLoopPromise<Void>?) {
1033-
assert(eventLoop.inEventLoop)
1033+
self.eventLoop.assertInEventLoop()
10341034

10351035
guard self.isOpen else {
10361036
promise?.fail(error: ChannelError.ioOnClosedChannel)
@@ -1087,7 +1087,7 @@ class BaseSocketChannel<T: BaseSocket>: SelectableChannel, ChannelCore {
10871087
}
10881088

10891089
private final func safeReregister(interested: SelectorEventSet) {
1090-
assert(eventLoop.inEventLoop)
1090+
self.eventLoop.assertInEventLoop()
10911091
assert(self.lifecycleManager.isRegisteredFully)
10921092

10931093
guard self.isOpen else {
@@ -1108,7 +1108,7 @@ class BaseSocketChannel<T: BaseSocket>: SelectableChannel, ChannelCore {
11081108
}
11091109

11101110
private func safeRegister(interested: SelectorEventSet) throws {
1111-
assert(eventLoop.inEventLoop)
1111+
self.eventLoop.assertInEventLoop()
11121112
assert(!self.lifecycleManager.isRegisteredFully)
11131113

11141114
guard self.isOpen else {
@@ -1126,7 +1126,7 @@ class BaseSocketChannel<T: BaseSocket>: SelectableChannel, ChannelCore {
11261126
}
11271127

11281128
final func becomeFullyRegistered0() throws {
1129-
assert(self.eventLoop.inEventLoop)
1129+
self.eventLoop.assertInEventLoop()
11301130
assert(self.lifecycleManager.isPreRegistered)
11311131
assert(!self.lifecycleManager.isRegisteredFully)
11321132

@@ -1136,7 +1136,7 @@ class BaseSocketChannel<T: BaseSocket>: SelectableChannel, ChannelCore {
11361136
}
11371137

11381138
final func becomeActive0(promise: EventLoopPromise<Void>?) {
1139-
assert(self.eventLoop.inEventLoop)
1139+
self.eventLoop.assertInEventLoop()
11401140
assert(self.lifecycleManager.isPreRegistered)
11411141
if !self.lifecycleManager.isRegisteredFully {
11421142
do {

Sources/NIO/Bootstrap.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -259,23 +259,23 @@ public final class ServerBootstrap {
259259
@inline(__always)
260260
func setupChildChannel() -> EventLoopFuture<Void> {
261261
return self.childChannelOptions.applyAll(channel: accepted).then { () -> EventLoopFuture<Void> in
262-
assert(childEventLoop.inEventLoop)
262+
childEventLoop.assertInEventLoop()
263263
return childChannelInit(accepted)
264264
}
265265
}
266266

267267
@inline(__always)
268268
func fireThroughPipeline(_ future: EventLoopFuture<Void>) {
269-
assert(ctxEventLoop.inEventLoop)
269+
ctxEventLoop.assertInEventLoop()
270270
future.then { (_) -> EventLoopFuture<Void> in
271-
assert(ctxEventLoop.inEventLoop)
271+
ctxEventLoop.assertInEventLoop()
272272
guard !ctx.pipeline.destroyed else {
273273
return ctx.eventLoop.newFailedFuture(error: ChannelError.ioOnClosedChannel)
274274
}
275275
ctx.fireChannelRead(data)
276276
return ctx.eventLoop.newSucceededFuture(result: ())
277277
}.whenFailure { error in
278-
assert(ctx.eventLoop.inEventLoop)
278+
ctxEventLoop.assertInEventLoop()
279279
self.closeAndFire(ctx: ctx, accepted: accepted, err: error)
280280
}
281281
}
@@ -308,9 +308,9 @@ private extension Channel {
308308
// In many cases `body` must be _synchronously_ follow `register`, otherwise in our current
309309
// implementation, `epoll` will send us `EPOLLHUP`. To have it run synchronously, we need to invoke the
310310
// `then` on the eventloop that the `register` will succeed on.
311-
assert(self.eventLoop.inEventLoop)
311+
self.eventLoop.assertInEventLoop()
312312
return self.register().then {
313-
assert(self.eventLoop.inEventLoop)
313+
self.eventLoop.assertInEventLoop()
314314
return body(self)
315315
}
316316
}
@@ -507,7 +507,7 @@ public final class ClientBootstrap {
507507

508508
@inline(__always)
509509
func setupChannel() -> EventLoopFuture<Channel> {
510-
assert(eventLoop.inEventLoop)
510+
eventLoop.assertInEventLoop()
511511
channelInitializer(channel).then {
512512
channelOptions.applyAll(channel: channel)
513513
}.then {

0 commit comments

Comments
 (0)