예제 #1
0
    def _channel_action(self, arg, d):
        """
        d == -1 : receive
        d ==  1 : send

        the original CStackless has an argument 'stackl' which is not used
        here.

        'target' is the peer tasklet to the current one
        """
        do_schedule = False
        assert abs(d) == 1

        source = ChannelWaiter(getcurrent(), get_scheduler())
        source.tempval = arg
        if d > 0:
            cando = self.balance < 0
            dir = d
        else:
            cando = self.balance > 0
            dir = 0

        if _channel_callback is not None:
            _channel_callback(self, source.task, dir, not cando)

        self.balance += d
        if cando:
            # there is somebody waiting
            target = self.queue.popleft()
            source.tempval, target.tempval = target.tempval, source.tempval
            target.blocked = 0
            if self.schedule_all:
                # always schedule
                target.scheduler.append(target.task)
                do_schedule = True
            elif self.preference == -d:
                target.scheduler.append(target.task, False)
                do_schedule = True
            else:
                target.scheduler.append(target.task)

            sched = target.scheduler

        else:
            # nobody is waiting
            sched = source.scheduler
            source.blocked = 1
            self.queue.append(source)
            _scheduler_remove(getcurrent())

            do_schedule = True

        if do_schedule:
            if sched.thread_id == thread.get_ident():
                schedule()

        retval = source.tempval
        if isinstance(retval, bomb):
            retval.raise_()
        return retval
예제 #2
0
파일: uv.py 프로젝트: benoitc/flower
 def idle(self, handle):
     if getcurrent() is self._runtask:
         schedule()
예제 #3
0
파일: channel.py 프로젝트: BigRLab/flower
    def _channel_action(self, arg, d):
        """
        d == -1 : receive
        d ==  1 : send

        the original CStackless has an argument 'stackl' which is not used
        here.

        'target' is the peer tasklet to the current one
        """

        assert abs(d) == 1

        do_schedule = False
        curr = getcurrent()
        source = ChannelWaiter(curr, get_scheduler(), arg)

        if d > 0:
            if not self.capacity:
                cando = self.balance < 0
            else:
                cando = len(self.recvq) <= self.capacity
            dir = d
        else:
            if not self.capacity:
                cando = self.balance > 0
            else:
                cando = len(self.sendq) <= self.capacity
            dir = 0

        if _channel_callback is not None:
            with self._lock:
                _channel_callback(self, getcurrent(), dir, not cando)

        if cando:
            # there is somebody waiting
            try:
                target = self.dequeue(d)
            except IndexError:
                # capacity is not None but nobody is waiting
                if d > 0:
                    self.enqueue(dir, ChannelWaiter(None, None, arg))
                return None

            source.arg, target.arg = target.arg, source.arg
            if target.task is not None:
                if self.schedule_all:
                    target.scheduler.unblock(target.task)
                    do_schedule = True
                elif self.preference == -d:
                    target.scheduler.unblock(target.task, False)
                    do_schedule = True
                else:
                    target.scheduler.unblock(target.task)
        else:
            # nobody is waiting
            source.task.blocked == 1
            self.enqueue(dir, source)
            schedrem(source.task)
            do_schedule = True

        if do_schedule:
            schedule()


        if isinstance(source.arg, bomb):
            source.arg.raise_()
        return source.arg
예제 #4
0
파일: uv.py 프로젝트: BigRLab/flower
 def idle(self, handle):
     if getcurrent() is self._runtask:
         schedule()