Пример #1
0
        //
        // The timer thread.
        //

        private static void TimerThread()
        {
            //
            // The timer thread is a background thread.
            //

            Thread.CurrentThread.IsBackground = true;
            Thread.CurrentThread.Name         = "StTimers";

            do
            {
                //
                // Acquire the timer list lock.
                //

                _lock.Enter();

                //
                // If the limit timer was activated, remove it from the timer list.
                //

                if (limitTimer.next != limitTimer)
                {
                    if (limitTimer.next != timerListHead)
                    {
                        limitTimer.next.delay += limitTimer.delay;
                    }
                    RemoveTimerFromList(limitTimer);
                    limitTimer.next = limitTimer;
                }

                //
                // Adjust the base time and the timer list and process
                // expired timers.
                //

                AdjustBaseTime();

                //
                // Initializes the parker and compute the time at which the
                // front timer must expire.
                //

                parker.Reset(1);

                //
                // If the first timer ...
                //

                RawTimer first = timerListHead.next;
                int      btime = baseTime;
                int      delay;

                if ((delay = first.delay) > MAXIMUM_SLEEP_TIME)
                {
                    limitTimer.delay = MAXIMUM_SLEEP_TIME;
                    InsertHeadTimerList(timerListHead, limitTimer);
                    if (first != timerListHead)
                    {
                        first.delay -= MAXIMUM_SLEEP_TIME;
                    }
                    delay = MAXIMUM_SLEEP_TIME;
                }

                //
                // Get the fired timers list and empty it.
                //

                RawTimer fired = TimerList.firedTimers;
                TimerList.firedTimers = null;

                //
                // Release the timer list's lock.
                //

                _lock.Exit();

                //
                // Call unpark method on the expired timer's parkers.
                //

                while (fired != null)
                {
                    RawTimer next = fired.prev;
                    fired.parker.Unpark(StParkStatus.Timeout);
                    fired = next;
                }

                //
                // Since that the timer thread can take significant time to execute
                // the timer's callbacks, we must ajust the *delay*, if needed.
                //

                int sliding;
                if ((sliding = Environment.TickCount - btime) != 0)
                {
                    delay = (sliding >= delay) ? 0 : (delay - sliding);
                }

                //
                // Park the timer thread until the next timer expires or a new
                // timer is inserted at front of the timer list.
                //

                parker.Park(new StCancelArgs(delay));
            } while (true);

            //
            // We never get here!
            //
        }