예제 #1
0
    def PipeClient(address):
        '''
        Return a connection object connected to the pipe given by `address`
        '''
        t = _init_timeout()
        while 1:
            try:
                _winapi.WaitNamedPipe(address, 1000)
                h = _winapi.CreateFile(
                    address, _winapi.GENERIC_READ | _winapi.GENERIC_WRITE, 0,
                    _winapi.NULL, _winapi.OPEN_EXISTING,
                    _winapi.FILE_FLAG_OVERLAPPED, _winapi.NULL)
            except OSError as e:
                if e.winerror not in (
                        _winapi.ERROR_SEM_TIMEOUT,
                        _winapi.ERROR_PIPE_BUSY) or _check_timeout(t):
                    raise
            else:
                break
        else:
            raise

        _winapi.SetNamedPipeHandleState(h, _winapi.PIPE_READMODE_MESSAGE, None,
                                        None)
        return PipeConnection(h)
예제 #2
0
    def Pipe(duplex=True, rnonblock=False, wnonblock=False):  # noqa
        '''
        Returns pair of connection objects at either end of a pipe
        '''
        address = arbitrary_address('AF_PIPE')
        if duplex:
            openmode = _winapi.PIPE_ACCESS_DUPLEX
            access = _winapi.GENERIC_READ | _winapi.GENERIC_WRITE
            obsize, ibsize = BUFSIZE, BUFSIZE
        else:
            openmode = _winapi.PIPE_ACCESS_INBOUND
            access = _winapi.GENERIC_WRITE
            obsize, ibsize = 0, BUFSIZE

        h1 = _winapi.CreateNamedPipe(
            address, openmode | _winapi.FILE_FLAG_OVERLAPPED
            | _winapi.FILE_FLAG_FIRST_PIPE_INSTANCE, _winapi.PIPE_TYPE_MESSAGE
            | _winapi.PIPE_READMODE_MESSAGE | _winapi.PIPE_WAIT, 1, obsize,
            ibsize, _winapi.NMPWAIT_WAIT_FOREVER, _winapi.NULL)
        h2 = _winapi.CreateFile(address, access, 0, _winapi.NULL,
                                _winapi.OPEN_EXISTING,
                                _winapi.FILE_FLAG_OVERLAPPED, _winapi.NULL)
        _winapi.SetNamedPipeHandleState(h2, _winapi.PIPE_READMODE_MESSAGE,
                                        None, None)

        overlapped = _winapi.ConnectNamedPipe(h1, overlapped=True)
        _, err = overlapped.GetOverlappedResult(True)
        assert err == 0

        c1 = PipeConnection(duplicate(h1, inheritable=True), writable=duplex)
        c2 = PipeConnection(duplicate(h2, inheritable=True), readable=duplex)
        _winapi.CloseHandle(h1)
        _winapi.CloseHandle(h2)
        return c1, c2
예제 #3
0
    async def connect(self):
        '''
        Return a connection object connected to the pipe given by `address`
        '''
        if self._conn is None:
            delay = CONNECT_PIPE_INIT_DELAY
            while True:
                # Unfortunately there is no way to do an overlapped connect to
                # a pipe.  Call CreateFile() in a loop until it doesn't fail with
                # ERROR_PIPE_BUSY.
                try:
                    h = _winapi.CreateFile(
                        self._address,
                        _winapi.GENERIC_READ | _winapi.GENERIC_WRITE, 0,
                        _winapi.NULL, _winapi.OPEN_EXISTING,
                        _winapi.FILE_FLAG_OVERLAPPED, _winapi.NULL)
                    break
                except OSError as e:
                    if e.winerror not in (_winapi.ERROR_SEM_TIMEOUT,
                                          _winapi.ERROR_PIPE_BUSY):
                        raise

                # ConnectPipe() failed with ERROR_PIPE_BUSY: retry later
                delay = min(delay * 2, CONNECT_PIPE_MAX_DELAY)
                await asyncio.sleep(delay)
            _winapi.SetNamedPipeHandleState(h, _winapi.PIPE_READMODE_MESSAGE,
                                            None, None)
            if self._wrap_ssl:
                self._conn = AsyncSslPipeConnection(h)
            else:
                self._conn = AsyncPipeConnection(h)
        return self._conn
예제 #4
0
    def Pipe(duplex=True):
        '''
        返回管道两端的一对连接对象
        Returns pair of connection objects at either end of a pipe
        '''
        address = arbitrary_address('AF_PIPE')
        if duplex:
            openmode = _winapi.PIPE_ACCESS_DUPLEX
            access = _winapi.GENERIC_READ | _winapi.GENERIC_WRITE
            obsize, ibsize = BUFSIZE, BUFSIZE
        else:
            openmode = _winapi.PIPE_ACCESS_INBOUND
            access = _winapi.GENERIC_WRITE
            obsize, ibsize = 0, BUFSIZE

        h1 = _winapi.CreateNamedPipe(
            address,
            openmode | _winapi.FILE_FLAG_OVERLAPPED
            | _winapi.FILE_FLAG_FIRST_PIPE_INSTANCE,
            _winapi.PIPE_TYPE_MESSAGE | _winapi.PIPE_READMODE_MESSAGE
            | _winapi.PIPE_WAIT,
            1,
            obsize,
            ibsize,
            _winapi.NMPWAIT_WAIT_FOREVER,
            # default security descriptor: the handle cannot be inherited
            _winapi.NULL)
        h2 = _winapi.CreateFile(address, access, 0, _winapi.NULL,
                                _winapi.OPEN_EXISTING,
                                _winapi.FILE_FLAG_OVERLAPPED, _winapi.NULL)
        _winapi.SetNamedPipeHandleState(h2, _winapi.PIPE_READMODE_MESSAGE,
                                        None, None)

        overlapped = _winapi.ConnectNamedPipe(h1, overlapped=True)
        _, err = overlapped.GetOverlappedResult(True)
        assert err == 0

        c1 = PipeConnection(h1, writable=duplex)
        c2 = PipeConnection(h2, readable=duplex)

        return c1, c2
예제 #5
0
파일: ipc.py 프로젝트: pranavrajpal/mypy
 def __init__(self, name: str, timeout: Optional[float]) -> None:
     super().__init__(name, timeout)
     if sys.platform == 'win32':
         timeout = int(
             self.timeout *
             1000) if self.timeout else _winapi.NMPWAIT_WAIT_FOREVER
         try:
             _winapi.WaitNamedPipe(self.name, timeout)
         except FileNotFoundError as e:
             raise IPCException(
                 f"The NamedPipe at {self.name} was not found.") from e
         except OSError as e:
             if e.winerror == _winapi.ERROR_SEM_TIMEOUT:
                 raise IPCException(
                     "Timed out waiting for connection.") from e
             else:
                 raise
         try:
             self.connection = _winapi.CreateFile(
                 self.name,
                 _winapi.GENERIC_READ | _winapi.GENERIC_WRITE,
                 0,
                 _winapi.NULL,
                 _winapi.OPEN_EXISTING,
                 _winapi.FILE_FLAG_OVERLAPPED,
                 _winapi.NULL,
             )
         except OSError as e:
             if e.winerror == _winapi.ERROR_PIPE_BUSY:
                 raise IPCException("The connection is busy.") from e
             else:
                 raise
         _winapi.SetNamedPipeHandleState(self.connection,
                                         _winapi.PIPE_READMODE_MESSAGE,
                                         None, None)
     else:
         self.connection = socket.socket(socket.AF_UNIX)
         self.connection.settimeout(timeout)
         self.connection.connect(name)
예제 #6
0
 def __init__(self, name: str, timeout: Optional[int]) -> None:
     super().__init__(name)
     if sys.platform == 'win32':
         timeout = timeout or 0xFFFFFFFF  # NMPWAIT_WAIT_FOREVER
         try:
             _winapi.WaitNamedPipe(self.name, timeout)
         except FileNotFoundError:
             raise IPCException("The NamedPipe at {} was not found.".format(self.name))
         except WindowsError as e:
             if e.winerror == _winapi.ERROR_SEM_TIMEOUT:
                 raise IPCException("Timed out waiting for connection.")
             else:
                 raise
         try:
             self.connection = _winapi.CreateFile(
                 self.name,
                 _winapi.GENERIC_READ | _winapi.GENERIC_WRITE,
                 0,
                 _winapi.NULL,
                 _winapi.OPEN_EXISTING,
                 0,
                 _winapi.NULL,
             )
         except WindowsError as e:
             if e.winerror == _winapi.ERROR_PIPE_BUSY:
                 raise IPCException("The connection is busy.")
             else:
                 raise
         _winapi.SetNamedPipeHandleState(self.connection,
                                         _winapi.PIPE_READMODE_MESSAGE,
                                         None,
                                         None)
     else:
         self.connection = socket.socket(socket.AF_UNIX)
         self.connection.settimeout(timeout)
         self.connection.connect(name)