@@ -185,7 +185,7 @@ final class HTTP1ClientChannelHandler: ChannelDuplexHandler {
185185 self . runTimeoutAction ( timeoutAction, context: context)
186186 }
187187
188- req. willExecuteRequest ( self )
188+ req. willExecuteRequest ( self . requestExecutor )
189189
190190 let action = self . state. runNewRequest (
191191 head: req. requestHead,
@@ -323,7 +323,7 @@ final class HTTP1ClientChannelHandler: ChannelDuplexHandler {
323323 case . sendRequestEnd( let writePromise, let shouldClose) :
324324 let writePromise = writePromise ?? context. eventLoop. makePromise ( of: Void . self)
325325 // We need to defer succeeding the old request to avoid ordering issues
326- writePromise. futureResult. hop ( to: context. eventLoop) . whenComplete { result in
326+ writePromise. futureResult. hop ( to: context. eventLoop) . assumeIsolated ( ) . whenComplete { result in
327327 switch result {
328328 case . success:
329329 // If our final action was `sendRequestEnd`, that means we've already received
@@ -396,7 +396,7 @@ final class HTTP1ClientChannelHandler: ChannelDuplexHandler {
396396 assert ( self . idleReadTimeoutTimer == nil , " Expected there is no timeout timer so far. " )
397397
398398 let timerID = self . currentIdleReadTimeoutTimerID
399- self . idleReadTimeoutTimer = self . eventLoop. scheduleTask ( in: timeAmount) {
399+ self . idleReadTimeoutTimer = self . eventLoop. assumeIsolated ( ) . scheduleTask ( in: timeAmount) {
400400 guard self . currentIdleReadTimeoutTimerID == timerID else { return }
401401 let action = self . state. idleReadTimeoutTriggered ( )
402402 self . run ( action, context: context)
@@ -409,7 +409,7 @@ final class HTTP1ClientChannelHandler: ChannelDuplexHandler {
409409
410410 self . currentIdleReadTimeoutTimerID &+= 1
411411 let timerID = self . currentIdleReadTimeoutTimerID
412- self . idleReadTimeoutTimer = self . eventLoop. scheduleTask ( in: timeAmount) {
412+ self . idleReadTimeoutTimer = self . eventLoop. assumeIsolated ( ) . scheduleTask ( in: timeAmount) {
413413 guard self . currentIdleReadTimeoutTimerID == timerID else { return }
414414 let action = self . state. idleReadTimeoutTriggered ( )
415415 self . run ( action, context: context)
@@ -431,7 +431,7 @@ final class HTTP1ClientChannelHandler: ChannelDuplexHandler {
431431 assert ( self . idleWriteTimeoutTimer == nil , " Expected there is no timeout timer so far. " )
432432
433433 let timerID = self . currentIdleWriteTimeoutTimerID
434- self . idleWriteTimeoutTimer = self . eventLoop. scheduleTask ( in: timeAmount) {
434+ self . idleWriteTimeoutTimer = self . eventLoop. assumeIsolated ( ) . scheduleTask ( in: timeAmount) {
435435 guard self . currentIdleWriteTimeoutTimerID == timerID else { return }
436436 let action = self . state. idleWriteTimeoutTriggered ( )
437437 self . run ( action, context: context)
@@ -443,7 +443,7 @@ final class HTTP1ClientChannelHandler: ChannelDuplexHandler {
443443
444444 self . currentIdleWriteTimeoutTimerID &+= 1
445445 let timerID = self . currentIdleWriteTimeoutTimerID
446- self . idleWriteTimeoutTimer = self . eventLoop. scheduleTask ( in: timeAmount) {
446+ self . idleWriteTimeoutTimer = self . eventLoop. assumeIsolated ( ) . scheduleTask ( in: timeAmount) {
447447 guard self . currentIdleWriteTimeoutTimerID == timerID else { return }
448448 let action = self . state. idleWriteTimeoutTriggered ( )
449449 self . run ( action, context: context)
@@ -461,8 +461,11 @@ final class HTTP1ClientChannelHandler: ChannelDuplexHandler {
461461
462462 // MARK: Private HTTPRequestExecutor
463463
464- private func writeRequestBodyPart0( _ data: IOData , request: HTTPExecutableRequest , promise: EventLoopPromise < Void > ? )
465- {
464+ fileprivate func writeRequestBodyPart0(
465+ _ data: IOData ,
466+ request: HTTPExecutableRequest ,
467+ promise: EventLoopPromise < Void > ?
468+ ) {
466469 guard self . request === request, let context = self . channelContext else {
467470 // Because the HTTPExecutableRequest may run in a different thread to our eventLoop,
468471 // calls from the HTTPExecutableRequest to our ChannelHandler may arrive here after
@@ -481,7 +484,7 @@ final class HTTP1ClientChannelHandler: ChannelDuplexHandler {
481484 self . run ( action, context: context)
482485 }
483486
484- private func finishRequestBodyStream0( _ request: HTTPExecutableRequest , promise: EventLoopPromise < Void > ? ) {
487+ fileprivate func finishRequestBodyStream0( _ request: HTTPExecutableRequest , promise: EventLoopPromise < Void > ? ) {
485488 guard self . request === request, let context = self . channelContext else {
486489 // See code comment in `writeRequestBodyPart0`
487490 promise? . fail ( HTTPClientError . requestStreamCancelled)
@@ -492,7 +495,7 @@ final class HTTP1ClientChannelHandler: ChannelDuplexHandler {
492495 self . run ( action, context: context)
493496 }
494497
495- private func demandResponseBodyStream0( _ request: HTTPExecutableRequest ) {
498+ fileprivate func demandResponseBodyStream0( _ request: HTTPExecutableRequest ) {
496499 guard self . request === request, let context = self . channelContext else {
497500 // See code comment in `writeRequestBodyPart0`
498501 return
@@ -504,7 +507,7 @@ final class HTTP1ClientChannelHandler: ChannelDuplexHandler {
504507 self . run ( action, context: context)
505508 }
506509
507- private func cancelRequest0( _ request: HTTPExecutableRequest ) {
510+ fileprivate func cancelRequest0( _ request: HTTPExecutableRequest ) {
508511 guard self . request === request, let context = self . channelContext else {
509512 // See code comment in `writeRequestBodyPart0`
510513 return
@@ -524,43 +527,39 @@ final class HTTP1ClientChannelHandler: ChannelDuplexHandler {
524527@available ( * , unavailable)
525528extension HTTP1ClientChannelHandler : Sendable { }
526529
527- extension HTTP1ClientChannelHandler : HTTPRequestExecutor {
528- func writeRequestBodyPart( _ data: IOData , request: HTTPExecutableRequest , promise: EventLoopPromise < Void > ? ) {
529- if self . eventLoop. inEventLoop {
530- self . writeRequestBodyPart0 ( data, request: request, promise: promise)
531- } else {
532- self . eventLoop. execute {
533- self . writeRequestBodyPart0 ( data, request: request, promise: promise)
530+ extension HTTP1ClientChannelHandler {
531+ var requestExecutor : RequestExecutor {
532+ RequestExecutor ( self )
533+ }
534+
535+ struct RequestExecutor : HTTPRequestExecutor , Sendable {
536+ private let loopBound : NIOLoopBound < HTTP1ClientChannelHandler >
537+
538+ init ( _ handler: HTTP1ClientChannelHandler ) {
539+ self . loopBound = NIOLoopBound ( handler, eventLoop: handler. eventLoop)
540+ }
541+
542+ func writeRequestBodyPart( _ data: IOData , request: HTTPExecutableRequest , promise: EventLoopPromise < Void > ? ) {
543+ self . loopBound. execute {
544+ $0. writeRequestBodyPart0 ( data, request: request, promise: promise)
534545 }
535546 }
536- }
537547
538- func finishRequestBodyStream( _ request: HTTPExecutableRequest , promise: EventLoopPromise < Void > ? ) {
539- if self . eventLoop. inEventLoop {
540- self . finishRequestBodyStream0 ( request, promise: promise)
541- } else {
542- self . eventLoop. execute {
543- self . finishRequestBodyStream0 ( request, promise: promise)
548+ func finishRequestBodyStream( _ request: HTTPExecutableRequest , promise: EventLoopPromise < Void > ? ) {
549+ self . loopBound. execute {
550+ $0. finishRequestBodyStream0 ( request, promise: promise)
544551 }
545552 }
546- }
547553
548- func demandResponseBodyStream( _ request: HTTPExecutableRequest ) {
549- if self . eventLoop. inEventLoop {
550- self . demandResponseBodyStream0 ( request)
551- } else {
552- self . eventLoop. execute {
553- self . demandResponseBodyStream0 ( request)
554+ func demandResponseBodyStream( _ request: HTTPExecutableRequest ) {
555+ self . loopBound. execute {
556+ $0. demandResponseBodyStream0 ( request)
554557 }
555558 }
556- }
557559
558- func cancelRequest( _ request: HTTPExecutableRequest ) {
559- if self . eventLoop. inEventLoop {
560- self . cancelRequest0 ( request)
561- } else {
562- self . eventLoop. execute {
563- self . cancelRequest0 ( request)
560+ func cancelRequest( _ request: HTTPExecutableRequest ) {
561+ self . loopBound. execute {
562+ $0. cancelRequest0 ( request)
564563 }
565564 }
566565 }
0 commit comments