def __init__(self): Channel.__init__(self) self.handlinglayer = None self.blocking = False self.timeout = 0 self.events = Queue.Queue() self.lock = Lock()
def read(self, count, less=False, peek=False): """ Attempts to recover count bytes from the channel. If the channel is blocking and timeout is infinite, this will block for as long as necessary, unless it L{ChannelFailure}s first If the channel is blocking and timeout is finite, this will block for at most timeout returning data or L{DataNotAvailable} or L{ChannelFailure} If the channel is nonblocking, it will return L{DataNotAvailable} or the data """ if not self.active: # If we cannot satisfy the request, we need to raise an exception # because we will never be able to do so if len(self.rx_buffer) == 0: # this would always fail raise ChannelClosed, 'channel closed' if len(self.rx_buffer) >= count: # if we can safely satisfy the request right away, do it return Channel.read(self, count, less, peek) else: # we cannot satisfy all of the request, only less might save us now # from raising an exception if less: return Channel.read(self, count, less, peek) else: raise ChannelClosed, 'channel closed`' with self.lock: if self.blocking: # uh, oh try: return Channel.read(self, count, False, peek) except DataNotAvailable: if self.timeout != None: # we need to hang for timeout at max try: msg = self.events.get(True, self.timeout) except Queue.Empty: if less: return Channel.read(self, count, less, peek) else: raise DataNotAvailable, 'no activity on channel for timeout' if isinstance(msg, self.LSMReadable): self.rx_buffer.extend(msg.data) return Channel.read(self, count, less, peek) # throws DataNotAvailable, we'll let it propagate elif isinstance(msg, self.LSMFailed): self.active = False raise ChannelFailure, 'channel failed' elif isinstance(msg, self.LSMClosed): self.active = False raise ChannelClosed, 'channel closed' else: # we may hang for eternity # there may be less in effect if less and (len(self.rx_buffer) > 0): return Channel.read(self, count, True, peek) while True: msg = self.events.get(True) # block until data is available if isinstance(msg, self.LSMReadable): self.rx_buffer.extend(msg.data) try: return Channel.read(self, count, less, peek) except DataNotAvailable: continue # no data? no problem, wait for more elif isinstance(msg, self.LSMFailed): self.active = False raise ChannelFailure, 'channel failed' elif isinstance(msg, self.LSMClosed): self.active = False raise ChannelClosed, 'channel closed' else: while True: try: msg = self.events.get(False) except Queue.Empty: break if isinstance(msg, self.LSMReadable): self.rx_buffer.extend(msg.data) elif isinstance(msg, self.LSMFailed): self.active = False raise ChannelFailure, 'channel failed' elif isinstance(msg, self.LSMClosed): self.active = False raise ChannelClosed, 'channel closed' return Channel.read(self, count, less, peek) # throws DataNotAvailable, let it propagate