Esempio n. 1
0
        /// <summary>
        /// Runs a new asynchronous machine event handler.
        /// </summary>
        /// <param name="machine">Machine that executes this event handler.</param>
        /// <param name="initialEvent">Event for initializing the machine.</param>
        /// <param name="isFresh">If true, then this is a new machine.</param>
        private async Task RunMachineEventHandlerAsync(Machine machine, Event initialEvent, bool isFresh)
        {
            bool completed;

            try
            {
                if (isFresh)
                {
                    await machine.GotoStartState(initialEvent);
                }

                completed = await machine.RunEventHandler(true);
            }
            catch (AssertionFailureException)
            {
                base.IsRunning = false;
                return;
            }
            catch (Exception ex)
            {
                base.IsRunning = false;
                base.RaiseOnFailureEvent(ex);
                return;
            }

            if (!completed)
            {
                RunMachineEventHandler(machine, null, false);
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Sends an asynchronous event to a machine.
        /// </summary>
        /// <param name="sender">Sender machine</param>
        /// <param name="mid">MachineId</param>
        /// <param name="e">Event</param>
        /// <param name="isStarter">Is starting a new operation</param>
        internal virtual void Send(AbstractMachine sender, MachineId mid, Event e, bool isStarter)
        {
            EventOriginInfo originInfo = null;

            if (sender != null && sender is Machine)
            {
                originInfo = new EventOriginInfo(sender.Id,
                                                 (sender as Machine).GetType().Name,
                                                 Machine.GetQualifiedStateName((sender as Machine).CurrentState));
            }

            EventInfo eventInfo = new EventInfo(e, originInfo);

            Machine machine = null;

            if (!this.MachineMap.TryGetValue(mid.Value, out machine))
            {
                return;
            }

            bool runHandler = false;

            machine.Enqueue(eventInfo, ref runHandler);

            if (!runHandler)
            {
                return;
            }

            Task task = new Task(() =>
            {
                try
                {
                    machine.RunEventHandler();
                }
                catch (Exception)
                {
                    if (this.Configuration.ThrowInternalExceptions)
                    {
                        throw;
                    }
                }
                finally
                {
                    this.TaskMap.TryRemove(Task.CurrentId.Value, out machine);
                }
            });

            this.MachineTasks.Add(task);
            this.TaskMap.TryAdd(task.Id, machine);

            task.Start();
        }
Esempio n. 3
0
        /// <summary>
        /// Tries to create a new machine of the specified type.
        /// </summary>
        /// <param name="creator">Creator machine</param>
        /// <param name="type">Type of the machine</param>
        /// <param name="friendlyName">Friendly machine name used for logging</param>
        /// <param name="e">Event</param>
        /// <returns>MachineId</returns>
        internal virtual MachineId TryCreateMachine(Machine creator, Type type,
                                                    string friendlyName, Event e)
        {
            this.Assert(type.IsSubclassOf(typeof(Machine)),
                        $"Type '{type.Name}' is not a machine.");

            MachineId mid = new MachineId(type, friendlyName, this);

            if (!MachineConstructorMap.ContainsKey(type))
            {
                Func <Machine> constructor = Expression.Lambda <Func <Machine> >(
                    Expression.New(type.GetConstructor(Type.EmptyTypes))).Compile();
                MachineConstructorMap[type] = constructor;
            }

            Machine machine = MachineConstructorMap[type]();

            machine.SetMachineId(mid);
            machine.InitializeStateInformation();

            bool result = this.MachineMap.TryAdd(mid.Value, machine);

            this.Assert(result, $"Machine '{mid}' was already created.");

            Task task = new Task(() =>
            {
                try
                {
                    machine.GotoStartState(e);
                    machine.RunEventHandler();
                }
                catch (Exception)
                {
                    if (this.Configuration.ThrowInternalExceptions)
                    {
                        throw;
                    }
                }
                finally
                {
                    this.TaskMap.TryRemove(Task.CurrentId.Value, out machine);
                }
            });

            this.MachineTasks.Add(task);
            this.TaskMap.TryAdd(task.Id, machine);

            task.Start();

            return(mid);
        }
Esempio n. 4
0
        /// <summary>
        /// Runs a new asynchronous machine event handler.
        /// </summary>
        /// <param name="machine">Machine that executes this event handler.</param>
        /// <param name="initialEvent">Event for initializing the machine.</param>
        /// <param name="isFresh">If true, then this is a new machine.</param>
        private async Task RunMachineEventHandlerAsync(Machine machine, Event initialEvent, bool isFresh)
        {
            try
            {
                if (isFresh)
                {
                    await machine.GotoStartState(initialEvent);
                }

                await machine.RunEventHandler();
            }
            catch (Exception ex)
            {
                base.IsRunning = false;
                base.RaiseOnFailureEvent(ex);
                return;
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Tries to create a new machine of the given type with an optional payload.
        /// </summary>
        /// <param name="type">Type of the machine</param>
        /// <param name="payload">Optional payload</param>
        /// <returns>Machine id</returns>
        internal static MachineId TryCreateMachine(Type type, params Object[] payload)
        {
            if (type.IsSubclassOf(typeof(Machine)))
            {
                Machine machine = Activator.CreateInstance(type) as Machine;

                MachineId mid = machine.Id;
                mid.IpAddress = PSharpRuntime.IpAddress;
                mid.Port      = PSharpRuntime.Port;

                if (!PSharpRuntime.MachineMap.TryAdd(mid.Value, machine))
                {
                    ErrorReporter.ReportAndExit("Machine {0}({1}) was already created.",
                                                type.Name, mid.Value);
                }

                Task task = new Task(() =>
                {
                    PSharpRuntime.TaskMap.TryAdd(Task.CurrentId.Value, machine);

                    try
                    {
                        machine.AssignInitialPayload(payload);
                        machine.GotoStartState();
                        machine.RunEventHandler();
                    }
                    finally
                    {
                        PSharpRuntime.TaskMap.TryRemove(Task.CurrentId.Value, out machine);
                    }
                });

                task.Start();

                return(mid);
            }
            else
            {
                ErrorReporter.ReportAndExit("Type '{0}' is not a machine.", type.Name);
                return(null);
            }
        }
Esempio n. 6
0
        /// <summary>
        /// Runs a new asynchronous machine event handler.
        /// This is a fire and forget invocation.
        /// </summary>
        /// <param name="machine">Machine</param>
        /// <param name="e">Event</param>
        /// <param name="isFresh">Is a new machine</param>
        private void RunMachineEventHandler(Machine machine, Event e, bool isFresh)
        {
            Task.Run(async() =>
            {
                try
                {
                    if (isFresh)
                    {
                        await machine.GotoStartState(e);
                    }

                    await machine.RunEventHandler();
                }
                catch (Exception ex)
                {
                    base.IsRunning = false;
                    base.RaiseOnFailureEvent(ex);
                }
            });
        }
Esempio n. 7
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.");
            }

            Machine machine = PSharpRuntime.MachineMap[mid.Value];

            bool runHandler = false;

            machine.Enqueue(e, ref runHandler);

            if (!runHandler)
            {
                return;
            }

            Task task = new Task(() =>
            {
                PSharpRuntime.TaskMap.TryAdd(Task.CurrentId.Value, machine as Machine);

                try
                {
                    machine.RunEventHandler();
                }
                finally
                {
                    PSharpRuntime.TaskMap.TryRemove(Task.CurrentId.Value, out machine);
                }
            });

            task.Start();
        }
Esempio n. 8
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();
        }