mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2025-12-12 09:10:30 +08:00
no busyloop in otg msd
This commit is contained in:
parent
cae9ad9a21
commit
ff6e284e64
@ -103,8 +103,8 @@ class _VirtualDriveState:
|
|||||||
|
|
||||||
|
|
||||||
class _State:
|
class _State:
|
||||||
def __init__(self, changes_queue: asyncio.queues.Queue) -> None:
|
def __init__(self, notifier: aiotools.AioNotifier) -> None:
|
||||||
self.__changes_queue = changes_queue
|
self.__notifier = notifier
|
||||||
|
|
||||||
self.storage: Optional[_StorageState] = None
|
self.storage: Optional[_StorageState] = None
|
||||||
self.vd: Optional[_VirtualDriveState] = None
|
self.vd: Optional[_VirtualDriveState] = None
|
||||||
@ -116,13 +116,13 @@ class _State:
|
|||||||
async def busy(self, check_online: bool=True) -> AsyncGenerator[None, None]:
|
async def busy(self, check_online: bool=True) -> AsyncGenerator[None, None]:
|
||||||
with self._region:
|
with self._region:
|
||||||
async with self._lock:
|
async with self._lock:
|
||||||
await self.__changes_queue.put(None)
|
await self.__notifier.notify()
|
||||||
if check_online:
|
if check_online:
|
||||||
if self.vd is None:
|
if self.vd is None:
|
||||||
raise MsdOfflineError()
|
raise MsdOfflineError()
|
||||||
assert self.storage
|
assert self.storage
|
||||||
yield
|
yield
|
||||||
await self.__changes_queue.put(None)
|
await self.__notifier.notify()
|
||||||
|
|
||||||
def is_busy(self) -> bool:
|
def is_busy(self) -> bool:
|
||||||
return self._region.is_busy()
|
return self._region.is_busy()
|
||||||
@ -154,9 +154,8 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes
|
|||||||
self.__new_file_written = 0
|
self.__new_file_written = 0
|
||||||
self.__new_file_tick = 0.0
|
self.__new_file_tick = 0.0
|
||||||
|
|
||||||
self.__changes_queue: asyncio.queues.Queue = asyncio.Queue()
|
self.__state_notifier = aiotools.AioNotifier()
|
||||||
|
self.__state = _State(self.__state_notifier)
|
||||||
self.__state = _State(self.__changes_queue)
|
|
||||||
|
|
||||||
logger = get_logger(0)
|
logger = get_logger(0)
|
||||||
logger.info("Using OTG gadget %r as MSD", gadget)
|
logger.info("Using OTG gadget %r as MSD", gadget)
|
||||||
@ -215,15 +214,15 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes
|
|||||||
if inotify_task.done():
|
if inotify_task.done():
|
||||||
RuntimeError("Inotify task is dead")
|
RuntimeError("Inotify task is dead")
|
||||||
|
|
||||||
try:
|
|
||||||
await asyncio.wait_for(self.__changes_queue.get(), timeout=0.1)
|
|
||||||
except asyncio.TimeoutError:
|
|
||||||
continue
|
|
||||||
|
|
||||||
state = await self.get_state()
|
state = await self.get_state()
|
||||||
if state != prev_state:
|
if state != prev_state:
|
||||||
yield state
|
yield state
|
||||||
prev_state = state
|
prev_state = state
|
||||||
|
|
||||||
|
await asyncio.wait([
|
||||||
|
inotify_task,
|
||||||
|
self.__state_notifier.wait(),
|
||||||
|
], return_when=asyncio.FIRST_COMPLETED)
|
||||||
finally:
|
finally:
|
||||||
if not inotify_task.done():
|
if not inotify_task.done():
|
||||||
inotify_task.cancel()
|
inotify_task.cancel()
|
||||||
@ -308,7 +307,7 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes
|
|||||||
with self.__state._region: # pylint: disable=protected-access
|
with self.__state._region: # pylint: disable=protected-access
|
||||||
try:
|
try:
|
||||||
async with self.__state._lock: # pylint: disable=protected-access
|
async with self.__state._lock: # pylint: disable=protected-access
|
||||||
await self.__changes_queue.put(None)
|
await self.__state_notifier.notify()
|
||||||
assert self.__state.storage
|
assert self.__state.storage
|
||||||
assert self.__state.vd
|
assert self.__state.vd
|
||||||
|
|
||||||
@ -324,7 +323,7 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes
|
|||||||
self.__new_file_written = 0
|
self.__new_file_written = 0
|
||||||
self.__new_file = await aiofiles.open(path, mode="w+b", buffering=0)
|
self.__new_file = await aiofiles.open(path, mode="w+b", buffering=0)
|
||||||
|
|
||||||
await self.__changes_queue.put(None)
|
await self.__state_notifier.notify()
|
||||||
yield
|
yield
|
||||||
self.__set_image_complete(name, True)
|
self.__set_image_complete(name, True)
|
||||||
|
|
||||||
@ -340,7 +339,7 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes
|
|||||||
# Между закрытием файла и эвентом айнотифи состояние может быть не обновлено,
|
# Между закрытием файла и эвентом айнотифи состояние может быть не обновлено,
|
||||||
# так что форсим обновление вручную, чтобы получить актуальное состояние.
|
# так что форсим обновление вручную, чтобы получить актуальное состояние.
|
||||||
await self.__reload_state()
|
await self.__reload_state()
|
||||||
await self.__changes_queue.put(None)
|
await self.__state_notifier.notify()
|
||||||
|
|
||||||
async def write_image_chunk(self, chunk: bytes) -> int:
|
async def write_image_chunk(self, chunk: bytes) -> int:
|
||||||
assert self.__new_file
|
assert self.__new_file
|
||||||
@ -350,7 +349,7 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes
|
|||||||
if self.__new_file_tick + 1 < now:
|
if self.__new_file_tick + 1 < now:
|
||||||
# Это нужно для ручного оповещения о свободном пространстве на диске, см. get_state()
|
# Это нужно для ручного оповещения о свободном пространстве на диске, см. get_state()
|
||||||
self.__new_file_tick = now
|
self.__new_file_tick = now
|
||||||
await self.__changes_queue.put(None)
|
await self.__state_notifier.notify()
|
||||||
return self.__new_file_written
|
return self.__new_file_written
|
||||||
|
|
||||||
async def remove(self, name: str) -> None:
|
async def remove(self, name: str) -> None:
|
||||||
@ -399,7 +398,7 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes
|
|||||||
while True:
|
while True:
|
||||||
# Активно ждем, пока не будут на месте все каталоги.
|
# Активно ждем, пока не будут на месте все каталоги.
|
||||||
await self.__reload_state()
|
await self.__reload_state()
|
||||||
await self.__changes_queue.put(None)
|
await self.__state_notifier.notify()
|
||||||
if self.__state.vd:
|
if self.__state.vd:
|
||||||
break
|
break
|
||||||
await asyncio.sleep(5)
|
await asyncio.sleep(5)
|
||||||
@ -411,7 +410,7 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes
|
|||||||
|
|
||||||
# После установки вотчеров еще раз проверяем стейт, чтобы ничего не потерять
|
# После установки вотчеров еще раз проверяем стейт, чтобы ничего не потерять
|
||||||
await self.__reload_state()
|
await self.__reload_state()
|
||||||
await self.__changes_queue.put(None)
|
await self.__state_notifier.notify()
|
||||||
|
|
||||||
while self.__state.vd: # Если живы после предыдущей проверки
|
while self.__state.vd: # Если живы после предыдущей проверки
|
||||||
need_restart = False
|
need_restart = False
|
||||||
@ -427,7 +426,7 @@ class Plugin(BaseMsd): # pylint: disable=too-many-instance-attributes
|
|||||||
break
|
break
|
||||||
if need_reload_state:
|
if need_reload_state:
|
||||||
await self.__reload_state()
|
await self.__reload_state()
|
||||||
await self.__changes_queue.put(None)
|
await self.__state_notifier.notify()
|
||||||
except asyncio.CancelledError: # pylint: disable=try-except-raise
|
except asyncio.CancelledError: # pylint: disable=try-except-raise
|
||||||
raise
|
raise
|
||||||
except Exception:
|
except Exception:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user