Пример #1
0
 /// <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;
 }
Пример #2
0
        /// <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;
            }
        }
Пример #3
0
 /// <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);
 }
Пример #4
0
 /// <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);
 }
Пример #5
0
 /// <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);
 }
Пример #6
0
        /// <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;
            }
        }
Пример #7
0
 /// <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);
 }
Пример #8
0
 /// <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);
 }
Пример #9
0
 /// <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);
 }
Пример #10
0
 /// <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);
 }
Пример #11
0
        /// <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;
            }
        }
Пример #12
0
 /// <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);
 }
Пример #13
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="e">Event</param>
 internal EventInfo(Event e)
 {
     this.Event = e;
     this.EventType = e.GetType();
     this.EventName = this.EventType.FullName;
 }
Пример #14
0
        /// <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();
        }
Пример #15
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="e">Event</param>
 internal EventInfo(Event e)
 {
     this.Event     = e;
     this.EventType = e.GetType();
     this.EventName = this.EventType.FullName;
 }