def recv(self, bufsize, flags=0): if self.__commstate in (SHUT_RD, SHUT_RDWR): return "" self.__checkconnected() if not isinstance(bufsize, int): raise TypeError("buffer size must be int, was %s" % type(bufsize)) if bufsize < 0: raise ValueError("negative buffersize in recv") # as for tcp if bufsize == 0: return "" # need this to ensure the _isclosed() check is up-to-date _macutil.looponce() if self._isclosed(): if len(self.__incomingdata) == 0: raise _socket.error(errno.ECONNRESET, os.strerror(errno.ECONNRESET)) return self.__incomingdata.read(bufsize) # if incoming data buffer is empty, wait until data is available or # channel is closed def gotdata(): return not self.__incomingdata.empty() or self._isclosed() if not gotdata(): self.__waituntil(gotdata, "recv timed out") # other side closed connection while waiting? if self._isclosed() and len(self.__incomingdata) == 0: raise _socket.error(errno.ECONNRESET, os.strerror(errno.ECONNRESET)) return self.__incomingdata.read(bufsize)
def __waituntil(self, stopwaiting, timeoutmsg): """ Waits until stopwaiting() returns True, or until the wait times out (according to the self.__timeout value). This is to make a function wait until a buffer has been filled. i.e. stopwaiting() should return True when the buffer is no longer empty. """ if not stopwaiting(): if self.__timeout == 0: # in non-blocking mode (immediate timeout) # push event loop to really be sure there is no data available _macutil.looponce() if not stopwaiting(): # trying to perform operation now would block raise _socket.error(errno.EAGAIN, os.strerror(errno.EAGAIN)) else: # block and wait until we get data, or time out if not _macutil.waituntil(stopwaiting, self.__timeout): raise _socket.timeout(timeoutmsg)
# Copyright (c) 2009 Bea Lam. All rights reserved.