@@ -408,10 +408,16 @@ def __init__(self, concurrency=0xffffffff):
408408 self ._unregistered = []
409409 self ._stopped_serving = weakref .WeakSet ()
410410
411+ def _check_closed (self ):
412+ if self ._iocp is None :
413+ raise RuntimeError ('IocpProactor is closed' )
414+
411415 def __repr__ (self ):
412- return ('<%s overlapped#=%s result#=%s>'
413- % (self .__class__ .__name__ , len (self ._cache ),
414- len (self ._results )))
416+ info = ['overlapped#=%s' % len (self ._cache ),
417+ 'result#=%s' % len (self ._results )]
418+ if self ._iocp is None :
419+ info .append ('closed' )
420+ return '<%s %s>' % (self .__class__ .__name__ , " " .join (info ))
415421
416422 def set_loop (self , loop ):
417423 self ._loop = loop
@@ -618,6 +624,8 @@ def _wait_cancel(self, event, done_callback):
618624 return fut
619625
620626 def _wait_for_handle (self , handle , timeout , _is_cancel ):
627+ self ._check_closed ()
628+
621629 if timeout is None :
622630 ms = _winapi .INFINITE
623631 else :
@@ -660,6 +668,8 @@ def _register_with_iocp(self, obj):
660668 # that succeed immediately.
661669
662670 def _register (self , ov , obj , callback ):
671+ self ._check_closed ()
672+
663673 # Return a future which will be set with the result of the
664674 # operation when it completes. The future's value is actually
665675 # the value returned by callback().
@@ -696,6 +706,7 @@ def _unregister(self, ov):
696706 already be signalled (pending in the proactor event queue). It is also
697707 safe if the event is never signalled (because it was cancelled).
698708 """
709+ self ._check_closed ()
699710 self ._unregistered .append (ov )
700711
701712 def _get_accept_socket (self , family ):
@@ -765,6 +776,10 @@ def _stop_serving(self, obj):
765776 self ._stopped_serving .add (obj )
766777
767778 def close (self ):
779+ if self ._iocp is None :
780+ # already closed
781+ return
782+
768783 # Cancel remaining registered operations.
769784 for address , (fut , ov , obj , callback ) in list (self ._cache .items ()):
770785 if fut .cancelled ():
@@ -787,14 +802,15 @@ def close(self):
787802 context ['source_traceback' ] = fut ._source_traceback
788803 self ._loop .call_exception_handler (context )
789804
805+ # wait until all cancelled overlapped future complete
790806 while self ._cache :
791807 if not self ._poll (1 ):
792808 logger .debug ('taking long time to close proactor' )
793809
794810 self ._results = []
795- if self . _iocp is not None :
796- _winapi .CloseHandle (self ._iocp )
797- self ._iocp = None
811+
812+ _winapi .CloseHandle (self ._iocp )
813+ self ._iocp = None
798814
799815 def __del__ (self ):
800816 self .close ()
0 commit comments