Пример #1
0
  void ChannelObject::send(gc<Fiber> sender, gc<Object> value)
  {
    // TODO(bob): What if the channel is closed?

    // If we have a receiver, give it the value.
    if (receivers_.count() > 0)
    {
      gc<Fiber> receiver = receivers_.removeAt(0);
      receiver->storeReturn(value);
      receiver->ready();

      // Add the sender back to the scheduler too since it isn't blocked.
      sender->ready();
      return;
    }

    // Otherwise, stuff the value and suspend.
    sender->waitToSend(value);
    senders_.add(sender);
    return;
  }
Пример #2
0
  bool ChannelObject::close(VM& vm, gc<Fiber> sender)
  {
    if (!isOpen_) return false;
    isOpen_ = false;

    // If nothing is going to receive the "done". Just ignore it and close
    // immediately.
    if (receivers_.count() == 0) return false;

    // Send "done" to all of the receivers.
    for (int i = 0; i < receivers_.count(); i++)
    {
      receivers_[i]->storeReturn(vm.getAtom(ATOM_DONE));
      receivers_[i]->ready();
    }

    receivers_.clear();

    // Add the sender back to the scheduler after the receiver so it can
    // continue.
    sender->ready();

    return true;
  }