private static void InvokeOnMaster(Action action, bool synchronous) { Assure.NotNull(action); PipelineProcessor processorLocal; lock (staticMutationLock) { if (!IsRunning) { try { ThrowIfCurrentThreadIsNotMaster(); } catch (InvalidOperationException e) { throw new InvalidOperationException("Can not execute given operation from any thread but the master when the " + "pipeline is not running. Either start the system or move the operation to the master thread.", e); } action(); return; } processorLocal = processor; } PipelineMasterInvocation pmi = PipelineMasterInvocation.Create(action, synchronous); processorLocal.InvokeOnMaster(pmi); if (pmi.IsSynchronousCall) { if (pmi.RaisedException != null) { ExceptionDispatchInfo.Capture(pmi.RaisedException).Throw(); } PipelineMasterInvocation.Free(pmi); } }
public static PipelineMasterInvocation Create(Action action, bool isSynchronousCall) { if (objectPool == null) { objectPool = new Stack <PipelineMasterInvocation>(); } PipelineMasterInvocation result; if (objectPool.Count == 0) { if (leasedAsync != null) { for (int i = leasedAsync.Count - 1; i >= 0; --i) { if (leasedAsync[i].AsyncRoutineComplete) { objectPool.Push(leasedAsync[i]); leasedAsync.RemoveAt(i); } } if (objectPool.Count > 0) { result = objectPool.Pop(); } else { result = new PipelineMasterInvocation(); } } else { result = new PipelineMasterInvocation(); } } else { result = objectPool.Pop(); } result.action = action; result.isSynchronousCall = isSynchronousCall; result.raisedException = null; if (!isSynchronousCall) { result.AsyncRoutineComplete = false; if (leasedAsync == null) { leasedAsync = new List <PipelineMasterInvocation>(); } leasedAsync.Add(result); } return(result); }
public void SlaveQueueOnMaster(PipelineMasterInvocation pmi) { Assure.NotNull(pmi); Assure.NotEqual(Thread.CurrentThread, LosgapSystem.MasterThread); Monitor.Enter(barrierOpenLock); masterInvocationQueue.Enqueue(pmi); Monitor.Pulse(barrierOpenLock); object externalLockObjLocal; lock (externalLockObjLock) { externalLockObjLocal = externalLockObj; } Monitor.Exit(barrierOpenLock); if (externalLockObjLocal != null) { Monitor.Enter(externalLockObjLocal); Monitor.PulseAll(externalLockObjLocal); Monitor.Exit(externalLockObjLocal); } }
public void InvokeOnMaster(PipelineMasterInvocation pmi) { if (isDisposed) { throw new ObjectDisposedException("Can not invoke actions on master when pipeline is disposed!"); } if (Thread.CurrentThread == LosgapSystem.MasterThread) { try { pmi.Action(); } catch (Exception e) { if (pmi.IsSynchronousCall) { pmi.RaisedException = e; } else { LosgapSystem.ExitWithError("Exception raised in asynchronous pipeline master invocation.", e); } } } else { if (pmi.IsSynchronousCall) { Monitor.Enter(pmi.InvocationCompleteMonitor); ParallelizationProvider.SlaveQueueOnMaster(pmi); Monitor.Wait(pmi.InvocationCompleteMonitor); Monitor.Exit(pmi.InvocationCompleteMonitor); } else { ParallelizationProvider.SlaveQueueOnMaster(pmi); } } }
internal void SlaveQueueOnMaster(PipelineMasterInvocation pmi) { WorkBarrier.SlaveQueueOnMaster(pmi); }
public static void Free(PipelineMasterInvocation pmi) { objectPool.Push(pmi); }