public void AddEvent(ReactorEvent new_event) { Monitor.Enter(events); events.Enqueue(new_event); Monitor.Pulse(events); Monitor.Exit(events); }
/// <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); }
/// <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); }
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); } }