Exemplo n.º 1
0
    def __init__(self):
        # Event (handle) for registering this input in the event loop.
        # This event is set when there is data available to read from the pipe.
        # Note: We use this approach instead of using a regular pipe, like
        #       returned from `os.pipe()`, because making such a regular pipe
        #       non-blocking is tricky and this works really well.
        self._event = create_win32_event()

        self._closed = False

        # Parser for incoming keys.
        self._buffer = []  # Buffer to collect the Key objects.
        self.vt100_parser = Vt100Parser(lambda key: self._buffer.append(key))

        # Identifier for every PipeInput for the hash.
        self.__class__._id += 1
        self._id = self.__class__._id
    def __init__(self):
        # Event (handle) for registering this input in the event loop.
        # This event is set when there is data available to read from the pipe.
        # Note: We use this approach instead of using a regular pipe, like
        #       returned from `os.pipe()`, because making such a regular pipe
        #       non-blocking is tricky and this works really well.
        self._event = create_win32_event()

        self._closed = False

        # Parser for incoming keys.
        self._buffer = []  # Buffer to collect the Key objects.
        self.vt100_parser = Vt100Parser(
            lambda key: self._buffer.append(key))

        # Identifier for every PipeInput for the hash.
        self.__class__._id += 1
        self._id = self.__class__._id
Exemplo n.º 3
0
    def add_win32_handle(self, handle: HANDLE,
                         callback: Callable[[], None]) -> None:
        """
        Add a Win32 handle to the event loop.
        """
        handle_value = handle.value

        if handle_value is None:
            raise ValueError("Invalid handle.")

        # Make sure to remove a previous registered handler first.
        self.remove_win32_handle(handle)

        loop = get_event_loop()
        self._handle_callbacks[handle_value] = callback

        # Create remove event.
        remove_event = create_win32_event()
        self._remove_events[handle_value] = remove_event

        # Add reader.
        def ready() -> None:
            # Tell the callback that input's ready.
            try:
                callback()
            finally:
                run_in_executor_with_context(wait, loop=loop)

        # Wait for the input to become ready.
        # (Use an executor for this, the Windows asyncio event loop doesn't
        # allow us to wait for handles like stdin.)
        def wait() -> None:
            # Wait until either the handle becomes ready, or the remove event
            # has been set.
            result = wait_for_handles([remove_event, handle])

            if result is remove_event:
                windll.kernel32.CloseHandle(remove_event)
                return
            else:
                loop.call_soon_threadsafe(ready)

        run_in_executor_with_context(wait, loop=loop)
Exemplo n.º 4
0
 def create(cls) -> Iterator["Win32PipeInput"]:
     event = create_win32_event()
     try:
         yield Win32PipeInput(_event=event)
     finally:
         windll.kernel32.CloseHandle(event)