def manage_run(self): """Set up the loop for running.""" self._check_closed() old_thread_id = self._thread_id old_running_loop = events._get_running_loop() try: self._thread_id = threading.get_ident() events._set_running_loop(self) self._num_runs_pending += 1 if self._is_proactorloop: if self._self_reading_future is None: self.call_soon(self._loop_self_reading) yield finally: self._thread_id = old_thread_id events._set_running_loop(old_running_loop) self._num_runs_pending -= 1 if self._is_proactorloop: if (self._num_runs_pending == 0 and self._self_reading_future is not None): ov = self._self_reading_future._ov self._self_reading_future.cancel() if ov is not None: self._proactor._unregister(ov) self._self_reading_future = None
def run_forever(self): if sys.version_info >= (3, 7, 0): set_coro_tracking = self._set_coroutine_origin_tracking else: set_coro_tracking = self._set_coroutine_wrapper self._check_closed() old_thread_id = self._thread_id old_running_loop = events._get_running_loop() set_coro_tracking(self._debug) self._thread_id = threading.get_ident() if self._asyncgens is not None: old_agen_hooks = sys.get_asyncgen_hooks() sys.set_asyncgen_hooks( firstiter=self._asyncgen_firstiter_hook, finalizer=self._asyncgen_finalizer_hook) try: events._set_running_loop(self) while True: self._run_once() if self._stopping: break finally: self._stopping = False self._thread_id = old_thread_id events._set_running_loop(old_running_loop) set_coro_tracking(False) if self._asyncgens is not None: sys.set_asyncgen_hooks(*old_agen_hooks)
def run_once_recurring(self): """ Run one iteration of the event loop, and enqueue the next iteration (if we're not stopping). This largely duplicates the "finally" behavior of the default Proactor run_forever implementation. """ # Perform one tick of the event loop. self._run_once() if self._stopping: # If we're stopping, we can do the "finally" handling from # the BaseEventLoop run_forever(). # === START BaseEventLoop.run_forever() finally handling === self._stopping = False self._thread_id = None events._set_running_loop(None) self._set_coroutine_origin_tracking(False) try: sys.set_asyncgen_hooks(*self._old_agen_hooks) except AttributeError: # Python < 3.6 didn't have set_asyncgen_hooks. # No action required for those versions. pass # === END BaseEventLoop.run_forever() finally handling === else: # Otherwise, live to tick another day. Enqueue the next tick, # and make sure there will be *something* to be processed. # If you don't ensure there is at least one message on the # queue, the select() call will block, locking the app. self.enqueue_tick() self.call_soon(self._loop_self_reading)
def run_forever_cooperatively(self, lifecycle=None): """A non-blocking version of :meth:`run_forever`. This may seem like nonsense; however, an iOS app is not expected to invoke a blocking "main event loop" method. As a result, we need to be able to *start* Python event loop handling, but then return control to the main app to start the actual event loop. The implementation is effectively all the parts of a call to :meth:`run_forever()`, but without any of the shutdown/cleanup logic. """ if not self._lifecycle: self._set_lifecycle( lifecycle if lifecycle else CFLifecycle(self._cfrunloop)) if self.is_running(): raise RuntimeError( "Recursively calling run_forever is forbidden. " "To recursively run the event loop, call run().") self._running = True if hasattr(events, "_set_running_loop"): events._set_running_loop(self) self._lifecycle.start()
def run(self): # pragma nocover # The coverage for this process has not yet started try: from asyncio.events import _set_running_loop _set_running_loop(None) except ImportError: pass run_actor(self)
def run_once(self): if hasattr(events, "_set_running_loop"): events._set_running_loop(self) self._run_once() if hasattr(events, "_set_running_loop"): events._set_running_loop(None)
def run_forever(self, app_context): """Set up the asyncio event loop, integrate it with the Winforms event loop, and start the application. This largely duplicates the setup behavior of the default Proactor run_forever implementation. :param app_context: The WinForms.ApplicationContext instance controlling the lifecycle of the app. """ # Remember the application context. self.app_context = app_context # Register a custom user window message. self.msg_id = user32.RegisterWindowMessageA("Python asyncio tick") # Add a message filter to listen for the asyncio tick message # FIXME: Actually install the message filter. # msg_filter = AsyncIOTickMessageFilter(self, self.msg_id) # WinForms.Application.AddMessageFilter(msg_filter) # Setup the Proactor. # The code between the following markers should be exactly the same as # the official CPython implementation, up to the start of the # `while True:` part of run_forever() (see BaseEventLoop.run_forever() # in Lib/ascynio/base_events.py) # === START BaseEventLoop.run_forever() setup === self._check_closed() if self.is_running(): raise RuntimeError('This event loop is already running') if events._get_running_loop() is not None: raise RuntimeError( 'Cannot run the event loop while another loop is running') self._set_coroutine_origin_tracking(self._debug) self._thread_id = threading.get_ident() try: self._old_agen_hooks = sys.get_asyncgen_hooks() sys.set_asyncgen_hooks(firstiter=self._asyncgen_firstiter_hook, finalizer=self._asyncgen_finalizer_hook) except AttributeError: # Python < 3.6 didn't have sys.get_asyncgen_hooks(); # No action required for those versions. pass events._set_running_loop(self) # === END BaseEventLoop.run_forever() setup === # Rather than going into a `while True:` loop, we're going to use the # Winforms event loop to queue a tick() message that will cause a # single iteration of the asyncio event loop to be executed. Each time # we do this, we queue *another* tick() message in 5ms time. In this # way, we'll get a continuous stream of tick() calls, without blocking # the Winforms event loop. # Queue the first asyncio tick. self.enqueue_tick() # Start the Winforms event loop. WinForms.Application.Run(self.app_context)
def run_until_complete(self, future): self._check_closed() events._set_running_loop(self) f = asyncio.ensure_future(future, loop=self) if f is not future: f._log_destroy_pending = False while not f.done(): self._run_once() if self._stopping: break if not f.done(): raise RuntimeError('Event loop stopped before Future completed.') return f.result()
def run_forever(self): self._check_closed() self._check_running() self._set_coroutine_origin_tracking(self._debug) self._thread_id = threading.get_ident() old_agen_hooks = sys.get_asyncgen_hooks() sys.set_asyncgen_hooks(firstiter=self._asyncgen_firstiter_hook, finalizer=self._asyncgen_finalizer_hook) try: events._set_running_loop(self) g_main_loop_run(self._main_loop) finally: self._thread_id = None events._set_running_loop(None) self._set_coroutine_origin_tracking(False) sys.set_asyncgen_hooks(*old_agen_hooks)
def run(self): """Internal implementatin of run using the CoreFoundation event loop.""" recursive = self.is_running() if not recursive and hasattr(events, "_get_running_loop") and events._get_running_loop(): raise RuntimeError('Cannot run the event loop while another loop is running') if not recursive: self._running = True if hasattr(events, "_set_running_loop"): events._set_running_loop(self) try: self._lifecycle.start() finally: if not recursive: self._running = False if hasattr(events, "_set_running_loop"): events._set_running_loop(None)
def run(self): recursive = self.is_running() if not recursive and hasattr(events, "_get_running_loop") and events._get_running_loop(): raise RuntimeError( 'Cannot run the event loop while another loop is running') if not recursive: self._running = True if hasattr(events, "_set_running_loop"): events._set_running_loop(self) try: if self._application is not None: self._application.run(None) else: self._mainloop.run() finally: if not recursive: self._running = False if hasattr(events, "_set_running_loop"): events._set_running_loop(None)
def main_loop(self): # Main loop is a no-op on iOS; the app loop is integrated with the # main iOS event loop. # The rest of this method will eventually be wrapped into # rubicon as the method `run_forever_cooperatively()`. # self.loop.run_forever_cooperatively(lifecycle=iOSLifecycle()) # ==== start run_forever_cooperatively() self.loop._set_lifecycle(iOSLifecycle()) if self.loop.is_running(): raise RuntimeError( "Recursively calling run_forever is forbidden. " "To recursively run the event loop, call run().") self.loop._running = True from asyncio import events if hasattr(events, "_set_running_loop"): events._set_running_loop(self.loop) self.loop._lifecycle.start()
def run_forever_37(self): # from Python 3.7 asyncio.base_events self._check_closed() old_thread_id = self._thread_id old_running_loop = events._get_running_loop() self._set_coroutine_origin_tracking(self._debug) self._thread_id = threading.get_ident() old_agen_hooks = sys.get_asyncgen_hooks() sys.set_asyncgen_hooks(firstiter=self._asyncgen_firstiter_hook, finalizer=self._asyncgen_finalizer_hook) try: events._set_running_loop(self) while True: self._run_once() if self._stopping: break finally: self._stopping = False self._thread_id = old_thread_id events._set_running_loop(old_running_loop) self._set_coroutine_origin_tracking(False) sys.set_asyncgen_hooks(*old_agen_hooks)
def stop(self): self._running = False events._set_running_loop(None)
def start(self): self._running = True events._set_running_loop(self)