diff options
Diffstat (limited to 'linuxnamespaces')
-rw-r--r-- | linuxnamespaces/syscalls.py | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/linuxnamespaces/syscalls.py b/linuxnamespaces/syscalls.py index 338e602..06b5025 100644 --- a/linuxnamespaces/syscalls.py +++ b/linuxnamespaces/syscalls.py @@ -5,9 +5,11 @@ for Linux namespaces including the new mount API. """ +import asyncio import ctypes import dataclasses import enum +import errno import os import typing @@ -419,6 +421,35 @@ class EventFD: call_libc("eventfd_read", self.fd, ctypes.byref(cvalue)) return cvalue.value + def __handle_readable(self, fd: int, fut: asyncio.Future[int]) -> None: + """Internal helper of aread.""" + try: + if fd != self.fd: + raise RuntimeError("EventFD file descriptor changed") + try: + result = self.read() + except OSError as err: + if err.errno == errno.EAGAIN: + return + raise + except Exception as exc: + fut.get_loop().remove_reader(fd) + fut.set_exception(exc) + else: + fut.get_loop().remove_reader(fd) + fut.set_result(result) + + def aread(self) -> typing.Awaitable[int]: + """Decrease the value of the eventfd asynchronously. It mst have been + constructed using EventFDFlags.NONBLOCK. + """ + if self.fd < 0: + raise ValueError("attempt to read from closed eventfd") + loop = asyncio.get_running_loop() + fut: asyncio.Future[int] = loop.create_future() + loop.add_reader(self.fd, self.__handle_readable, self.fd, fut) + return fut + def write(self, value: int = 1) -> None: """Add the given value to the eventfd using eventfd_write.""" if self.fd < 0: |