@@ -70,10 +70,6 @@ def _format_pipe(fd):
70
70
return repr (fd )
71
71
72
72
73
- class _StopError (BaseException ):
74
- """Raised to stop the event loop."""
75
-
76
-
77
73
def _check_resolved_address (sock , address ):
78
74
# Ensure that the address is already resolved to avoid the trap of hanging
79
75
# the entire event loop when the address requires doing a DNS lookup.
@@ -118,9 +114,6 @@ def _check_resolved_address(sock, address):
118
114
"got host %r: %s"
119
115
% (host , err ))
120
116
121
- def _raise_stop_error (* args ):
122
- raise _StopError
123
-
124
117
125
118
def _run_until_complete_cb (fut ):
126
119
exc = fut ._exception
@@ -129,7 +122,7 @@ def _run_until_complete_cb(fut):
129
122
# Issue #22429: run_forever() already finished, no need to
130
123
# stop it.
131
124
return
132
- _raise_stop_error ()
125
+ fut . _loop . stop ()
133
126
134
127
135
128
class Server (events .AbstractServer ):
@@ -184,6 +177,7 @@ class BaseEventLoop(events.AbstractEventLoop):
184
177
def __init__ (self ):
185
178
self ._timer_cancelled_count = 0
186
179
self ._closed = False
180
+ self ._stopping = False
187
181
self ._ready = collections .deque ()
188
182
self ._scheduled = []
189
183
self ._default_executor = None
@@ -298,11 +292,11 @@ def run_forever(self):
298
292
self ._thread_id = threading .get_ident ()
299
293
try :
300
294
while True :
301
- try :
302
- self ._run_once ()
303
- except _StopError :
295
+ self ._run_once ()
296
+ if self ._stopping :
304
297
break
305
298
finally :
299
+ self ._stopping = False
306
300
self ._thread_id = None
307
301
self ._set_coroutine_wrapper (False )
308
302
@@ -345,11 +339,10 @@ def run_until_complete(self, future):
345
339
def stop (self ):
346
340
"""Stop running the event loop.
347
341
348
- Every callback scheduled before stop() is called will run. Callbacks
349
- scheduled after stop() is called will not run. However, those callbacks
350
- will run if run_forever is called again later.
342
+ Every callback already scheduled will still run. This simply informs
343
+ run_forever to stop looping after a complete iteration.
351
344
"""
352
- self .call_soon ( _raise_stop_error )
345
+ self ._stopping = True
353
346
354
347
def close (self ):
355
348
"""Close the event loop.
@@ -1194,7 +1187,7 @@ def _run_once(self):
1194
1187
handle ._scheduled = False
1195
1188
1196
1189
timeout = None
1197
- if self ._ready :
1190
+ if self ._ready or self . _stopping :
1198
1191
timeout = 0
1199
1192
elif self ._scheduled :
1200
1193
# Compute the desired timeout.
0 commit comments