sync primitives

This commit is contained in:
Will McGugan
2025-06-08 15:07:00 +01:00
parent 7e7ea0cdd4
commit c0910a67b5
3 changed files with 28 additions and 4 deletions

View File

@@ -865,6 +865,17 @@ class App(Generic[ReturnType], DOMNode):
return super().__init_subclass__(*args, **kwargs)
def _thread_init(self):
"""Initialize threading primitives for the current thread.
https://github.com/Textualize/textual/issues/5845
"""
self._message_queue
self._mounted_event
self._exception_event
self._thread_id = threading.get_ident()
def _get_dom_base(self) -> DOMNode:
"""When querying from the app, we want to query the default screen."""
return self.default_screen
@@ -2094,8 +2105,9 @@ class App(Generic[ReturnType], DOMNode):
run_auto_pilot(auto_pilot, pilot), name=repr(pilot)
)
self._thread_init()
app._loop = asyncio.get_running_loop()
app._thread_id = threading.get_ident()
with app._context():
try:
await app._process_messages(
@@ -3120,6 +3132,9 @@ class App(Generic[ReturnType], DOMNode):
terminal_size: tuple[int, int] | None = None,
message_hook: Callable[[Message], None] | None = None,
) -> None:
self._thread_init()
async def app_prelude() -> bool:
"""Work required before running the app.

View File

@@ -11,7 +11,6 @@ A `MessagePump` is a base class for any object which processes messages, which i
from __future__ import annotations
import asyncio
import sys
import threading
from asyncio import CancelledError, QueueEmpty, Task, create_task
from contextlib import contextmanager
@@ -23,12 +22,10 @@ from typing import (
Awaitable,
Callable,
Generator,
Generic,
Iterable,
Type,
TypeVar,
cast,
overload,
)
from weakref import WeakSet
@@ -163,6 +160,15 @@ class MessagePump(metaclass=_MessagePumpMeta):
prevent_message_types_stack.set(stack)
return stack
def _thread_init(self):
"""Initialize threading primitives for the current thread.
Require for Python3.8 https://github.com/Textualize/textual/issues/5845
"""
self._message_queue
self._mounted_event
def _get_prevented_messages(self) -> set[type[Message]]:
"""A set of all the prevented message types."""
return self._prevent_message_types_stack[-1]
@@ -506,6 +512,8 @@ class MessagePump(metaclass=_MessagePumpMeta):
def _start_messages(self) -> None:
"""Start messages task."""
self._thread_init()
if self.app._running:
self._task = create_task(
self._process_messages(), name=f"message pump {self}"

View File

@@ -152,6 +152,7 @@ class Timer:
count = 0
_repeat = self._repeat
_interval = self._interval
self._active # Force instantiation in same thread
await self._active.wait()
start = _time.get_time()