Skip to content

Commit

Permalink
use cache for HID device info
Browse files Browse the repository at this point in the history
  • Loading branch information
LeonarddeR authored and SaschaCowley committed Dec 17, 2024
1 parent 3b7f795 commit ce0ef4e
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 13 deletions.
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, str | None]:
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

0 comments on commit ce0ef4e

Please sign in to comment.