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)); }