Ejemplo n.º 1
0
 def __enter__(self) -> 'IPCServer':
     if sys.platform == 'win32':
         # NOTE: It is theoretically possible that this will hang forever if the
         # client never connects, though this can be "solved" by killing the server
         try:
             ov = _winapi.ConnectNamedPipe(self.connection, overlapped=True)
             # TODO: remove once typeshed supports Literal types
             assert isinstance(ov, _winapi.Overlapped)
         except OSError as e:
             # Don't raise if the client already exists, or the client already connected
             if e.winerror not in (_winapi.ERROR_PIPE_CONNECTED,
                                   _winapi.ERROR_NO_DATA):
                 raise
         else:
             try:
                 timeout = int(self.timeout *
                               1000) if self.timeout else _winapi.INFINITE
                 res = _winapi.WaitForSingleObject(ov.event, timeout)
                 assert res == _winapi.WAIT_OBJECT_0
             except BaseException:
                 ov.cancel()
                 _winapi.CloseHandle(self.connection)
                 raise
             _, err = ov.GetOverlappedResult(True)
             assert err == 0
     else:
         try:
             self.connection, _ = self.sock.accept()
         except socket.timeout as e:
             raise IPCException('The socket timed out') from e
     return self
Ejemplo n.º 2
0
def _pid_alive(pid):
    """Check if the process with this PID is alive or not.

    Args:
        pid: The pid to check.

    Returns:
        This returns false if the process is dead. Otherwise, it returns true.
    """
    no_such_process = errno.EINVAL if sys.platform == "win32" else errno.ESRCH
    alive = True
    try:
        if sys.platform == "win32":
            SYNCHRONIZE = 0x00100000  # access mask defined in <winnt.h>
            handle = _winapi.OpenProcess(SYNCHRONIZE, False, pid)
            try:
                alive = (_winapi.WaitForSingleObject(handle, 0) !=
                         _winapi.WAIT_OBJECT_0)
            finally:
                _winapi.CloseHandle(handle)
        else:
            os.kill(pid, 0)
    except OSError as ex:
        if ex.errno != no_such_process:
            raise
        alive = False
    return alive
Ejemplo n.º 3
0
 def write(self, data: bytes) -> None:
     """Write bytes to an IPC connection."""
     if sys.platform == 'win32':
         try:
             ov, err = _winapi.WriteFile(self.connection,
                                         data,
                                         overlapped=True)
             # TODO: remove once typeshed supports Literal types
             assert isinstance(ov, _winapi.Overlapped)
             assert isinstance(err, int)
             try:
                 if err == _winapi.ERROR_IO_PENDING:
                     timeout = int(
                         self.timeout *
                         1000) if self.timeout else _winapi.INFINITE
                     res = _winapi.WaitForSingleObject(ov.event, timeout)
                     if res != _winapi.WAIT_OBJECT_0:
                         raise IPCException(
                             f"Bad result from I/O wait: {res}")
                 elif err != 0:
                     raise IPCException(
                         f"Failed writing to pipe with error: {err}")
             except BaseException:
                 ov.cancel()
                 raise
             bytes_written, err = ov.GetOverlappedResult(True)
             assert err == 0, err
             assert bytes_written == len(data)
         except OSError as e:
             raise IPCException(
                 f"Failed to write with error: {e.winerror}") from e
     else:
         self.connection.sendall(data)
         self.connection.shutdown(socket.SHUT_WR)
Ejemplo n.º 4
0
 def _wait_pid(self, blocking):
     assert self.__handle is not None
     if blocking:
         timeout = _winapi.INFINITE
     else:
         timeout = 0
     result = _winapi.WaitForSingleObject(self.__handle, timeout)
     if result != _winapi.WAIT_TIMEOUT:
         self.__result = _winapi.GetExitCodeProcess(self._handle)
 def wait(self, timeout=None):
     if self.returncode is None:
         if timeout is None:
             msecs = _winapi.INFINITE
         else:
             msecs = max(0, int(timeout * 1000 + 0.5))
         res = _winapi.WaitForSingleObject(int(self._handle), msecs)
         if res == _winapi.WAIT_OBJECT_0:
             code = _winapi.GetExitCodeProcess(self._handle)
             if code == TERMINATE:
                 code = -signal.SIGTERM
             self.returncode = code
     return self.returncode
Ejemplo n.º 6
0
 def wait(self, timeout=None, endtime=None):
     if endtime is not None:
         timeout = self._remaining_time(endtime)
     if timeout is None:
         timeout_millis = _winapi.INFINITE
     else:
         timeout_millis = int(timeout*1000)
     if self.returncode is None:
         result = _winapi.WaitForSingleObject(self._handle, timeout_millis)
         if result == _winapi.WAIT_TIMEOUT:
             raise TimeoutExpired(self.args, timeout)
         self.returncode = _winapi.GetExitCodeProcess(self._handle)
     return self.returncode
Ejemplo n.º 7
0
 def finish(trans, key, ov):
     if not f.cancelled():
         try:
             _overlapped.UnregisterWait(wh)
         except OSError as e:
             if e.winerror != _overlapped.ERROR_IO_PENDING:
                 raise
     # Note that this second wait means that we should only use
     # this with handles types where a successful wait has no
     # effect.  So events or processes are all right, but locks
     # or semaphores are not.  Also note if the handle is
     # signalled and then quickly reset, then we may return
     # False even though we have not timed out.
     return (_winapi.WaitForSingleObject(handle,
                                         0) == _winapi.WAIT_OBJECT_0)
Ejemplo n.º 8
0
 def read(self, size: int = 100000) -> bytes:
     """Read bytes from an IPC connection until its empty."""
     bdata = bytearray()
     if sys.platform == 'win32':
         while True:
             ov, err = _winapi.ReadFile(self.connection,
                                        size,
                                        overlapped=True)
             # TODO: remove once typeshed supports Literal types
             assert isinstance(ov, _winapi.Overlapped)
             assert isinstance(err, int)
             try:
                 if err == _winapi.ERROR_IO_PENDING:
                     timeout = int(
                         self.timeout *
                         1000) if self.timeout else _winapi.INFINITE
                     res = _winapi.WaitForSingleObject(ov.event, timeout)
                     if res != _winapi.WAIT_OBJECT_0:
                         raise IPCException(
                             "Bad result from I/O wait: {}".format(res))
             except BaseException:
                 ov.cancel()
                 raise
             _, err = ov.GetOverlappedResult(True)
             more = ov.getbuffer()
             if more:
                 bdata.extend(more)
             if err == 0:
                 # we are done!
                 break
             elif err == _winapi.ERROR_MORE_DATA:
                 # read again
                 continue
             elif err == _winapi.ERROR_OPERATION_ABORTED:
                 raise IPCException("ReadFile operation aborted.")
     else:
         while True:
             more = self.connection.recv(size)
             if not more:
                 break
             bdata.extend(more)
     return bytes(bdata)
Ejemplo n.º 9
0
 def _poll(self):
     # non-blocking wait: use a timeout of 0 millisecond
     return (_winapi.WaitForSingleObject(self._handle,
                                         0) == _winapi.WAIT_OBJECT_0)
Ejemplo n.º 10
0
 def _poll(self):
     return _winapi.WaitForSingleObject(self._handle, 0
         ) == _winapi.WAIT_OBJECT_0