@@ -13,7 +13,8 @@ import type {
13
13
VerifyCallback ,
14
14
} from './types' ;
15
15
import type { Connection , ConnectionErrorCode , SendInfo } from './native/types' ;
16
- import { Lock , LockBox , Monitor , RWLockWriter } from '@matrixai/async-locks' ;
16
+ import type { Monitor } from '@matrixai/async-locks' ;
17
+ import { Lock , LockBox , RWLockWriter } from '@matrixai/async-locks' ;
17
18
import {
18
19
ready ,
19
20
running ,
@@ -515,29 +516,34 @@ class QUICConnection extends EventTarget {
515
516
this . logger . debug ( 'streams destroyed' ) ;
516
517
this . stopKeepAliveIntervalTimer ( ) ;
517
518
518
- mon = mon ?? new Monitor < RWLockWriter > ( this . lockbox , RWLockWriter ) ;
519
519
// Trigger closing connection in the background and await close later.
520
- void mon . withF ( this . lockCode , async ( mon ) => {
521
- // If this is already closed, then `Done` will be thrown
522
- // Otherwise it can send `CONNECTION_CLOSE` frame
523
- // This can be 0x1c close at the QUIC layer or no errors
524
- // Or it can be 0x1d for application close with an error
525
- // Upon receiving a `CONNECTION_CLOSE`, you can send back
526
- // 1 packet containing a `CONNECTION_CLOSE` frame too
527
- // (with `NO_ERROR` code if appropriate)
528
- // It must enter into a draining state, and no other packets can be sent
529
- try {
530
- this . conn . close ( applicationError , errorCode , Buffer . from ( errorMessage ) ) ;
531
- // If we get a `Done` exception we don't bother calling send
532
- // The send only gets sent if the `Done` is not the case
533
- await this . send ( mon ) ;
534
- } catch ( e ) {
535
- // Ignore 'Done' if already closed
536
- if ( e . message !== 'Done' ) {
537
- // No other exceptions are expected
538
- never ( ) ;
520
+ void utils . withMonitor ( mon , this . lockbox , RWLockWriter , async ( mon ) => {
521
+ await mon . withF ( this . lockCode , async ( mon ) => {
522
+ // If this is already closed, then `Done` will be thrown
523
+ // Otherwise it can send `CONNECTION_CLOSE` frame
524
+ // This can be 0x1c close at the QUIC layer or no errors
525
+ // Or it can be 0x1d for application close with an error
526
+ // Upon receiving a `CONNECTION_CLOSE`, you can send back
527
+ // 1 packet containing a `CONNECTION_CLOSE` frame too
528
+ // (with `NO_ERROR` code if appropriate)
529
+ // It must enter into a draining state, and no other packets can be sent
530
+ try {
531
+ this . conn . close (
532
+ applicationError ,
533
+ errorCode ,
534
+ Buffer . from ( errorMessage ) ,
535
+ ) ;
536
+ // If we get a `Done` exception we don't bother calling send
537
+ // The send only gets sent if the `Done` is not the case
538
+ await this . send ( mon ) ;
539
+ } catch ( e ) {
540
+ // Ignore 'Done' if already closed
541
+ if ( e . message !== 'Done' ) {
542
+ // No other exceptions are expected
543
+ never ( ) ;
544
+ }
539
545
}
540
- }
546
+ } ) ;
541
547
} ) ;
542
548
543
549
if ( this . conn . isClosed ( ) ) {
@@ -750,17 +756,14 @@ class QUICConnection extends EventTarget {
750
756
* Any errors must be emitted as events.
751
757
* @internal
752
758
*/
753
- public async send (
754
- mon : Monitor < RWLockWriter > = new Monitor < RWLockWriter > (
755
- this . lockbox ,
756
- RWLockWriter ,
757
- ) ,
758
- ) : Promise < void > {
759
- if ( ! mon . isLocked ( this . lockCode ) ) {
760
- return mon . withF ( this . lockCode , async ( mon ) => {
761
- return this . send ( mon ) ;
762
- } ) ;
763
- }
759
+ public async send ( mon ?: Monitor < RWLockWriter > ) : Promise < void > {
760
+ await utils . withMonitor ( mon , this . lockbox , RWLockWriter , async ( mon ) => {
761
+ if ( ! mon . isLocked ( this . lockCode ) ) {
762
+ return mon . withF ( this . lockCode , async ( mon ) => {
763
+ return this . send ( mon ) ;
764
+ } ) ;
765
+ }
766
+ } ) ;
764
767
765
768
const sendBuffer = new Uint8Array ( quiche . MAX_DATAGRAM_SIZE ) ;
766
769
let sendLength : number ;
@@ -914,17 +917,15 @@ class QUICConnection extends EventTarget {
914
917
this . resolveClosedP ( ) ;
915
918
// If we are still running and not stopping then we need to stop
916
919
if ( this [ running ] && this [ status ] !== 'stopping' ) {
917
- const mon = new Monitor ( this . lockbox , RWLockWriter ) ;
918
920
// Background stopping, we don't want to block the timer resolving
919
- void this . stop ( { force : true } , mon ) ;
921
+ void this . stop ( { force : true } ) ;
920
922
}
921
923
logger . debug ( 'CLEANING UP TIMER' ) ;
922
924
return ;
923
925
}
924
926
925
- const mon = new Monitor ( this . lockbox , RWLockWriter ) ;
926
927
// There may be data to send after timing out
927
- void this . send ( mon ) ;
928
+ void this . send ( ) ;
928
929
929
930
// Note that a `0` timeout is still a valid timeout
930
931
const timeout = this . conn . timeout ( ) ;
@@ -982,9 +983,8 @@ class QUICConnection extends EventTarget {
982
983
// Intelligently schedule a PING frame.
983
984
// If the connection has already sent ack-eliciting frames
984
985
// then this is a noop.
985
- const mon = new Monitor ( this . lockbox , RWLockWriter ) ;
986
986
this . conn . sendAckEliciting ( ) ;
987
- await this . send ( mon ) ;
987
+ await this . send ( ) ;
988
988
this . keepAliveIntervalTimer = new Timer ( {
989
989
delay : ms ,
990
990
handler : keepAliveHandler ,
0 commit comments