Esempio n. 1
0
        /**
         * @brief A script instance was just removed from the Start or Yield Queue.
         *        So run it for a little bit then stick in whatever queue it should go in.
         */
        private void RunInstance(XMRInstance inst, int tid)
        {
            m_LastRanAt       = DateTime.UtcNow;
            m_ScriptExecTime -= (long)(m_LastRanAt - DateTime.MinValue).TotalMilliseconds;
            inst.m_IState     = XMRInstState.RUNNING;
            lock (m_WakeUpLock) {
                m_RunningInstances[tid] = inst;
            }
            XMRInstState newIState = inst.RunOne();

            lock (m_WakeUpLock) {
                m_RunningInstances[tid] = null;
            }
            HandleNewIState(inst, newIState);
            m_ScriptExecTime += (long)(DateTime.UtcNow - DateTime.MinValue).TotalMilliseconds;
        }
Esempio n. 2
0
        /**
         * @brief The user clicked the Reset Script button.
         *        We want to reset the script to a never-has-ever-run-before state.
         */
        public void Reset()
        {
checkstate:
            XMRInstState iState = m_IState;

            switch (iState)
            {
            // If it's really being constructed now, that's about as reset as we get.
            case XMRInstState.CONSTRUCT:
                return;

            // If it's idle, that means it is ready to receive a new event.
            // So we lock the event queue to prevent another thread from taking
            // it out of idle, verify that it is still in idle then transition
            // it to resetting so no other thread will touch it.
            case XMRInstState.IDLE:
                lock (m_QueueLock)
                {
                    if (m_IState == XMRInstState.IDLE)
                    {
                        m_IState = XMRInstState.RESETTING;
                        break;
                    }
                }
                goto checkstate;

            // If it's on the start queue, that means it is about to dequeue an
            // event and start processing it.  So we lock the start queue so it
            // can't be started and transition it to resetting so no other thread
            // will touch it.
            case XMRInstState.ONSTARTQ:
                lock (m_Engine.m_StartQueue)
                {
                    if (m_IState == XMRInstState.ONSTARTQ)
                    {
                        m_Engine.m_StartQueue.Remove(this);
                        m_IState = XMRInstState.RESETTING;
                        break;
                    }
                }
                goto checkstate;

            // If it's running, tell CheckRun() to suspend the thread then go back
            // to see what it got transitioned to.
            case XMRInstState.RUNNING:
                suspendOnCheckRunHold = true;
                lock (m_QueueLock)
                {
                }
                goto checkstate;

            // If it's sleeping, remove it from sleep queue and transition it to
            // resetting so no other thread will touch it.
            case XMRInstState.ONSLEEPQ:
                lock (m_Engine.m_SleepQueue)
                {
                    if (m_IState == XMRInstState.ONSLEEPQ)
                    {
                        m_Engine.m_SleepQueue.Remove(this);
                        m_IState = XMRInstState.RESETTING;
                        break;
                    }
                }
                goto checkstate;

            // It was just removed from the sleep queue and is about to be put
            // on the yield queue (ie, is being woken up).
            // Let that thread complete transition and try again.
            case XMRInstState.REMDFROMSLPQ:
                Sleep(10);
                goto checkstate;

            // If it's yielding, remove it from yield queue and transition it to
            // resetting so no other thread will touch it.
            case XMRInstState.ONYIELDQ:
                lock (m_Engine.m_YieldQueue)
                {
                    if (m_IState == XMRInstState.ONYIELDQ)
                    {
                        m_Engine.m_YieldQueue.Remove(this);
                        m_IState = XMRInstState.RESETTING;
                        break;
                    }
                }
                goto checkstate;

            // If it just finished running something, let that thread transition it
            // to its next state then check again.
            case XMRInstState.FINISHED:
                Sleep(10);
                goto checkstate;

            // If it's disposed, that's about as reset as it gets.
            case XMRInstState.DISPOSED:
                return;

            // Some other thread is already resetting it, let it finish.

            case XMRInstState.RESETTING:
                return;

            default:
                throw new Exception("bad state");
            }

            // This thread transitioned the instance to RESETTING so reset it.
            lock (m_RunLock)
            {
                CheckRunLockInvariants(true);

                // No other thread should have transitioned it from RESETTING.
                if (m_IState != XMRInstState.RESETTING)
                {
                    throw new Exception("bad state");
                }

                // Mark it idle now so it can get queued to process new stuff.
                m_IState = XMRInstState.IDLE;

                // Reset everything and queue up default's start_entry() event.
                ClearQueue();
                ResetLocked("external Reset");

                CheckRunLockInvariants(true);
            }
        }