示例#1
0
 /// <summary>
 /// Create a message fiber instance
 /// </summary>
 public MessageFiberBase()
 {
     RunInternalWaitCallback = RunInternal;
     m_SyncContext           = new FiberSyncContext(this);
     tail = lastTale = new MessageNodeBase()
     {
         Next = Blocked
     };
 }
示例#2
0
        internal void EnqueueInternal(MessageNodeBase newTail)
        {
            var oldTail = Atomic.Swap(ref tail, newTail);

            //if oldtail is null or tailing is failed
            if (!TryTail(oldTail, newTail))
            {
                //statis is a single object in heap, no further allocation with object[]
                ThreadPool.QueueUserWorkItem(RunInternalWaitCallback, newTail);
            }
        }
示例#3
0
        void RunInternal(object obj)
        {
            var messageNode = (MessageNodeBase)obj;

            //because it's thread specific value, we dont need to set
            //null everytime.
            CurrentIFiber = this;

            var cachedContext = SynchronizationContext.Current;

            SynchronizationContext.SetSynchronizationContext(m_SyncContext);

            do
            {
                //restore blocked, let it can be recycle
                lastTale.PushToPool();
                //remember last tale to be continued
                lastTale = messageNode;

                try
                {
                    InvokeMessage(messageNode);
                }
                catch (Exception e)
                {
                    HandleException(e);
                }

                //if next is null, then it successfully replace it's Next to Blocked
                //otherwise messagenode is what recently trytail'ed
                messageNode = GetNext(messageNode);
            }while (messageNode != null);

            SynchronizationContext.SetSynchronizationContext(cachedContext);
            //now we're done is this thread pool thread,
            CurrentIFiber = null;
        }
示例#4
0
 internal override void InvokeMessage(MessageNodeBase message)
 {
     message.Invoke();
 }
示例#5
0
 internal abstract void InvokeMessage(MessageNodeBase message);
示例#6
0
 //get next node and mark it as blocked
 //if it's not null, we dont need to execute exchange function
 static MessageNodeBase GetNext(MessageNodeBase prev)
 {
     return(Atomic.Swap(ref prev.Next, Blocked));
 }
示例#7
0
 //if next is already blocked, then previous actions are already executed.
 static bool TryTail(MessageNodeBase prev, MessageNodeBase next)
 {
     return(Atomic.SwapIfSame(ref prev.Next, next, null));
 }