Skip to content

Commit bf8b6e6

Browse files
committed
Use asyncio._get_running_loop() and _set_running_loop() when available
1 parent ea6d979 commit bf8b6e6

File tree

3 files changed

+39
-2
lines changed

3 files changed

+39
-2
lines changed

tests/test_base.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,3 +530,27 @@ def test_uvloop_policy(self):
530530
loop.close()
531531
finally:
532532
asyncio.set_event_loop_policy(None)
533+
534+
@unittest.skipUnless(hasattr(asyncio, '_get_running_loop'),
535+
'No asyncio._get_running_loop')
536+
def test_running_loop_within_a_loop(self):
537+
@asyncio.coroutine
538+
def runner(loop):
539+
loop.run_forever()
540+
541+
try:
542+
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
543+
544+
loop = asyncio.new_event_loop()
545+
outer_loop = asyncio.new_event_loop()
546+
547+
try:
548+
with self.assertRaisesRegex(RuntimeError,
549+
'while another loop is running'):
550+
outer_loop.run_until_complete(runner(loop))
551+
finally:
552+
loop.close()
553+
outer_loop.close()
554+
555+
finally:
556+
asyncio.set_event_loop_policy(None)

uvloop/includes/stdlib.pxi

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ cdef aio_Protocol = asyncio.Protocol
3838
cdef aio_SSLProtocol = asyncio.sslproto.SSLProtocol
3939
cdef aio_debug_wrapper = asyncio.coroutines.debug_wrapper
4040
cdef aio_isfuture = getattr(asyncio, 'isfuture', None)
41+
cdef aio_get_running_loop = getattr(asyncio, '_get_running_loop', None)
42+
cdef aio_set_running_loop = getattr(asyncio, '_set_running_loop', None)
4143

4244
cdef col_deque = collections.deque
4345
cdef col_Iterable = collections.Iterable

uvloop/loop.pyx

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,12 @@ cdef class Loop:
322322
raise RuntimeError('unable to start the loop; it was closed')
323323

324324
if self._running == 1:
325-
raise RuntimeError('Event loop is running.')
325+
raise RuntimeError('this event loop is already running.')
326+
327+
if (aio_get_running_loop is not None and
328+
aio_get_running_loop() is not None):
329+
raise RuntimeError(
330+
'Cannot run the event loop while another loop is running')
326331

327332
if self._signal_handlers is None:
328333
self._setup_signals()
@@ -337,7 +342,13 @@ cdef class Loop:
337342
self.handler_check__exec_writes.start()
338343
self.handler_idle.start()
339344

340-
self.__run(mode)
345+
if aio_set_running_loop is not None:
346+
aio_set_running_loop(self)
347+
try:
348+
self.__run(mode)
349+
finally:
350+
if aio_set_running_loop is not None:
351+
aio_set_running_loop(None)
341352

342353
self.handler_check__exec_writes.stop()
343354
self.handler_idle.stop()

0 commit comments

Comments
 (0)