////////////////////////////////////////////////////////////////////////// // Implementation ////////////////////////////////////////////////////////////////////////// private Future _send(object msg, Duration dur, Future whenDone) { // ensure immutable or safe copy msg = Sys.safe(msg); // don't deliver new messages to a stopped pool if (m_pool.isStopped()) { throw Err.make("ActorPool is stopped").val; } // get the future instance to manage this message's lifecycle Future f = new Future(msg); // either enqueue immediately or schedule with pool if (dur != null) { m_pool.schedule(this, dur, f); } else if (whenDone != null) { whenDone.sendWhenDone(this, f); } else { f = _enqueue(f, true); } return(f); }
public object get(Duration timeout) { object r = null; try { lock (this) { // wait until we enter a done state, the only notifies // on this object should be from cancel, set, or err if (timeout == null) { // wait forever until done while ((m_state & DONE) == 0) { Monitor.Wait(this); } } else { // if not done, then wait with timeout and then // if still not done throw a timeout exception if ((m_state & DONE) == 0) { Monitor.Wait(this, (int)timeout.millis()); if ((m_state & DONE) == 0) { throw TimeoutErr.make("Future.get timed out").val; } } } // if canceled throw CancelErr if (m_state == DONE_CANCEL) { throw CancelledErr.make("message canceled").val; } // if error was raised, raise it to caller if (m_state == DONE_ERR) { throw ((Err)m_result).rebase(); } // assign result to local variable for return r = m_result; } } catch (ThreadInterruptedException e) { throw InterruptedErr.make(e).val; } // ensure immutable or safe copy return(Sys.safe(r)); }
internal void set(object r) { r = Sys.safe(r); ArrayList wd; lock (this) { m_state = DONE_OK; m_result = r; Monitor.PulseAll(this); wd = whenDone; whenDone = null; } sendWhenDone(wd); }