Exemplo n.º 1
0
 def distinguish_empty(self, io_method, args):
     """Some io.SocketIO methods return the empty string both for
     disconnects and EAGAIN.  Attempt to distinguish between the two.
     """
     result = io_method(*args)
     if not result:
         try:
             if self.socket.recv(1, socket.MSG_PEEK):
                 # the socket has become readable in the time it took
                 # to get here.  raise a BlockingIOError so we can get
                 # selected as readable again
                 raise core.eagain()
             else:
                 # the socket was actually disconnected
                 raise core.EndOfStream
         except socket.error as e:
             if e.errno not in (errno.EAGAIN, errno.EWOULDBLOCK):
                 # if this isn't a blocking io errno, raise the legitimate
                 # exception
                 raise
             # a socket can't be reopened for reading if it's
             # closed/shutdown, so it's still unreadable.  raise a
             # BlockingIOError to communicate this upward
             raise io.BlockingIOError(*e.args)
     return result
Exemplo n.º 2
0
 def read_peek(self, amount):
     with self.peek_buffer_lock:
         peeked = self.distinguish_empty(self.inbound.peek, (amount, ))
         self.peek_buffer.append(peeked)
         if len(peeked) < amount:
             raise core.eagain()
         result = ''.join(self.peek_buffer)
         self.peek_buffer = []
         return result
Exemplo n.º 3
0
    def read_line(self):
        with self.readline_buffer_lock:
            partial_line = self.distinguish_empty(self.inbound.readline,
                                                  (core.MAXLINE, ))

            self.readline_buffer.append(partial_line)
            if not core.LINE_END.search(partial_line):
                raise core.eagain()

            line = ''.join(self.readline_buffer)
            self.readline_buffer = []
            return line
Exemplo n.º 4
0
    def write_data(self, data):
        with self.write_backlog_rlock:
            written = self.outbound.write(data)
            if not written:
                # written may be None, but characters_written on
                # BlockingIOError must be an integer. so set it to 0.
                written = 0
                self.write_backlog = data
            else:
                self.write_backlog = data[written:]

            if self.write_backlog:
                raise core.eagain(characters_written=written)

            return written
Exemplo n.º 5
0
 def read_data(self, amount):
     data = self.inbound.read(amount)
     if data is None:
         raise core.eagain()
     return data