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
def idle(self, handle): if getcurrent() is self._runtask: schedule()
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