You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ueberzug/ueberzug/files.py

48 lines
1.2 KiB
Python

import select
import fcntl
import contextlib
import pathlib
class LineReader:
"""Async iterator class used to read lines"""
def __init__(self, loop, file):
self._loop = loop
self._file = file
@staticmethod
async def read_line(loop, file):
"""Waits asynchronously for a line and returns it"""
return await loop.run_in_executor(None, file.readline)
def __aiter__(self):
return self
async def __anext__(self):
if select.select([self._file], [], [], 0)[0]:
return self._file.readline()
return await LineReader.read_line(self._loop, self._file)
@contextlib.contextmanager
def lock(path: pathlib.PosixPath):
"""Creates a lock file,
a file protected from beeing used by other processes.
(The lock file isn't the same as the file of the passed path.)
Args:
path (pathlib.PosixPath): path to the file
"""
path = path.with_suffix('.lock')
if not path.exists():
path.touch()
with path.open("r+") as lock_file:
try:
fcntl.lockf(lock_file.fileno(), fcntl.LOCK_EX)
yield lock_file
finally:
fcntl.lockf(lock_file.fileno(), fcntl.LOCK_UN)