public void FiberDone(RCRunner runner, long bot, long fiber, RCValue result) { Queue <RCClosure> waiters; RCValue botResult = null; lock (_fiberLock) { if (_fiberWaiters.TryGetValue(fiber, out waiters)) { _fiberWaiters.Remove(fiber); } if (!_fiberResults.ContainsKey(fiber)) { _fiberResults.Add(fiber, result); } else { // I wanted to draw a hard line and ensure this method was // called only once for each fiber, by the fiber or bot operator. // But it has to also be called from within try when there is nothing // to do next. if (!_fiberResults[fiber].Equals(result)) { throw new Exception("Conflicting results for fiber " + fiber); } } if (_fiberResults.Count == _fibers.Count) { botResult = _fiberResults[0L]; } } if (waiters != null) { RCNative exValue = result as RCNative; if (exValue != null && exValue.Value is Exception) { foreach (RCClosure waiter in waiters) { runner.Finish(waiter, (Exception)exValue.Value, 1); } } else { foreach (RCClosure waiter in waiters) { runner.Yield(waiter, result); } } } if (botResult != null) { runner.BotDone(bot, botResult); } }
protected void SafeYieldFromWait(RCClosure closure, RCValue result) { RCNative exValue = result as RCNative; if (exValue != null && exValue.Value is Exception) { Finish(closure, (Exception)exValue.Value, 1); } else { Yield(closure, result); } }