private void ReleaseForDisposedFiberInternal(IFiber fiber)
 {
     if ((_executingEntityFiberManager != null && _executingEntityFiberManager != this) || !Monitor.TryEnter(_executionLock, 1))
     {
         _applicationFiber.Enqueue(() => ReleaseForDisposedFiberInternal(fiber));
         return;
     }
     try
     {
         //lock (_enqueueLock)
         //{
         if (_currentFiber != fiber)
         {
             return;
         }
         _currentFiber = null;
         Thread.MemoryBarrier();         // do not reorder!
         if (_actions != null)
         {
             _applicationFiber.Enqueue(() => Execute(null));
         }
         //}
     }
     finally
     {
         Monitor.Exit(_executionLock);
     }
 }
예제 #2
0
 public void Enter(ActorPeer peer)
 {
     _executionFiber.Enqueue(() =>
     {
         ListPeer.Add(peer);
         SpawnPlayer(peer);
     });
 }
예제 #3
0
 public void PeerJoined(StarCollectorDemoPeer peer)
 {
     // schedule peer to be added to PeerList on the main thread
     executionFiber.Enqueue(() =>
     {
         PeerList.Add(peer);
     });
 }
예제 #4
0
            public void Signal()
            {
                if (Interlocked.CompareExchange(ref _flushPending, 1, 0) == 1)
                {
                    return;
                }

                _target.Enqueue(_cache);
            }
예제 #5
0
            public void Signal()
            {
                lock (this)
                {
                    if (_flushPending)
                    {
                        return;
                    }

                    _flushPending = true;
                    _target.Enqueue(_cache);
                }
            }
예제 #6
0
        protected override object Invoke(MethodInfo targetMethod, object[] args)
        {
            if (targetMethod == null)
            {
                throw new ArgumentException(nameof(targetMethod));
            }

            string targetMethodName = targetMethod.Name;

            if (targetMethodName == "Dispose")
            {
                Dispose();
                return(targetMethod.Invoke(_decorated, args));
            }

            //Handle event attach.detach
            if (targetMethod.ReturnType != typeof(void) ||
                targetMethodName.StartsWith("add_", StringComparison.Ordinal) ||
                targetMethodName.StartsWith("remove_", StringComparison.Ordinal))
            {
                return(targetMethod.Invoke(_decorated, args));
            }

            _fiber.Enqueue(() => targetMethod.Invoke(_decorated, args));
            return(null);
        }
예제 #7
0
 private void Run()
 {
     while (_running)
     {
         try
         {
             NetMQMessage msg = _replySocket.ReceiveMessage();
             if (msg.IsEmpty)
             {
                 continue;
             }
             if (msg.FrameCount != 3)
             {
                 throw new Exception("Msg error");
             }
             var guid = new Guid(msg[1].Buffer);
             if (!_requests.ContainsKey(guid))
             {
                 throw new Exception("We don't have a msg SenderId for this reply");
             }
             TReply reply = _replyUnmarshaller(msg[2].Buffer);
             _fiber.Enqueue(() => Send(guid, reply));
         }
         catch (Exception e)
         {
             _running = false;
         }
     }
     InternalDispose();
 }
예제 #8
0
        public static void InOrderExecution(IFiber fiber)
        {
            using (fiber)
                using (var reset = new AutoResetEvent(false))
                {
                    int count  = 0;
                    var result = new List <int>();

                    void Command()
                    {
                        result.Add(count++);
                        if (count == 100)
                        {
                            reset.Set();
                        }
                    }

                    for (int i = 0; i < 100; i++)
                    {
                        fiber.Enqueue(Command);
                    }
                    Assert.IsTrue(reset.WaitOne(10000, false));
                    Assert.AreEqual(100, count);
                }
        }
예제 #9
0
 public void Run(IFiber fiber)
 {
     i = 0;
     for (int j = 0; j < 1000000; j++)
     {
         fiber.Enqueue(Handler);
     }
     WaitHandle.WaitAny(new WaitHandle[] { _wait });
 }
예제 #10
0
 public IDisposable Schedule(IFiber fiber, Action action, TimeSpan dueTime)
 {
     if (dueTime.TotalMilliseconds <= 0)
     {
         var pending = new PendingAction(action);
         fiber.Enqueue(pending.Execute);
         return(pending);
     }
     return(new TimerAction(fiber, action, dueTime));
 }
예제 #11
0
 private void ExecuteOnTimerThread(IFiber fiber)
 {
     if (_interval.Ticks == TimeSpan.FromMilliseconds(-1).Ticks || _cancelled)
     {
         fiber.Remove(this);
         DisposeTimer();
     }
     if (!_cancelled)
         fiber.Enqueue(Execute);
 }
예제 #12
0
 public void Publish(TSnapshot msg)
 {
     if (_disposed)
     {
         return;
     }
     _fiber.Enqueue(() => _receiveSnapshot(msg));
     //publishing the snapshot subscribes the updates...
     _sub = _updatesPort.Subscribe(_fiber, _receive);
 }
예제 #13
0
 public IDisposable Schedule(IFiber fiber, Action action, TimeSpan dueTime)
 {
     if (dueTime.TotalMilliseconds <= 0)
     {
         var pending = new PendingAction(action);
         fiber.Enqueue(pending.Execute);
         return pending;
     }
     return new TimerAction(fiber, action, dueTime);
 }
예제 #14
0
 public static void ExecuteOnlyAfterStart(IFiber fiber)
 {
     using (fiber)
     using (var reset = new AutoResetEvent(false))
     {
         fiber.Enqueue(() => reset.Set());
         Assert.IsFalse(reset.WaitOne(1, false));
         fiber.Start();
         Assert.IsTrue(reset.WaitOne(1000, false));
     }
 }
예제 #15
0
        public IDisposable Subscribe(IFiber fiber, Action <T> receive)
        {
            void Receive(T msg)
            {
                fiber.Enqueue(() => receive(msg));
            }

            IDisposable disposable = _internalEvent.Subscribe(Receive);

            return(new Unsubscriber(disposable, fiber));
        }
예제 #16
0
        public IDisposable Subscribe(IFiber fiber, Action receive)
        {
            void Action()
            {
                fiber.Enqueue(receive);
            }

            IDisposable disposable = _internalEvent.Subscribe(Action);

            return(new Unsubscriber(disposable, fiber));
        }
예제 #17
0
 public static void ExecuteOnlyAfterStart(IFiber fiber)
 {
     using (fiber)
         using (var reset = new AutoResetEvent(false))
         {
             fiber.Enqueue(() => reset.Set());
             Assert.IsFalse(reset.WaitOne(1, false));
             fiber.Start();
             Assert.IsTrue(reset.WaitOne(1000, false));
         }
 }
예제 #18
0
 protected void Cleanup()
 {
     ClientFiber.Enqueue(() =>
     {
         Send.Dispose();
         Context1.Dispose();
         Subscriber.Dispose();
         Context2.Dispose();
     });
     Thread.Sleep(100);
     ClientFiber.Dispose();
 }
예제 #19
0
 private void ExecuteOnTimerThread(IFiber fiber)
 {
     if (_interval.Ticks == TimeSpan.FromMilliseconds(-1).Ticks || _cancelled)
     {
         fiber.Remove(this);
         DisposeTimer();
     }
     if (!_cancelled)
     {
         fiber.Enqueue(Execute);
     }
 }
예제 #20
0
 public IDisposable Subscribe(IFiber fiber, Action <T> handler)
 {
     lock (_lock)
     {
         IDisposable disposable = _updateChannel.Subscribe(fiber, handler);
         if (_hasValue)
         {
             T item = _last;
             fiber.Enqueue(() => handler(item));
         }
         return(disposable);
     }
 }
예제 #21
0
 public IDisposable Subscribe(IFiber fiber, Action <T> handler)
 {
     lock (_lock)
     {
         IDisposable disposable = _updateChannel.Subscribe(fiber, handler);
         int         length     = _list.Count;
         for (int index = 0; index < length; index++)
         {
             T item = _list[index];
             fiber.Enqueue(() => handler(item));
         }
         return(disposable);
     }
 }
예제 #22
0
        public void PeerJoined(StarCollectorDemoPeer peer)
        {
            // schedule peer to be added to PeerList on the main thread
            executionFiber.Enqueue(() =>
            {
                PeerList.Add(peer);

                // send player CreateActor events for all players and stars

                foreach (Player p in Players)
                {
                    EventData evt     = new EventData((byte)StarCollectorEventTypes.CreateActor);
                    evt.Parameters    = new Dictionary <byte, object>();
                    evt.Parameters[0] = p.ActorType;
                    evt.Parameters[1] = p.ActorID;
                    evt.Parameters[2] = p.PosX;
                    evt.Parameters[3] = p.PosY;
                    evt.Parameters[4] = (p.Owner as StarCollectorDemoPeer).PlayerID;

                    peer.SendEvent(evt, new SendParameters());
                }

                foreach (Star s in Stars)
                {
                    EventData evt     = new EventData((byte)StarCollectorEventTypes.CreateActor);
                    evt.Parameters    = new Dictionary <byte, object>();
                    evt.Parameters[0] = s.ActorType;
                    evt.Parameters[1] = s.ActorID;
                    evt.Parameters[2] = s.PosX;
                    evt.Parameters[3] = s.PosY;

                    peer.SendEvent(evt, new SendParameters());
                }

                SpawnPlayer(peer);
            });
        }
예제 #23
0
 protected void Cleanup()
 {
     ClientFiber.Enqueue(() =>
     {
         Console.WriteLine("Dispose push");
         Push.Dispose();
         Context2.Dispose();
         Thread.Sleep(10);
         Console.WriteLine("Dispose pull");
         Pull.Dispose();
         Context1.Dispose();
         Thread.Sleep(10);
     });
     Thread.Sleep(200);
     ClientFiber.Dispose();
 }
예제 #24
0
        /// <summary>
        /// Subscribe with a message predicate to filter messages
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="port"></param>
        /// <param name="fiber"></param>
        /// <param name="receive"></param>
        /// <param name="filter"></param>
        /// <returns></returns>
        public static IDisposable Subscribe <T>(this ISubscriberPort <T> port,
                                                IFiber fiber,
                                                Action <T> receive,
                                                Predicate <T> filter)
        {
            Action <T> filteredReceiver = x =>
            {
                if (filter(x))
                {
                    fiber.Enqueue(() => receive(x));
                }
            };

            //we use a stub fiber to force the filtering onto the publisher thread.
            return(port.Subscribe(StubFiber.StartNew(), filteredReceiver));
        }
예제 #25
0
 protected void Cleanup()
 {
     ClientFiber.Enqueue(() =>
     {
         Client.Dispose();
         ClientContext.Dispose();
         Thread.Sleep(10);
         Service.Dispose();
         ServerContext.Dispose();
     });
     Thread.Sleep(100);
     Console.WriteLine("Dispose client fiber");
     ClientFiber.Dispose();
     Console.WriteLine("Dispose service");
     ServerFiber.Dispose();
 }
예제 #26
0
        /// <summary>
        ///     Subscribe with a message predicate to filter messages
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="port"></param>
        /// <param name="fiber"></param>
        /// <param name="receive"></param>
        /// <param name="filter"></param>
        /// <returns></returns>
        public static IDisposable Subscribe <T>(this IFiber fiber,
                                                ISubscriberPort <T> port,
                                                Action <T> receive,
                                                Predicate <T> filter)
        {
            void FilteredReceiver(T x)
            {
                if (filter(x))
                {
                    fiber.Enqueue(() => receive(x));
                }
            }

            IDisposable sub = port.Subscribe(FilteredReceiver);

            return(new Unsubscriber(sub, fiber));
        }
예제 #27
0
        /// <summary>
        ///     Subscribe a fiber to an Action based event.
        /// </summary>
        /// <param name="fiber"></param>
        /// <param name="obj"></param>
        /// <param name="eventName"></param>
        /// <param name="receive"></param>
        /// <returns></returns>
        public static IDisposable SubscribeToEvent(this IFiber fiber, object obj, string eventName,
                                                   Action receive)
        {
            EventInfo  evt    = obj.GetType().GetEvent(eventName);
            MethodInfo add    = evt.GetAddMethod();
            MethodInfo remove = evt.GetRemoveMethod();

            void Action()
            {
                fiber.Enqueue(receive);
            }

            object[] addHandlerArgs = { (Action)Action };
            add.Invoke(obj, addHandlerArgs);

            return(new Unsubscriber(new DisposeAction(() => remove.Invoke(obj, addHandlerArgs)), fiber));
        }
예제 #28
0
        /// <summary>
        /// Subscribe with a message predicate to filter messages
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="port"></param>
        /// <param name="fiber"></param>
        /// <param name="receive"></param>
        /// <param name="filter"></param>
        /// <returns></returns>
        public static IDisposable Subscribe <T>(this IFiber fiber,
                                                ISubscriberPort <T> port,
                                                Action <T> receive,
                                                Predicate <T> filter)
        {
            void FilteredReceiver(T x)
            {
                if (filter(x))
                {
                    fiber.Enqueue(() => receive(x));
                }
            }

            //we use a stub fiber to force the filtering onto the publisher thread.
            var stub = StubFiber.StartNew();

            port.Subscribe(stub, FilteredReceiver);
            return(stub);
        }
예제 #29
0
 public static void InOrderExecution(IFiber fiber)
 {
     using (fiber)
     using (var reset = new AutoResetEvent(false))
     {
         int count = 0;
         var result = new List<int>();
         Action command = () =>
         {
             result.Add(count++);
             if (count == 100)
                 reset.Set();
         };
         for (int i = 0; i < 100; i++)
             fiber.Enqueue(command);
         Assert.IsTrue(reset.WaitOne(10000, false));
         Assert.AreEqual(100, count);
     }
 }
예제 #30
0
        //0 allocations when caching the handler to Action
        public void Run2(IFiber fiber)
        {
            using AutoResetEvent wait = new AutoResetEvent(false);
            using (fiber)
            {
                int    i       = 0;
                Action handler = () =>
                {
                    i++;
                    if (i == OperationsPerInvoke)
                    {
                        wait.Set();
                    }
                };
                for (int j = 0; j < OperationsPerInvoke; j++)
                {
                    fiber.Enqueue(handler);
                }

                WaitHandle.WaitAny(new WaitHandle[] { wait });
            }
        }
예제 #31
0
 /// <summary>
 /// Receives the action and queues the execution on the target fiber.
 /// </summary>
 /// <param name="msg"></param>
 protected override void OnMessageOnProducerThread(T msg)
 {
     _fiber.Enqueue(() => _receiver(msg));
 }
예제 #32
0
        public void GetAccount(string applicationId, IFiber fiber, Action <ApplicationAccount> callback)
        {
            if (callback == null)
            {
                throw new ArgumentNullException("callback");
            }

            if (fiber == null)
            {
                throw new ArgumentNullException("fiber");
            }

            var tmp = callback;

            callback = account => fiber.Enqueue(() => tmp(account));

            if (applicationId == null)
            {
                if (log.IsDebugEnabled)
                {
                    log.Debug("Failed to authenticate. Application id is null.");
                }

                callback(new ApplicationAccount(string.Empty, AccountServiceResult.Error, false, ErrorMessages.AppIdMissing));
                return;
            }

            applicationId = applicationId.Trim();
            if (string.IsNullOrEmpty(applicationId))
            {
                if (log.IsDebugEnabled)
                {
                    log.Debug("Failed to authenticate. app id is Empty");
                }

                callback(new ApplicationAccount(string.Empty, AccountServiceResult.Error, false, ErrorMessages.EmptyAppId));
                return;
            }

            string appId;

            if (!this.accountService.FormatApplicationId(applicationId, out appId))
            {
                if (log.IsDebugEnabled)
                {
                    log.DebugFormat("Failed to authenticate. Invalid application id format: {0}", applicationId);
                }

                callback(new ApplicationAccount(string.Empty, AccountServiceResult.Error, false, ErrorMessages.InvalidAppIdFormat));
                return;
            }

            CachedResult result;

            using (Lock.TryEnter(this.dictionary, 10000))
            {
                if (!this.dictionary.TryGetValue(appId, out result))
                {
                    log.DebugFormat("Create cached auth result for app: {0}", appId);
                    result = new CachedResult(this, appId, this.refreshInterval);
                    this.dictionary.Add(appId, result);
                }
            }

            result.GetResult(callback);
        }
예제 #33
0
 public void BusyWait()
 {
     _busyWait.Enqueue(_lambda);
 }
예제 #34
0
 public void Sleep()
 {
     _sleep.Enqueue(_lambda);
 }