Beispiel #1
0
        public void Send(T msg)
        {
            runtime.Schedule(OpType.SEND);
            LogSend(msg);
            mailbox.Add(msg);

            if (waiter != null)
            {
                Safety.Assert(!waiter.enabled);
                waiter.enabled = true;
                waiter         = null;
            }
        }
        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));
        }