annotate libervia/frontends/tools/aio.py @ 4240:79c8a70e1813

backend, frontend: prepare remote control: This is a series of changes necessary to prepare the implementation of remote control feature: - XEP-0166: add a `priority` attribute to `ApplicationData`: this is needed when several applications are working in a same session, to know which one must be handled first. Will be used to make Remote Control have precedence over Call content. - XEP-0166: `_call_plugins` is now async and is not used with `DeferredList` anymore: the benefit to have methods called in parallels is very low, and it cause a lot of trouble as we can't predict order. Methods are now called sequentially so workflow can be predicted. - XEP-0167: fix `senders` XMPP attribute <=> SDP mapping - XEP-0234: preflight acceptance key is now `pre-accepted` instead of `file-accepted`, so the same key can be used with other jingle applications. - XEP-0167, XEP-0343: move some method to XEP-0167 - XEP-0353: use new `priority` feature to call preflight methods of applications according to it. - frontend (webrtc): refactor the sources/sink handling with a more flexible mechanism based on Pydantic models. It is now possible to have has many Data Channel as necessary, to have them in addition to A/V streams, to specify manually GStreamer sources and sinks, etc. - frontend (webrtc): rework of the pipeline to reduce latency. - frontend: new `portal_desktop` method. Screenshare portal handling has been moved there, and RemoteDesktop portal has been added. - frontend (webrtc): fix `extract_ufrag_pwd` method. rel 436
author Goffi <goffi@goffi.org>
date Sat, 11 May 2024 13:52:41 +0200
parents d01b8d002619
children 7d98d894933c
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4127
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
1 #!/usr/bin/env python3
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
2
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
3 # Libervia AsyncIO helper methods
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
4 # Copyright (C) 2009-2023 Jérôme Poisson (goffi@goffi.org)
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
5
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
6 # This program is free software: you can redistribute it and/or modify
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
7 # it under the terms of the GNU Affero General Public License as published by
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
8 # the Free Software Foundation, either version 3 of the License, or
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
9 # (at your option) any later version.
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
10
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
11 # This program is distributed in the hope that it will be useful,
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
14 # GNU Affero General Public License for more details.
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
15
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
16 # You should have received a copy of the GNU Affero General Public License
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
18
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
19 import asyncio
4138
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
20 from typing import Any, Awaitable, Callable, Coroutine
4127
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
21
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
22 from libervia.backend.core import log as logging
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
23
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
24 log = logging.getLogger(__name__)
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
25 background_tasks = set()
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
26
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
27
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
28 def _on_task_done(task: asyncio.Future) -> None:
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
29 """Callback function to execute when a task is done.
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
30
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
31 @param task: The completed task.
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
32 Note: The function removes the task from the tracking set and logs any exceptions
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
33 that might have occurred.
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
34 """
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
35 background_tasks.discard(task)
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
36 e = task.exception()
4233
d01b8d002619 cli (call, file), frontends: implement webRTC data channel transfer:
Goffi <goffi@goffi.org>
parents: 4138
diff changeset
37 if e is not None and not isinstance(e, SystemExit):
4127
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
38 exc_info = (type(e), e, e.__traceback__)
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
39 log.error("Task failed:", exc_info=exc_info)
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
40
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
41
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
42 def run_async(async_method: Coroutine | asyncio.Future) -> None:
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
43 """Schedules and tracks an asynchronous method.
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
44
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
45 @param async_method: The method to be scheduled for execution.
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
46 Note: The function keeps a strong reference to the task to prevent it from being
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
47 garbage-collected. In case of task failure, logs the error.
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
48 cf. https://docs.python.org/3/library/asyncio-task.html#asyncio.create_task
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
49 """
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
50 if isinstance(async_method, asyncio.Future):
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
51 task = asyncio.ensure_future(async_method)
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
52 else:
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
53 task = asyncio.create_task(async_method)
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
54
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
55 background_tasks.add(task)
5fc26a6ef113 frontends (tools) new `aio` module for tools regarding asyncio:
Goffi <goffi@goffi.org>
parents:
diff changeset
56 task.add_done_callback(_on_task_done)
4138
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
57
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
58
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
59 def run_with_args(
4233
d01b8d002619 cli (call, file), frontends: implement webRTC data channel transfer:
Goffi <goffi@goffi.org>
parents: 4138
diff changeset
60 async_method: Callable[..., Coroutine], *args: Any, **kwargs: Any
4138
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
61 ) -> None:
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
62 """Schedules and tracks an asynchronous method with arguments.
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
63
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
64 This function wraps the provided asynchronous method with its arguments
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
65 and then schedules it for execution.
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
66
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
67 @param async_method: The asynchronous method to be scheduled.
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
68 @param args: Positional arguments to pass to the async_method.
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
69 @param kwargs: Keyword arguments to pass to the async_method.
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
70 """
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
71 run_async(async_method(*args, **kwargs))
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
72
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
73
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
74 def run_from_thread(
4233
d01b8d002619 cli (call, file), frontends: implement webRTC data channel transfer:
Goffi <goffi@goffi.org>
parents: 4138
diff changeset
75 async_method: Callable[..., Coroutine] | Callable[..., asyncio.Future],
4138
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
76 *args,
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
77 loop: asyncio.AbstractEventLoop | None = None,
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
78 **kwargs,
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
79 ) -> None:
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
80 """Schedules an asynchronous method from another thread.
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
81
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
82 @param async_method: The method to be scheduled for execution.
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
83 """
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
84 if loop is None:
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
85 loop = asyncio.get_event_loop()
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
86 assert loop is not None
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
87 loop.call_soon_threadsafe(run_with_args, async_method, *args, **kwargs)
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
88
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
89
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
90 def maybe_async(result: Any | Awaitable[Any]) -> Awaitable[Any]:
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
91 """
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
92 Convert the provided result into an awaitable.
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
93
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
94 @param result: the result of a function or coroutine call
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
95 @return: an awaitable object which can be awaited to get the result
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
96 """
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
97 if asyncio.iscoroutine(result):
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
98 return result
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
99
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
100 future = asyncio.Future()
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
101 future.set_result(result)
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
102 return future
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
103
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
104
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
105 def install_glib_asyncio_iteration():
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
106 """Import and install GLib context iteration inside our asyncio event loop.
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
107
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
108 This is used as soon as GLib is used (like GStreamer).
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
109 Inspired from Kivy's install_gobject_iteration (in ``kivy.support``), thanks to Kivy's
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
110 team.
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
111 """
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
112
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
113 import asyncio
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
114
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
115 try:
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
116 from gi.repository import GLib
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
117 except ImportError:
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
118 raise ImportError("GLib could not be imported. Ensure it's installed.")
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
119
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
120 if hasattr(GLib, "_glib_already_installed"):
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
121 # already installed, don't do it twice.
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
122 return
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
123
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
124 GLib._glib_already_installed = True
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
125
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
126 loop = asyncio.get_event_loop()
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
127
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
128 # Create a GLib MainContext and make it the default
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
129 glib_context = GLib.MainContext.default()
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
130
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
131 # Function to iterate over the GLib main context
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
132 def _glib_iteration():
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
133 # We need to loop over the context to prevent lag
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
134 iteration_count = 0
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
135 while glib_context.pending() and iteration_count < 20:
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
136 glib_context.iteration(False)
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
137 iteration_count += 1
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
138
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
139 # If no work was done in the GLib loop, add a short delay before
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
140 # scheduling the next iteration, to prevent spinning and high CPU usage.
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
141 if iteration_count == 0:
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
142 loop.call_later(0.01, _glib_iteration)
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
143 else:
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
144 # Schedule ourselves to run again on the next asyncio loop iteration
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
145 loop.call_soon(_glib_iteration)
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
146
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
147 # Kick off the GLib iteration
5de6f3595380 frontends (tools/aio): add tool to run from thread, run maybe async method, or run GLib loop:
Goffi <goffi@goffi.org>
parents: 4127
diff changeset
148 loop.call_soon(_glib_iteration)