mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-17 06:09:19 +00:00
Bug 1926214 part 1: Call CoInitialize for new threads in a11y Python test runner. r=nlapre
Each browser test file is run with a separate instance of shared-head.js and thus a distinct WebSocket connection to the a11y Python runner. pywebsocket3 is multi-threaded and may thus choose different threads to handle different WebSocket requests. Python comtypes implicitly initialises COM when it is imported, but COM initialisation is thread specific and Python modules are cached, so this only applies to the thread on which comtypes was imported. These factors were causing problems such as event timeouts when running multiple IA2 test files because IA2 relies on COM being initialised. To fix this, add a setup() function to a11y_setup.py which is called when a request is handled. For Windows, this calls CoInitialize once in each thread in which it is run. Differential Revision: https://phabricator.services.mozilla.com/D227143
This commit is contained in:
parent
8e37a980d5
commit
4cdf0b15c1
@ -28,6 +28,11 @@ sys.path.pop()
|
||||
del pyatspiFile
|
||||
|
||||
|
||||
def setup():
|
||||
# We do all the setup we need at module level.
|
||||
pass
|
||||
|
||||
|
||||
def getDoc():
|
||||
"""Get the Accessible for the document being tested."""
|
||||
# We can compare the parent process ids to find the Firefox started by the
|
||||
|
@ -41,6 +41,7 @@ def web_socket_transfer_data(request):
|
||||
try:
|
||||
import a11y_setup
|
||||
|
||||
a11y_setup.setup()
|
||||
cleanNamespace = a11y_setup.__dict__
|
||||
setupExc = None
|
||||
except Exception:
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
import ctypes
|
||||
import os
|
||||
import threading
|
||||
from ctypes import POINTER, byref
|
||||
from ctypes.wintypes import BOOL, HWND, LPARAM, POINT # noqa: F401
|
||||
from dataclasses import dataclass
|
||||
@ -62,6 +63,18 @@ uiaClient = comtypes.CoCreateInstance(
|
||||
clsctx=comtypes.CLSCTX_INPROC_SERVER,
|
||||
)
|
||||
|
||||
_threadLocal = threading.local()
|
||||
|
||||
|
||||
def setup():
|
||||
if getattr(_threadLocal, "isSetup", False):
|
||||
return
|
||||
# We can do most setup at module level. However, because modules are cached
|
||||
# and pywebsocket3 can serve requests on any thread, we need to do setup for
|
||||
# each new thread here.
|
||||
comtypes.CoInitialize()
|
||||
_threadLocal.isSetup = True
|
||||
|
||||
|
||||
def AccessibleObjectFromWindow(hwnd, objectID=OBJID_CLIENT):
|
||||
p = POINTER(IAccessible)()
|
||||
|
Loading…
x
Reference in New Issue
Block a user