public void ProcessCountChange(Pointstamp time, Int64 weight) { // the PCS should not be touched outside this lock, other than by capturing PCS.Frontier. Tracing.Trace("(PCSLock"); Monitor.Enter(this.PCS); var oldfrontier = PCS.Frontier; var frontierChanged = PCS.UpdatePointstampCount(time, weight); var newfrontier = PCS.Frontier; Monitor.Exit(this.PCS); Tracing.Trace(")PCSLock"); if (frontierChanged) { // get an exclusive lock, as this.Output.Send is not threadsafe. Tracing.Trace("(GlobalLock"); lock (this.scheduler.Controller.GlobalLock) { foreach (var pointstamp in newfrontier.Except(oldfrontier)) { this.Output.Send(+1, pointstamp); } foreach (var pointstamp in oldfrontier.Except(newfrontier)) { this.Output.Send(-1, pointstamp); } this.Output.Flush(); } Tracing.Trace(")GlobalLock"); if (this.OnFrontierChanged != null) { this.OnFrontierChanged(this, new FrontierChangedEventArgs(newfrontier)); } } }
public void ProcessCountChange(Pointstamp time, Int64 weight) { // the PCS should not be touched outside this lock, other than by capturing PCS.Frontier. Tracing.Trace("(PCSLock"); Monitor.Enter(this.PCS); var oldFrontier = PCS.Frontier; var frontierChanged = PCS.UpdatePointstampCount(time, weight); var newFrontier = PCS.Frontier; Monitor.Exit(this.PCS); Tracing.Trace(")PCSLock"); if (frontierChanged) { // aggregation may need to flush this.Aggregator.ConsiderFlushingBufferedUpdates(); // fire any frontier changed events if (this.OnFrontierChanged != null) { this.OnFrontierChanged(this, new FrontierChangedEventArgs(newFrontier)); } // no elements means done. if (newFrontier.Length == 0) { Tracing.Trace("Frontier advanced to <empty>"); this.FrontierEmpty.Set(); } else { Tracing.Trace("Frontier advanced to " + string.Join(" ", newFrontier.Select(x => x.ToString()))); } // Wake up schedulers to run shutdown actions for the graph. this.Stage.InternalGraphManager.Controller.Workers.WakeUp(); } }