////////////////////////////////////////////////////////////////////////// // When Done ////////////////////////////////////////////////////////////////////////// internal void sendWhenDone(Actor a, Future f) { // if already done, then set immediate flag // otherwise add to our when done list bool immediate = false; lock (this) { if (isDone()) immediate = true; else { if (whenDone == null) whenDone = new ArrayList(); whenDone.Add(new WhenDone(a, f)); } } // if immediate we are already done so enqueue immediately if (immediate) { try { a._enqueue(f, false); } catch (System.Exception e) { Err.dumpStack(e); } } }
public WhenDone(Actor a, Future f) { actor = a; future = f; }
public Future sendWhenDone(Future f, object msg) { return(_send(msg, null, f)); }
public virtual Future coalesce(Future f) { return(null); }
public virtual Future coalesce(Future f) { return null; }
public virtual Future get() { if (head == null) return null; Future f = head; head = f.m_next; if (head == null) tail = null; f.m_next = null; size--; return f; }
public override Future coalesce(Future incoming) { object key = toKey(incoming.m_msg); if (key == null) return null; Future orig = (Future)pending[key]; if (orig == null) return null; orig.m_msg = coalesce(orig.m_msg, incoming.m_msg); return orig; }
public ScheduledWork(Actor a, Future f) { actor = a; future = f; }
////////////////////////////////////////////////////////////////////////// // 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 override void add(Future f) { try { object key = toKey(f.m_msg); if (key != null) pending[key] = f; } catch (System.Exception e) { Err.dumpStack(e); } base.add(f); }
internal Future _enqueue(Future f, bool coalesce) { lock (m_lock) { // attempt to coalesce if (coalesce) { Future c = m_queue.coalesce(f); if (c != null) return c; } // add to queue m_queue.add(f); // submit to thread pool if not submitted or current running if (!m_submitted) { m_submitted = true; m_pool.submit(this); } return f; } }
internal void _dispatch(Future future) { try { if (future.isCancelled()) return; if (m_pool.m_killed) { future.cancel(); return; } future.set(receive(future.m_msg)); } catch (Err.Val e) { future.err(e.m_err); } catch (System.Exception e) { future.err(Err.make(e)); } }
public Future sendWhenDone(Future f, object msg) { return _send(msg, null, f); }
internal void schedule(Actor a, Duration d, Future f) { m_scheduler.schedule(d.ticks(), new ScheduledWork(a, f)); }
public virtual void add(Future f) { if (tail == null) { head = tail = f; f.m_next = null; } else { tail.m_next = f; tail = f; } size++; }