internal static void EnqueueInternal(MessageFiberBase fiber, Action continuation) { var newTail = NodePool <ActionMessageNode> .Pop(); newTail.Message = continuation; fiber.EnqueueInternal(newTail); }
/// <summary> /// Return AwaitableObject /// </summary> /// <param name="task">task</param> /// <param name="fiber">fiber to continue</param> /// <returns></returns> public static FiberAwaiter ContinueIn(this Task task, MessageFiberBase fiber) { if (fiber == null) { throw new Exception("target fiber is empty"); } return(new FiberAwaiter(task, fiber)); }
public void OnCompleted(Action continuation) { if (m_Fiber.IsCurrentThread) { continuation(); } else { MessageFiberBase.EnqueueInternal(m_Fiber, continuation); } }
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; }
public FiberAwaiter(Task <TResult> task, MessageFiberBase fiber) { m_Task = task; m_Task.ConfigureAwait(false); m_Fiber = fiber; }
public void UnsafeOnCompleted(Action continuation) { MessageFiberBase.EnqueueInternal(m_Fiber, continuation); }
public EnsureInFiber(MessageFiberBase fiber) { m_Fiber = fiber; }
public static IAwaiter GetAwaiter(this MessageFiberBase fiber) => new EnsureInFiber(fiber);
public FiberSyncContext(MessageFiberBase fiber) { m_Fiber = fiber; }