Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
use cache for HID device info
  • Loading branch information
LeonarddeR committed Dec 26, 2024
commit 3b95bd7447b3f1b823c45ee800199d783c20fdd7
41 changes: 28 additions & 13 deletions source/hwPortUtils.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import hidpi
import winKernel
from logHandler import log
from winAPI.constants import SystemErrorCodes
from winKernel import SYSTEMTIME


Expand Down Expand Up @@ -496,7 +497,10 @@ def __init__(self, **kwargs):
super().__init__(Size=ctypes.sizeof(HIDD_ATTRIBUTES), **kwargs)


def _getHidInfo(hwId, path):
_getHidInfoCache: dict[str, dict] = {}


def _getHidInfo(hwId: str, path: str) -> dict[str, typing.Any]:
info = {
"hardwareID": hwId,
"devicePath": path,
Expand All @@ -517,18 +521,28 @@ def _getHidInfo(hwId, path):
# Fetch additional info about the HID device.
from serial.win32 import FILE_FLAG_OVERLAPPED, INVALID_HANDLE_VALUE, CreateFile

handle = CreateFile(
path,
0,
winKernel.FILE_SHARE_READ | winKernel.FILE_SHARE_WRITE,
None,
winKernel.OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
None,
)
if handle == INVALID_HANDLE_VALUE:
if _isDebug():
log.debugWarning(f"Opening device {path} to get additional info failed: {ctypes.WinError()}")
if (
handle := CreateFile(
path,
0,
winKernel.FILE_SHARE_READ | winKernel.FILE_SHARE_WRITE,
None,
winKernel.OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
None,
)
) == INVALID_HANDLE_VALUE:
if (err := ctypes.GetLastError()) == SystemErrorCodes.SHARING_VIOLATION:
if _isDebug():
log.debugWarning(
f"Opening device {path} to get additional info failed because the device is being used. "
"Falling back to cache for device info",
)
if cachedInfo := _getHidInfoCache.get(path):
cachedInfo.update(info)
return cachedInfo
elif _isDebug():
log.debugWarning(f"Opening device {path} to get additional info failed: {ctypes.WinError(err)}")
return info
try:
attribs = HIDD_ATTRIBUTES()
Expand All @@ -555,6 +569,7 @@ def _getHidInfo(hwId, path):
ctypes.windll.hid.HidD_FreePreparsedData(pd)
finally:
winKernel.closeHandle(handle)
_getHidInfoCache[path] = info
return info


Expand Down
2 changes: 2 additions & 0 deletions source/winAPI/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ class SystemErrorCodes(enum.IntEnum):
ACCESS_DENIED = 0x5
INVALID_DATA = 0xD
NOT_READY = 0x15
SHARING_VIOLATION = 0x20
"""The process cannot access the file because it is being used by another process."""
INVALID_PARAMETER = 0x57
MOD_NOT_FOUND = 0x7E
CANCELLED = 0x4C7
2 changes: 2 additions & 0 deletions user_docs/en/changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ Specifically, MathML inside of span and other elements that have the attribute `
In any document, if the cursor is on the last line, it will be moved to the end when using this command.
(#17251, #17430, @nvdaes)
* In web browsers, changes to text selection no longer sometimes fail to be reported in editable text controls. (#17501, @jcsteh)
* When the Standard HID Braille Display driver is explicitly selected as the braille display driver, and the braille display list is opened, NVDA correctly identifies the HID driver as the selected driver instead of showing no driver selected. (#17537, @LeonarddeR)
* The Humanware Brailliant driver is now more reliable in selecting the right connection endpoint, resulting in better connection stability and less errors. (#17537, @LeonarddeR)

### Changes for Developers

Expand Down