// Decompiled with JetBrains decompiler // Type: Microsoft.Iris.Queues.Dispatcher // Assembly: UIX, Version=4.8.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217 // MVID: A56C6C9D-B7F6-46A9-8BDE-B3D9B8D60B11 // Assembly location: C:\Program Files\Zune\UIX.dll using Microsoft.Iris.Debug; using System; using System.IO; using System.IO.Pipes; using System.Threading; namespace Microsoft.Iris.Queues { public abstract class Dispatcher { private static Interconnect s_interconnect = new Interconnect(); [ThreadStatic] private static Dispatcher s_threadDispatcher; private static NamedPipeClientStream _debugPipe; private static BinaryWriter _debugPipeWriter; private static BinaryReader _debugPipeReader; private Thread _owningThread; private uint _enterCount; private Feeder _feeder; private int _feederReadStamp; private int _feederWriteStamp; public Dispatcher() { _owningThread = Thread.CurrentThread; _feeder = EnterDispatch(); } public void FinalStopDispatch() { LeaveDispatch(); _feeder = null; } public void Dispose() { if (_enterCount != 1U) return; LeaveDispatch(); } public static Dispatcher CurrentDispatcher => s_threadDispatcher; public static void PostItem_AnyThread(Thread thread, QueueItem item, int priority) { if (thread == null || thread == Thread.CurrentThread) { Dispatcher currentDispatcher = CurrentDispatcher; if (currentDispatcher != null) { currentDispatcher.PostItem_SameThread(item, priority); return; } } s_interconnect.PostItem(thread, item, priority); } public Thread DispatchThread => _owningThread; public void MainLoop(Queue queue) { EnterDispatch(); try { while (true) { QueueItem nextItem = queue.GetNextItem(); if (nextItem != null) { Application.Debugger?.LogDispatcher(nextItem.ToDebugPacketString()); nextItem.Dispatch(); } else break; } } finally { LeaveDispatch(); } } protected abstract void PostItem_SameThread(QueueItem item, int priority); protected abstract void PostItems_SameThread(QueueItem.FIFO items, int priority); protected abstract void WakeDispatchThread(); private Feeder EnterDispatch() { bool isRoot = _enterCount == 0U; ++_enterCount; if (isRoot) s_threadDispatcher = this; return s_interconnect.EnterDispatch(this, isRoot); } private void LeaveDispatch() { --_enterCount; bool isRoot = _enterCount == 0U; if (isRoot) s_threadDispatcher = null; s_interconnect.LeaveDispatch(this, isRoot); } public void NotifyFeederItems() { if (Thread.CurrentThread == _owningThread) return; Interlocked.Increment(ref _feederWriteStamp); WakeDispatchThread(); } internal bool DrainFeeder() { int feederWriteStamp = _feederWriteStamp; if (feederWriteStamp == _feederReadStamp) return false; bool flag = false; _feederReadStamp = feederWriteStamp; QueueItem.FIFO[] recycled = _feeder.HandoffFIFOs(); if (recycled != null) { for (int priority = 0; priority < recycled.Length; ++priority) { QueueItem.FIFO items = recycled[priority]; if (items != null) { PostItems_SameThread(items, priority); flag = true; } } _feeder.RecycleFIFOs(recycled); } return flag; } } }