23
23
from .log import logger
24
24
25
25
26
+ def _test_selector_event (selector , fd , event ):
27
+ # Test if the selector is monitoring 'event' events
28
+ # for the file descriptor 'fd'.
29
+ try :
30
+ key = selector .get_key (fd )
31
+ except KeyError :
32
+ return False
33
+ else :
34
+ return bool (key .events & event )
35
+
36
+
26
37
class BaseSelectorEventLoop (base_events .BaseEventLoop ):
27
38
"""Selector event loop.
28
39
@@ -116,6 +127,9 @@ def _accept_connection(self, protocol_factory, sock,
116
127
sslcontext = None , server = None ):
117
128
try :
118
129
conn , addr = sock .accept ()
130
+ if self ._debug :
131
+ logger .debug ("%r got a new connection from %r: %r" ,
132
+ server , addr , conn )
119
133
conn .setblocking (False )
120
134
except (BlockingIOError , InterruptedError , ConnectionAbortedError ):
121
135
pass # False alarm.
@@ -419,6 +433,26 @@ def __init__(self, loop, sock, protocol, extra, server=None):
419
433
if self ._server is not None :
420
434
self ._server ._attach ()
421
435
436
+ def __repr__ (self ):
437
+ info = [self .__class__ .__name__ , 'fd=%s' % self ._sock_fd ]
438
+ polling = _test_selector_event (self ._loop ._selector ,
439
+ self ._sock_fd , selectors .EVENT_READ )
440
+ if polling :
441
+ info .append ('read=polling' )
442
+ else :
443
+ info .append ('read=idle' )
444
+
445
+ polling = _test_selector_event (self ._loop ._selector ,
446
+ self ._sock_fd , selectors .EVENT_WRITE )
447
+ if polling :
448
+ state = 'polling'
449
+ else :
450
+ state = 'idle'
451
+
452
+ bufsize = self .get_write_buffer_size ()
453
+ info .append ('write=<%s, bufsize=%s>' % (state , bufsize ))
454
+ return '<%s>' % ' ' .join (info )
455
+
422
456
def abort (self ):
423
457
self ._force_close (None )
424
458
@@ -433,7 +467,10 @@ def close(self):
433
467
434
468
def _fatal_error (self , exc , message = 'Fatal error on transport' ):
435
469
# Should be called from exception handler only.
436
- if not isinstance (exc , (BrokenPipeError , ConnectionResetError )):
470
+ if isinstance (exc , (BrokenPipeError , ConnectionResetError )):
471
+ if self ._loop .get_debug ():
472
+ logger .debug ("%r: %s" , self , message , exc_info = True )
473
+ else :
437
474
self ._loop .call_exception_handler ({
438
475
'message' : message ,
439
476
'exception' : exc ,
@@ -492,6 +529,8 @@ def pause_reading(self):
492
529
raise RuntimeError ('Already paused' )
493
530
self ._paused = True
494
531
self ._loop .remove_reader (self ._sock_fd )
532
+ if self ._loop .get_debug ():
533
+ logger .debug ("%r pauses reading" , self )
495
534
496
535
def resume_reading (self ):
497
536
if not self ._paused :
@@ -500,6 +539,8 @@ def resume_reading(self):
500
539
if self ._closing :
501
540
return
502
541
self ._loop .add_reader (self ._sock_fd , self ._read_ready )
542
+ if self ._loop .get_debug ():
543
+ logger .debug ("%r resumes reading" , self )
503
544
504
545
def _read_ready (self ):
505
546
try :
@@ -512,6 +553,8 @@ def _read_ready(self):
512
553
if data :
513
554
self ._protocol .data_received (data )
514
555
else :
556
+ if self ._loop .get_debug ():
557
+ logger .debug ("%r received EOF" , self )
515
558
keep_open = self ._protocol .eof_received ()
516
559
if keep_open :
517
560
# We're keeping the connection open so the
@@ -638,31 +681,37 @@ def __init__(self, loop, rawsock, protocol, sslcontext, waiter=None,
638
681
# SSL-specific extra info. (peercert is set later)
639
682
self ._extra .update (sslcontext = sslcontext )
640
683
641
- self ._on_handshake ()
684
+ if self ._loop .get_debug ():
685
+ logger .debug ("%r starts SSL handshake" , self )
686
+ start_time = self ._loop .time ()
687
+ else :
688
+ start_time = None
689
+ self ._on_handshake (start_time )
642
690
643
- def _on_handshake (self ):
691
+ def _on_handshake (self , start_time ):
644
692
try :
645
693
self ._sock .do_handshake ()
646
694
except ssl .SSLWantReadError :
647
- self ._loop .add_reader (self ._sock_fd , self ._on_handshake )
695
+ self ._loop .add_reader (self ._sock_fd ,
696
+ self ._on_handshake , start_time )
648
697
return
649
698
except ssl .SSLWantWriteError :
650
- self ._loop .add_writer (self ._sock_fd , self ._on_handshake )
651
- return
652
- except Exception as exc :
653
- self ._loop .remove_reader (self ._sock_fd )
654
- self ._loop .remove_writer (self ._sock_fd )
655
- self ._sock .close ()
656
- if self ._waiter is not None :
657
- self ._waiter .set_exception (exc )
699
+ self ._loop .add_writer (self ._sock_fd ,
700
+ self ._on_handshake , start_time )
658
701
return
659
702
except BaseException as exc :
703
+ if self ._loop .get_debug ():
704
+ logger .warning ("%r: SSL handshake failed" ,
705
+ self , exc_info = True )
660
706
self ._loop .remove_reader (self ._sock_fd )
661
707
self ._loop .remove_writer (self ._sock_fd )
662
708
self ._sock .close ()
663
709
if self ._waiter is not None :
664
710
self ._waiter .set_exception (exc )
665
- raise
711
+ if isinstance (exc , Exception ):
712
+ return
713
+ else :
714
+ raise
666
715
667
716
self ._loop .remove_reader (self ._sock_fd )
668
717
self ._loop .remove_writer (self ._sock_fd )
@@ -676,6 +725,10 @@ def _on_handshake(self):
676
725
try :
677
726
ssl .match_hostname (peercert , self ._server_hostname )
678
727
except Exception as exc :
728
+ if self ._loop .get_debug ():
729
+ logger .warning ("%r: SSL handshake failed "
730
+ "on matching the hostname" ,
731
+ self , exc_info = True )
679
732
self ._sock .close ()
680
733
if self ._waiter is not None :
681
734
self ._waiter .set_exception (exc )
@@ -696,6 +749,10 @@ def _on_handshake(self):
696
749
self ._loop .call_soon (self ._waiter ._set_result_unless_cancelled ,
697
750
None )
698
751
752
+ if self ._loop .get_debug ():
753
+ dt = self ._loop .time () - start_time
754
+ logger .debug ("%r: SSL handshake took %.1f ms" , self , dt * 1e3 )
755
+
699
756
def pause_reading (self ):
700
757
# XXX This is a bit icky, given the comment at the top of
701
758
# _read_ready(). Is it possible to evoke a deadlock? I don't
@@ -709,6 +766,8 @@ def pause_reading(self):
709
766
raise RuntimeError ('Already paused' )
710
767
self ._paused = True
711
768
self ._loop .remove_reader (self ._sock_fd )
769
+ if self ._loop .get_debug ():
770
+ logger .debug ("%r pauses reading" , self )
712
771
713
772
def resume_reading (self ):
714
773
if not self ._paused :
@@ -717,6 +776,8 @@ def resume_reading(self):
717
776
if self ._closing :
718
777
return
719
778
self ._loop .add_reader (self ._sock_fd , self ._read_ready )
779
+ if self ._loop .get_debug ():
780
+ logger .debug ("%r resumes reading" , self )
720
781
721
782
def _read_ready (self ):
722
783
if self ._write_wants_read :
@@ -741,6 +802,8 @@ def _read_ready(self):
741
802
self ._protocol .data_received (data )
742
803
else :
743
804
try :
805
+ if self ._loop .get_debug ():
806
+ logger .debug ("%r received EOF" , self )
744
807
keep_open = self ._protocol .eof_received ()
745
808
if keep_open :
746
809
logger .warning ('returning true from eof_received() '
0 commit comments