/// <summary> /// Acquires a resource according to the specified resource request, either blocking until successful, or /// returning <null> if the resource is not immediately available. /// </summary> /// <param name="resourceRequest">The IResourceRequest that specifies the criteria by which to select the resource.</param> /// <param name="blockAwaitingAcquisition">If true, request will suspend until granted. If false, will return false if unable to fulfill.</param> /// <returns>True if granted, false if not granted.</returns> public bool Acquire(IResourceRequest resourceRequest, bool blockAwaitingAcquisition) { if (blockAwaitingAcquisition) { IDetachableEventController dec = Model.Executive.CurrentEventController; if (dec == null) { throw new ApplicationException("Someone tried to call Acquire(..., true) while not in a detachable event. This is not allowed."); } dec.SetAbortHandler(resourceRequest.AbortHandler); resourceRequest.ResourceRequestAborting += m_onResourceRequestAborting; while (true) { if (Acquire(resourceRequest)) { break; } m_waiters.Add(dec); dec.Suspend(); dec.ClearAbortHandler(); } return(true); } else { return(Acquire(resourceRequest)); } }
/// <summary> /// Acquires the resource and quantity specifed by the resource request, blocking /// until it can return successfully. /// </summary> /// <param name="request">The resource request that describes the desired resource and quantity.</param> /// <returns>Always true.</returns> protected bool AcquireWithWait(IResourceRequest request) { IDetachableEventController dec = Model.Executive.CurrentEventController; if (dec == null) { throw new ApplicationException("Someone tried to call AcquireWithWait() while not in a detachable event. This is not allowed."); } dec.SetAbortHandler(request.AbortHandler); request.ResourceRequestAborting += m_onResourceRequestAborting; while (!Acquire(request, false)) { m_waiters.Add(request, dec); dec.Suspend(); dec.ClearAbortHandler(); } if (request.ResourceObtained != null) { ResourceAcquired?.Invoke(request, request.ResourceObtained); return(true); } else { return(false); } }
private ITuple BlockingTake(object key) { #region Ensure that this is a Detachable Event. #if DEBUG if (m_exec.CurrentEventType != ExecEventType.Detachable) { throw new ApplicationException("Attempt to do a blocking take with an executive event that is not Detachable."); } #endif #endregion while (true) { ITuple tuple = NonBlockingTake(key); if (tuple != null) { return(tuple); } #region Wait 'til next take against this key. IDetachableEventController idec = m_exec.CurrentEventController; m_waitersToTake.Add(key, idec); idec.Suspend(); #endregion } }
/// <summary> /// Blocks the caller's detachable event thread until this transfer has started. /// </summary> public void BlockTilStart() { _Debug.Assert(m_model.Executive.CurrentEventType == ExecEventType.Detachable); if (m_completionKey == long.MinValue /*i.e. it has not started*/) { IDetachableEventController waiter = m_model.Executive.CurrentEventController; m_startWaiters.Add(waiter); waiter.Suspend(); } }
private void ProcessGetters(IExecutive exec, object userData) { m_getProcessor = exec.CurrentEventController; IDetachableEventController waiter = null; while (m_waiters.Count > 0 && m_waiters[0] != waiter) { waiter = m_waiters[0]; waiter.Resume(); m_getProcessor.Suspend(); } m_getFlushEventId = -1; m_getProcessor = s_dummyIdec; }
protected void GetPermissionToStart(PfcExecutionContext myPfcec, StepStateMachine ssm) { PfcExecutionContext root = myPfcec; int ascents = m_rootHeight; while (ascents > 0) { root = (PfcExecutionContext)myPfcec.Parent.Payload; ascents--; } Exchange exchange = null; if (m_myIndex == 0) { //Console.WriteLine(myPfcec.Name + " is creating an exchange and injecting it into pfcec " + root.Name + " under key " + m_sequenceKey); exchange = new Exchange(myPfcec.Model.Executive); root.Add(m_sequenceKey, exchange); } else { //Console.WriteLine(myPfcec.Name + " is looking for an exchange in pfcec " + root.Name + " under key " + m_sequenceKey); DictionaryChange dc = new DictionaryChange(myPfcec_EntryAdded); while (true) { exchange = (Exchange)root[m_sequenceKey]; if (exchange == null) { root.EntryAdded += dc; m_idec = myPfcec.Model.Executive.CurrentEventController; m_idec.Suspend(); } else { root.EntryAdded -= dc; break; } } exchange.Take(m_myKey, true); // Only indices 1,2, ... take (and wait?). Index 0 only posts. //Console.WriteLine(myPfcec.Name + " got the key I was looking for!"); } Guid nextGuysKey = GuidOps.Increment(m_myKey); exchange.Post(nextGuysKey, nextGuysKey, false); //Console.WriteLine(myPfcec.Name + " posted the key the next guy is looking for!"); }
private void BlockingPost(ITuple tuple) { #region Ensure that this is a Detachable Event. #if DEBUG if (m_exec.CurrentEventType != ExecEventType.Detachable) { throw new ApplicationException("Attempt to do a blocking post with an executive event that is not Detachable."); } #endif #endregion NonBlockingPost(tuple); #region Wait 'til next take against this key. IDetachableEventController idec = m_exec.CurrentEventController; m_blockedPosters.Add(tuple.Key, idec); idec.Suspend(); #endregion }
internal void GetStartPermission(PfcExecutionContext pfcec) { IDetachableEventController currentEventController = m_myStep.Model.Executive.CurrentEventController; SsmData ssmData = GetSsmData(pfcec); if (!ssmData.State.Equals(StepState.Idle)) { ssmData.QueueIdec.Enqueue(currentEventController); if (s_diagnostics) { Console.WriteLine(m_myStep.Model.Executive.Now + " : suspending awaiting start of " + m_myStep.Name + " ..."); } currentEventController.Suspend(); if (s_diagnostics) { Console.WriteLine(m_myStep.Model.Executive.Now + " : resuming the starting of " + m_myStep.Name + " ..."); } } }
private ITuple BlockingRead(object key) { lock ( m_ts ) { while (true) { ITuple tuple = NonBlockingRead(key); if (tuple != null) { return(tuple); } #region Wait 'til next post against this key. IDetachableEventController idec = m_exec.CurrentEventController; m_waitersToRead.Add(key, idec); idec.Suspend(); #endregion } } }
private void LogSynchronization(object sortKey, IDetachableEventController idec, SynchChannel sc) { if (m_waiters.ContainsValue(idec)) { throw new ApplicationException("Synchronize(...) called on a SynchChannel that is already waiting."); } if (!m_synchChannels.Contains(sc)) { throw new ApplicationException("SynchChannel applied to a synchronizer that did not own it - serious error."); } if ((m_waiters.Count + 1) == m_synchChannels.Count) { m_exec.RequestEvent(new ExecEventReceiver(LaunchAll), m_exec.Now, m_exec.CurrentPriorityLevel, null); } m_waiters.Add(sortKey, idec); idec.SetAbortHandler(new DetachableEventAbortHandler(idec_AbortionEvent)); idec.Suspend(); idec.ClearAbortHandler(); }
public void FixTheSink(IExecutive exec, object userData) { IDetachableEventController idec = exec.CurrentEventController; Console.WriteLine("{0} : {1} is starting to fix the sink.", exec.Now, Name); idec.SuspendFor(TimeSpan.FromMinutes(10.0)); // When the suspend call returns, 10 minutes have passed. Console.WriteLine("{0} : {1} discovered that the disposal needed rewiring.", exec.Now, Name); DateTime when = exec.Now + TimeSpan.FromMinutes(5.0); exec.RequestEvent(new Electrician("Edgar").RewireDisposal, when, idec); Console.WriteLine("{0} : {1} called the electrician and is starting to eat lunch.", exec.Now, Name); idec.Suspend(); // When the suspend call returns (from the electrician calling "Resume",) // the electrician is done, and presumably the sink is fixed. Console.WriteLine("{0} : {1} was told by the electrician that the disposal is fixed.", exec.Now, Name); Console.WriteLine("{0} : {1} is resuming fixing the sink.", exec.Now, Name); idec.SuspendFor(TimeSpan.FromMinutes(40.0)); // Finishing fixing the sink requires 40 minutes, // and on return from this call, that time has passed. Console.WriteLine("{0} : {1} is done fixing the sink.", exec.Now, Name); }
public void Run() { m_exchange.TupleTaken += m_myEvent; m_idec.Suspend(); }
private void WaitForAllActionsToComplete(IExecutive exec) { m_myIDEC = exec.CurrentEventController; m_myIDEC.Suspend(); }
public void RunAndWait() { m_idec = m_model.Executive.CurrentEventController; m_idec.Suspend(); }