示例#1
0
    def __init__(self):
        Channel.__init__(self)
        self.handlinglayer = None

        self.blocking = False
        self.timeout = 0
        self.events = Queue.Queue()

        self.lock = Lock()
示例#2
0
    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