internal object GetResult(ISession session, FutureList futures, bool remove) { Debug.WriteLineIf(CLI.FnTrace.Enabled, "Future.GetResult ()"); bool locked = false; bool check_timeout = false; try { for (;;) { if (!locked) { Monitor.Enter(this); locked = true; } if (results != null && results.Count > 0) { object result = results[0]; if (remove) { results.RemoveAt(0); } return(result); } if (error != null) { if (error is bool && (bool)error) { throw new SystemException("Timeout expired."); } throw new SystemException(error.ToString()); } if (isComplete) { return(null); } if (endOfTime != 0) { if (check_timeout) { long now = DateTime.Now.Ticks; if (endOfTime > now) { timeout = (int)((endOfTime - now) / Values.TicksPerSec); } else { Debug.WriteLineIf(Switch.Enabled, "future timed out: " + requestNo); error = true; Future cancel = new Future(Service.Cancel); cancel.SendRequest(session); throw new SystemException("Timeout expired."); } } else { check_timeout = true; } } if (futures.ReadLock()) { try { bool read = session.PollRead(timeout); if (read) { object[] answer = ReadAnswer(session, false); if (answer != null) { int id = (int)answer[RpcMessageLayout.RRC_COND_NUMBER]; Debug.WriteLineIf(Switch.Enabled, "RRC_COND_NUMBER: " + id); Future future = (Future)futures[id]; if (future != null) { future.HandleAnswer(answer); } } } } finally { futures.ReadUnlock(); } } else { // Unlock so that HandleAnswer for this future // can be called from another thread. Monitor.Exit(this); locked = false; futures.ReadWait(timeout); } } } finally { if (locked) { Monitor.Exit(this); } } }
internal object GetResult (ISession session, FutureList futures, bool remove) { Debug.WriteLineIf (CLI.FnTrace.Enabled, "Future.GetResult ()"); bool locked = false; bool check_timeout = false; try { for (;;) { if (!locked) { Monitor.Enter (this); locked = true; } if (results != null && results.Count > 0) { object result = results[0]; if (remove) results.RemoveAt (0); return result; } if (error != null) { if (error is bool && (bool) error) throw new SystemException ("Timeout expired."); throw new SystemException (error.ToString ()); } if (isComplete) return null; if (endOfTime != 0) { if (check_timeout) { long now = DateTime.Now.Ticks; if (endOfTime > now) { timeout = (int) ((endOfTime - now) / Values.TicksPerSec); } else { Debug.WriteLineIf (Switch.Enabled, "future timed out: " + requestNo); error = true; Future cancel = new Future (Service.Cancel); cancel.SendRequest (session); throw new SystemException ("Timeout expired."); } } else { check_timeout = true; } } if (futures.ReadLock ()) { try { bool read = session.PollRead (timeout); if (read) { object[] answer = ReadAnswer (session, false); if (answer != null) { int id = (int) answer[RpcMessageLayout.RRC_COND_NUMBER]; Debug.WriteLineIf (Switch.Enabled, "RRC_COND_NUMBER: " + id); Future future = (Future) futures[id]; if (future != null) future.HandleAnswer (answer); } } } finally { futures.ReadUnlock (); } } else { // Unlock so that HandleAnswer for this future // can be called from another thread. Monitor.Exit (this); locked = false; futures.ReadWait (timeout); } } } finally { if (locked) { Monitor.Exit (this); } } }