示例#1
0
        /// <summary>
        /// Creates a new <see cref="Machine"/> of the specified <see cref="Type"/>. The
        /// method returns only when the machine is initialized and the <see cref="Event"/>
        /// (if any) is handled.
        /// </summary>
        /// <param name="type">Type of the machine</param>
        /// <param name="friendlyName">Friendly machine name used for logging</param>
        /// <param name="e">Event passed during machine construction</param>
        /// <param name="creator">Creator machine</param>
        /// <returns>MachineId</returns>
        internal override async Task <MachineId> CreateMachineAndExecute(Type type, string friendlyName, Event e, Machine creator)
        {
            Machine machine = this.CreateMachine(type, friendlyName);

            await this.RunMachineEventHandlerAsync(machine, e, true);

            return(machine.Id);
        }
示例#2
0
 internal virtual void NotifyDefaultHandlerFired(Machine machine)
 {
     // Override to implement the notification.
 }
示例#3
0
        /// <summary>
        /// Creates a new <see cref="Machine"/> of the specified <see cref="Type"/>.
        /// </summary>
        /// <param name="type">Type of the machine</param>
        /// <param name="friendlyName">Friendly machine name used for logging</param>
        /// <param name="e">Event passed during machine construction</param>
        /// <param name="creator">Creator machine</param>
        /// <returns>MachineId</returns>
        internal override MachineId CreateMachine(Type type, string friendlyName, Event e, Machine creator)
        {
            Machine machine = this.CreateMachine(type, friendlyName);

            this.RunMachineEventHandler(machine, e, true);
            return(machine.Id);
        }
示例#4
0
 internal virtual void NotifyReceivedEvent(Machine machine, EventInfo eventInfo)
 {
     // Override to implement the notification.
 }
示例#5
0
 internal virtual void NotifyHalted(Machine machine, LinkedList <EventInfo> inbox)
 {
     // Override to implement the notification.
 }
示例#6
0
 /// <summary>
 /// Notifies that a machine has halted.
 /// </summary>
 /// <param name="machine">Machine</param>
 internal override void NotifyHalted(Machine machine)
 {
     base.Log($"<HaltLog> Machine '{machine.Id}' halted.");
     this.MachineMap.TryRemove(machine.Id.Value, out machine);
 }
示例#7
0
        /// <summary>
        /// Notifies that a machine received an event that it was waiting for.
        /// </summary>
        /// <param name="mid">Machine id</param>
        internal static void NotifyReceivedEvent(MachineId mid)
        {
            Machine machine = PSharpRuntime.MachineMap[mid.Value];

            PSharpRuntime.BugFinder.NotifyTaskReceivedEvent(machine);
        }
示例#8
0
 internal virtual void NotifyCompletedAction(Machine machine, MethodInfo action, Event receivedEvent)
 {
     // Override to implement the notification.
 }
示例#9
0
 internal virtual void NotifyPop(Machine machine)
 {
     // Override to implement the notification.
 }
示例#10
0
 internal virtual bool CheckStartEventHandler(Machine machine)
 {
     return(true);
 }
示例#11
0
 internal virtual void NotifyExitedState(Machine machine)
 {
     // Override to implement the notification.
 }
示例#12
0
 /// <summary>
 /// Creates a new remote <see cref="Machine"/> of the specified <see cref="System.Type"/>.
 /// </summary>
 /// <param name="type">Type of the machine</param>
 /// <param name="friendlyName">Friendly machine name used for logging</param>
 /// <param name="endpoint">Endpoint</param>
 /// <param name="operationGroupId">Operation group id</param>
 /// <param name="e">Event passed during machine construction</param>
 /// <param name="creator">Creator machine</param>
 /// <returns>MachineId</returns>
 internal abstract MachineId CreateRemoteMachine(Type type, string friendlyName, string endpoint,
                                                 Event e, Machine creator, Guid?operationGroupId);
示例#13
0
 /// <summary>
 /// Creates a new <see cref="Machine"/> of the specified <see cref="Type"/>. The
 /// method returns only when the machine is initialized and the <see cref="Event"/>
 /// (if any) is handled.
 /// </summary>
 /// <param name="mid">Unbound machine id</param>
 /// <param name="type">Type of the machine</param>
 /// <param name="friendlyName">Friendly machine name used for logging</param>
 /// <param name="e">Event passed during machine construction</param>
 /// <param name="operationGroupId">Operation group id</param>
 /// <param name="creator">Creator machine</param>
 /// <returns>MachineId</returns>
 internal abstract Task <MachineId> CreateMachineAndExecute(MachineId mid, Type type, string friendlyName, Event e, Machine creator, Guid?operationGroupId);
示例#14
0
 /// <summary>
 /// Creates a new <see cref="Machine"/> of the specified <see cref="Type"/>.
 /// </summary>
 /// <param name="mid">Unbound machine id</param>
 /// <param name="type">Type of the machine</param>
 /// <param name="friendlyName">Friendly machine name used for logging</param>
 /// <param name="operationGroupId">Operation group id</param>
 /// <param name="e">Event passed during machine construction</param>
 /// <param name="creator">Creator machine</param>
 /// <returns>MachineId</returns>
 internal abstract MachineId CreateMachine(MachineId mid, Type type, string friendlyName, Event e, Machine creator, Guid?operationGroupId);
示例#15
0
 /// <summary>
 /// Notifies that a machine dequeued an <see cref="Event"/>.
 /// </summary>
 /// <param name="machine">Machine</param>
 /// <param name="eventInfo">EventInfo</param>
 internal override void NotifyDequeuedEvent(Machine machine, EventInfo eventInfo)
 {
     base.Log($"<DequeueLog> Machine '{machine.Id}' dequeued " +
              $"event '{eventInfo.EventName}'.");
 }
示例#16
0
 internal virtual void NotifyReceiveCalled(Machine machine)
 {
     // Override to implement the notification.
 }
示例#17
0
 /// <summary>
 /// Notifies that a machine is waiting to receive one or more events.
 /// </summary>
 /// <param name="machine">Machine</param>
 internal override void NotifyWaitEvents(Machine machine)
 {
     base.Log($"<ReceiveLog> Machine '{machine.Id}' is waiting to receive an event.");
 }
示例#18
0
 /// <summary>
 /// Notifies that a machine is waiting to receive one or more events.
 /// </summary>
 /// <param name="machine">Machine</param>
 /// <param name="eventInfoInInbox">The event info if it is in the inbox, else null</param>
 internal virtual void NotifyWaitEvents(Machine machine, EventInfo eventInfoInInbox)
 {
     // Override to implement the notification.
 }
示例#19
0
        /// <summary>
        /// Initializes the state.
        /// </summary>
        /// <param name="machine">Machine</param>
        internal void InitializeState(Machine machine)
        {
            this.Machine = machine;

            this.GotoTransitions = new GotoStateTransitions();
            this.PushTransitions = new PushStateTransitions();
            this.ActionBindings  = new ActionBindings();

            this.IgnoredEvents  = new HashSet <Type>();
            this.DeferredEvents = new HashSet <Type>();

            var entryAttribute = this.GetType().GetCustomAttribute(typeof(OnEntry), false) as OnEntry;
            var exitAttribute  = this.GetType().GetCustomAttribute(typeof(OnExit), false) as OnExit;

            if (entryAttribute != null)
            {
                var method = this.Machine.GetType().GetMethod(entryAttribute.Action,
                                                              BindingFlags.NonPublic | BindingFlags.Instance);
                var action = (Action)Delegate.CreateDelegate(typeof(Action), this.Machine, method);
                this.EntryAction = action;
            }

            if (exitAttribute != null)
            {
                var method = this.Machine.GetType().GetMethod(exitAttribute.Action,
                                                              BindingFlags.NonPublic | BindingFlags.Instance);
                var action = (Action)Delegate.CreateDelegate(typeof(Action), this.Machine, method);
                this.ExitAction = action;
            }

            var gotoAttributes = this.GetType().GetCustomAttributes(typeof(OnEventGotoState), false)
                                 as OnEventGotoState[];
            var pushAttributes = this.GetType().GetCustomAttributes(typeof(OnEventPushState), false)
                                 as OnEventPushState[];
            var doAttributes = this.GetType().GetCustomAttributes(typeof(OnEventDoAction), false)
                               as OnEventDoAction[];

            foreach (var attr in gotoAttributes)
            {
                if (attr.Action == null)
                {
                    this.GotoTransitions.Add(attr.Event, attr.State);
                }
                else
                {
                    var method = this.Machine.GetType().GetMethod(attr.Action,
                                                                  BindingFlags.NonPublic | BindingFlags.Instance);
                    var action = (Action)Delegate.CreateDelegate(typeof(Action), this.Machine, method);
                    this.GotoTransitions.Add(attr.Event, attr.State, action);
                }
            }

            foreach (var attr in pushAttributes)
            {
                this.PushTransitions.Add(attr.Event, attr.State);
            }

            foreach (var attr in doAttributes)
            {
                var method = this.Machine.GetType().GetMethod(attr.Action,
                                                              BindingFlags.NonPublic | BindingFlags.Instance);
                var action = (Action)Delegate.CreateDelegate(typeof(Action), this.Machine, method);
                this.ActionBindings.Add(attr.Event, action);
            }

            var ignoreEventsAttribute = this.GetType().GetCustomAttribute(typeof(IgnoreEvents), false) as IgnoreEvents;
            var deferEventsAttribute  = this.GetType().GetCustomAttribute(typeof(DeferEvents), false) as DeferEvents;

            if (ignoreEventsAttribute != null)
            {
                this.IgnoredEvents.UnionWith(ignoreEventsAttribute.Events);
            }

            if (deferEventsAttribute != null)
            {
                this.DeferredEvents.UnionWith(deferEventsAttribute.Events);
            }
        }
示例#20
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();
        }