예제 #1
0
        public void Execute(Action <IActorRuntime, ITestingRuntime> action, IScheduler scheduler)
        {
            runtime = new TestingActorRuntime(scheduler);

            // TODO: Remove this somehow.
            TaskHelper.runtime = runtime;

            var task = new Task(() =>
            {
                TestingActorRuntime.ActorBody <object>(
                    () =>
                {
                    action(runtime, runtime);
                    return(null);
                },
                    runtime,
                    true);
            },
                                CancellationToken.None,
                                TaskCreationOptions.RunContinuationsAsynchronously);

            runtime.RegisterMainTask(task);

            task.Start(taskScheduler);

            task.Wait();
            runtime.WaitForAllActorsToTerminate();
        }
예제 #2
0
 public ActorInfo(
     ActorId id,
     string name,
     Task task,
     CancellationTokenSource cts,
     TestingActorRuntime runtime)
 {
     this.id          = id;
     this.task        = task;
     this.name        = name;
     this.cts         = cts;
     Mailbox          = new Mailbox <object>(this, runtime);
     terminateWaiters = new HashSet <ActorInfo>();
     exceptions       = new List <Exception>();
 }
예제 #3
0
 public Mailbox(ActorInfo ownerActorInfo, TestingActorRuntime runtime)
 {
     this.ownerActorInfo = ownerActorInfo;
     this.runtime        = runtime;
     mailbox             = new List <T>();
 }
        public static T ActorBody <T>(
            Func <T> func,
            TestingActorRuntime runtime,
            bool mainThread,
            ActorInfo info = null)
        {
            if (info == null)
            {
                info = runtime.GetCurrentActorInfo();
            }
            lock (info.mutex)
            {
                Safety.Assert(info.active);
                info.currentOp = OpType.START;

                if (!mainThread)
                {
                    info.active = false;
                    Monitor.PulseAll(info.mutex);

                    while (!info.active)
                    {
                        Monitor.Wait(info.mutex);
                    }
                }
            }

            try
            {
                return(func());
            }
            catch (OperationCanceledException ex)
            {
                lock (info.mutex)
                {
                    if (info.cts.Token ==
                        ex.CancellationToken &&
                        info.cts.IsCancellationRequested)
                    {
                        info.cancelled = true;
                    }
                    info.exceptions.Add(ex);
                }
                throw;
            }
            catch (ActorTerminatedException ex)
            {
                if (mainThread && runtime.error == null)
                {
                    runtime.error = new Exception("Main actor did not terminate.", ex);
                }
            }
            catch (Exception ex)
            {
                runtime.error      = ex;
                runtime.terminated = true;
                runtime.ActivateAllActors();
            }
            finally
            {
                try
                {
                    if (!runtime.terminated)
                    {
                        runtime.Schedule(OpType.END, info);

                        lock (info.mutex)
                        {
                            info.enabled    = false;
                            info.terminated = true;
                            foreach (var waiter in info.terminateWaiters)
                            {
                                waiter.enabled = true;
                            }
                            info.terminateWaiters.Clear();
                        }

                        runtime.Schedule(OpType.END, info);
                    }
                }
                catch (ActorTerminatedException)
                {
                }
                finally
                {
                    lock (info.mutex)
                    {
                        info.terminated = true;
                    }
                }
            }
            return(default(T));
        }