/// <summary> /// Constructor. /// </summary> /// <param name="e">Event</param> /// <param name="originInfo">EventOriginInfo</param> internal EventInfo(Event e, EventOriginInfo originInfo) { this.Event = e; this.EventType = e.GetType(); this.EventName = this.EventType.FullName; this.OriginInfo = originInfo; }
/// <summary> /// Handles the given event. /// </summary> /// <param name="e">Event to handle</param> private void HandleEvent(Event e) { // Do not process an ignored event. if (this.IgnoredEvents.Contains(e.GetType())) { Output.Log("<IgnoreLog> Monitor '{0}' ignored event '{1}'.", this.GetType().Name, e.GetType()); return; } // Assign trigger and payload. this.Trigger = e.GetType(); this.Payload = e.Payload; while (true) { if (this.State == null) { // If the event cannot be handled then report an error and exit. this.Assert(false, "Monitor '{0}' received event '{1}' that cannot be handled.", this.GetType().Name, e.GetType().Name); } // If current state cannot handle the event then null the state. if (!this.CanHandleEvent(e.GetType())) { Output.Debug(DebugType.Runtime, "<ExitLog> Monitor '{0}' exiting state '{1}'.", this, this.State.GetType().Name); this.State = null; continue; } // Checks if the event can trigger a goto state transition. if (this.GotoTransitions.ContainsKey(e.GetType())) { var transition = this.GotoTransitions[e.GetType()]; Type targetState = transition.Item1; Action onExitAction = transition.Item2; this.GotoState(targetState, onExitAction); } // Checks if the event can trigger an action. else if (this.ActionBindings.ContainsKey(e.GetType())) { Action action = this.ActionBindings[e.GetType()]; this.Do(action); } break; } }
/// <summary> /// Notifies the monitor to handle the received event. /// </summary> /// <param name="e">Event</param> internal void MonitorEvent(Event e) { Output.Debug(DebugType.Runtime, "<EnqueueLog> Monitor '{0}' is processing " + "event '{1}'.", this, e.GetType()); this.HandleEvent(e); }
/// <summary> /// Raises an event internally and returns from the execution context. /// </summary> /// <param name="e">Event</param> protected internal void Raise(Event e) { // If the event is null then report an error and exit. this.Assert(e != null, "Monitor '{0}' is raising a null event.", this.GetType().Name); base.Runtime.Log("<MonitorLog> Monitor '{0}' raised event '{1}'.", this, e.GetType().FullName); this.HandleEvent(e); }
/// <summary> /// Notifies the monitor to handle the received event. /// </summary> /// <param name="e">Event</param> internal void MonitorEvent(Event e) { base.Runtime.Log("<MonitorLog> Monitor '{0}' is processing event '{1}'.", this, e.GetType().FullName); this.HandleEvent(e); }
/// <summary> /// Handles the given event. /// </summary> /// <param name="e">Event to handle</param> private void HandleEvent(Event e) { // Do not process an ignored event. if (this.IgnoredEvents.Contains(e.GetType())) { return; } // Assigns the receieved event. this.ReceivedEvent = e; while (true) { if (this.State == null) { // If the event cannot be handled, then report an error and exit. this.Assert(false, $"Monitor '{this.GetType().Name}' received event " + $"'{e.GetType().FullName}' that cannot be handled."); } // If current state cannot handle the event then null the state. if (!this.CanHandleEvent(e.GetType())) { base.Runtime.NotifyExitedState(this); this.State = null; continue; } // Checks if the event is a goto state event. if (e.GetType() == typeof(GotoStateEvent)) { Type targetState = (e as GotoStateEvent).State; this.GotoState(targetState, null); } // Checks if the event can trigger a goto state transition. else if (this.GotoTransitions.ContainsKey(e.GetType())) { var transition = this.GotoTransitions[e.GetType()]; this.GotoState(transition.Item1, transition.Item2); } // Checks if the event can trigger an action. else if (this.ActionBindings.ContainsKey(e.GetType())) { string actionName = this.ActionBindings[e.GetType()]; this.Do(actionName); } break; } }
/// <summary> /// Notifies the monitor to handle the received event. /// </summary> /// <param name="e">Event</param> internal void MonitorEvent(Event e) { base.Runtime.Log($"<MonitorLog> Monitor '{this.GetType().Name}' " + $"is processing event '{e.GetType().FullName}'."); this.HandleEvent(e); }
/// <summary> /// Notifies the monitor to handle the received event. /// </summary> /// <param name="e">Event</param> internal void MonitorEvent(Event e) { this.Runtime.Logger.OnMonitorEvent(this.GetType().Name, this.Id, this.CurrentStateName, e.GetType().FullName, isProcessing: true); this.HandleEvent(e); }
/// <summary> /// Handles the given event. /// </summary> /// <param name="e">Event to handle</param> private void HandleEvent(Event e) { while (true) { if (this.StateStack.Count == 0) { // If the stack of states is empty and the event // is halt, then terminate the machine. if (e.GetType().Equals(typeof(Halt))) { lock (this.Inbox) { Machine.Dispatcher.Log("<HaltLog> Machine '{0}({1})' halted.", this.GetType().Name, base.Id.MVal); this.IsHalted = true; this.CleanUpResources(); } return; } // If the event cannot be handled then report an error and exit. this.Assert(false, "Machine '{0}' received event '{1}' that cannot be handled.", this.GetType().Name, e.GetType().Name); } // If current state cannot handle the event then pop the state. if (!this.CanHandleEvent(e.GetType())) { // The machine performs the on exit action of the current state. this.ExecuteCurrentStateOnExit(null); if (this.IsHalted) { return; } this.StateStack.Pop(); if (this.StateStack.Count == 0) { Machine.Dispatcher.Log("<PopLog> Machine '{0}({1})' popped with unhandled event '{2}'.", this, base.Id.MVal, e.GetType().Name); } else { Machine.Dispatcher.Log("<PopLog> Machine '{0}({1})' popped with unhandled event '{2}' " + "and reentered state '{3}.", this, base.Id.MVal, e.GetType().Name, this.StateStack.Peek().GetType().Name); this.ConfigureStateTransitions(this.StateStack.Peek()); } continue; } // Checks if the event can trigger a goto state transition. if (this.GotoTransitions.ContainsKey(e.GetType())) { var transition = this.GotoTransitions[e.GetType()]; Type targetState = transition.Item1; Action onExitAction = transition.Item2; this.GotoState(targetState, onExitAction); } // Checks if the event can trigger a push state transition. else if (this.PushTransitions.ContainsKey(e.GetType())) { Type targetState = this.PushTransitions[e.GetType()]; this.PushState(targetState); } // Checks if the event can trigger an action. else if (this.ActionBindings.ContainsKey(e.GetType())) { Action action = this.ActionBindings[e.GetType()]; this.Do(action); } break; } }
/// <summary> /// Notifies the monitor to handle the received event. /// </summary> /// <param name="e">Event</param> internal void MonitorEvent(Event e) { Machine.Dispatcher.Log("<MonitorLog> Monitor '{0}' is processing event '{1}'.", this, e.GetType()); this.HandleEvent(e); }
/// <summary> /// Constructor. /// </summary> /// <param name="e">Event</param> internal EventInfo(Event e) { this.Event = e; this.EventType = e.GetType(); this.EventName = this.EventType.FullName; }
/// <summary> /// Sends an asynchronous event to a machine. /// </summary> /// <param name="mid">Machine id</param> /// <param name="e">Event</param> internal static void Send(MachineId mid, Event e) { if (mid == null) { ErrorReporter.ReportAndExit("Cannot send to a null machine."); } else if (e == null) { ErrorReporter.ReportAndExit("Cannot send a null event."); } if (PSharpRuntime.TaskMap.ContainsKey((int)Task.CurrentId)) { Machine sender = PSharpRuntime.TaskMap[(int)Task.CurrentId]; Output.Log("<SendLog> Machine '{0}({1})' sent event '{2}' to '{3}({4})'.", sender, sender.Id.MVal, e.GetType(), mid.Type, mid.MVal); } else { Output.Log("<SendLog> Event '{0}' was sent to '{1}({2})'.", e.GetType(), mid.Type, mid.MVal); } Machine machine = PSharpRuntime.MachineMap[mid.Value]; bool runHandler = false; machine.Enqueue(e, ref runHandler); if (!runHandler) { PSharpRuntime.BugFinder.Schedule(); return; } Task task = new Task(() => { PSharpRuntime.BugFinder.NotifyTaskStarted(); machine.RunEventHandler(); PSharpRuntime.BugFinder.NotifyTaskCompleted(); }); lock (PSharpRuntime.Lock) { PSharpRuntime.MachineTasks.Add(task); PSharpRuntime.TaskMap.Add(task.Id, machine as Machine); } PSharpRuntime.BugFinder.NotifyNewTaskCreated(task.Id, machine); if (PSharpRuntime.Configuration.ScheduleIntraMachineConcurrency) { task.Start(PSharpRuntime.TaskScheduler); } else { task.Start(); } PSharpRuntime.BugFinder.WaitForTaskToStart(task.Id); PSharpRuntime.BugFinder.Schedule(); }