diff -r c26e6beb2e35 Lib/asyncio/unix_events.py --- a/Lib/asyncio/unix_events.py Sat Jul 26 19:53:38 2014 +0300 +++ b/Lib/asyncio/unix_events.py Sun Jul 27 12:07:46 2014 -0400 @@ -863,6 +863,7 @@ def __init__(self): super().__init__() self._watcher = None + self._pid = os.getpid() def _init_watcher(self): with events._lock: @@ -886,6 +887,18 @@ isinstance(threading.current_thread(), threading._MainThread): self._watcher.attach_loop(loop) + def get_event_loop(self): + """ Get the event loop. + + If we detect we're in a child process forked by multiprocessing, + we reset self._local so that we'll get a new event loop. + + """ + if (self._local._loop is not None and + self._pid != os.getpid()): + self._local = self._Local() + return super().get_event_loop() + def get_child_watcher(self): """Get the watcher for child processes. diff -r c26e6beb2e35 Lib/test/test_asyncio/test_unix_events.py --- a/Lib/test/test_asyncio/test_unix_events.py Sat Jul 26 19:53:38 2014 +0300 +++ b/Lib/test/test_asyncio/test_unix_events.py Sun Jul 27 12:07:46 2014 -0400 @@ -13,6 +13,7 @@ import tempfile import threading import unittest +import multiprocessing from unittest import mock if sys.platform == 'win32': @@ -1500,6 +1501,26 @@ return asyncio.FastChildWatcher() +class ForkedProcessTests(unittest.TestCase): + def setUp(self): + self.parent_loop = asyncio.SelectorEventLoop() + asyncio.set_event_loop(self.parent_loop) + self.ctx = multiprocessing.get_context("fork") + + def _check_loops_not_equal(self, old_loop): + loop = asyncio.get_event_loop() + sys.exit(loop == old_loop) + + def test_new_loop_in_child(self): + p = self.ctx.Process(target=self._check_loops_not_equal, + args=(self.parent_loop,)) + p.start() + p.join() + self.assertEqual(p.exitcode, 0, + "Child process inherited parent's event loop") + self.parent_loop.close() + + class PolicyTests(unittest.TestCase): def create_policy(self):