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