Example #1
0
 public void AddEvent(ReactorEvent new_event)
 {
     Monitor.Enter(events);
     events.Enqueue(new_event);
     Monitor.Pulse(events);
     Monitor.Exit(events);
 }
Example #2
0
        /// <summary>
        /// Return the next event or null if there are no events and the
        /// timeout milliseconds have passed.
        /// </summary>
        /// <param name="timeout"></param>
        /// <returns></returns>
        private ReactorEvent GetNextEvent(int timeout)
        {
            if (timeout > 20)
            {
                timeout = 20;
            }

            ReactorEvent nextEvent = null;

            // If there's an event queued now, return the next immediately.
            Monitor.Enter(events);
            if (events.Count > 0)
            {
                nextEvent = events.Dequeue();
            }
            Monitor.Exit(events);

            if (nextEvent != null)
            {
                return(nextEvent);
            }

            // If no timeout because lot's of pending timers, return immediately.
            if (timeout == 0)
            {
                return(null);
            }

            // Wait for another event to be queued or for the timeout
            // to expire.
            Monitor.Enter(events);
            if (timeout > 0)
            {
                Monitor.Wait(events, timeout);
            }
            else
            {
                Monitor.Wait(events);
            }
            if (events.Count > 0)
            {
                nextEvent = events.Dequeue();
            }
            Monitor.Exit(events);

            return(nextEvent);
        }
Example #3
0
        /// <summary>
        /// Run timers and return the next event to process
        /// </summary>
        /// <returns></returns>
        public ReactorEvent Run(double current_time, double delta)
        {
            // By default go to sleep for half a second
            double shortest_timeout = 0.5;

            List <ReactorTimer> timers_copy = new List <ReactorTimer>(timers);

            foreach (ReactorTimer timer in timers_copy)
            {
                timer.timeout -= delta;
                // Call the timer event handler if needed.
                if (timer.timeout <= 0)
                {
                    if (timer.last_event_time == 0)
                    {
                        timer.last_event_time = current_time;
                    }

                    double timer_delta = current_time - timer.last_event_time;
                    timer.last_event_time = current_time;
                    timer.HandleTimerEvent(timer_delta);
                }
                // Check for timer expiry after calling handle event. The timer may have been
                // rescheduled in HandleTimerEvent and thus is no longer expired
                if (timer.timeout <= 0)
                {
                    timers.Remove(timer);
                }
                // Record when the next timeout is so we don't block too long in the
                // event queue
                else if (timer.timeout < shortest_timeout)
                {
                    shortest_timeout = timer.timeout;
                }
            }

            ReactorEvent next_event = GetNextEvent((int)(shortest_timeout * 1000));

            if (next_event != null)
            {
                double queue_time = GetTime() - next_event.event_start;
                average_queue_time += queue_time;
            }
            average_queue_time /= 2;
            return(next_event);
        }
Example #4
0
        void ThreadRun()
        {
            System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture;
            double current_time = GetTime();

            bool running = true;

            while (running)
            {
                // Calculate the delta time.
                double delta = GetTime() - current_time;
                current_time += delta;

                // Call the reactor to return the next event the process
                // and run any timer functions.
                ReactorEvent next_event = Run(current_time, delta);
                if (next_event is ReactorShutdownEvent)
                {
                    running = false;
                }
                else if (next_event is LogEvent)
                {
                    LogEvent log_event = next_event as LogEvent;

                    if (console)
                    {
                        Console.WriteLine(log_event.message);
                    }
                    else if (logpath.Length > 0)
                    {
                        StreamWriter writer = File.AppendText(logpath);
                        writer.WriteLine(log_event.message);
                        writer.Close();
                    }
                }

                System.Threading.Thread.Sleep(0);
            }
        }