Example #1
0
        /// <summary>
        /// Acquires a resource according to the specified resource request, either blocking until successful, or
        /// returning &lt;null&gt; 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));
            }
        }
Example #2
0
        /// <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);
            }
        }
Example #3
0
        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
            }
        }
Example #4
0
 /// <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();
     }
 }
Example #5
0
        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;
        }
Example #6
0
        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!");
        }
Example #7
0
        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
        }
Example #8
0
        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 + " ...");
                }
            }
        }
Example #9
0
        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
                }
            }
        }
Example #10
0
        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();
        }
Example #11
0
                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);
                }
Example #12
0
 public void Run()
 {
     m_exchange.TupleTaken += m_myEvent;
     m_idec.Suspend();
 }
Example #13
0
 private void WaitForAllActionsToComplete(IExecutive exec)
 {
     m_myIDEC = exec.CurrentEventController;
     m_myIDEC.Suspend();
 }
Example #14
0
 public void RunAndWait()
 {
     m_idec = m_model.Executive.CurrentEventController;
     m_idec.Suspend();
 }