Files
MicrosoftIris/UIX/Microsoft/Iris/Queues/Dispatcher.cs
T

146 lines
4.3 KiB
C#
Raw Normal View History

2022-03-03 08:14:05 -06:00
// 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
2022-06-07 01:00:15 -05:00
using Microsoft.Iris.Debug;
2022-03-03 08:14:05 -06:00
using System;
using System.IO;
using System.IO.Pipes;
using System.Threading;
namespace Microsoft.Iris.Queues
{
2022-10-07 10:29:09 -05:00
public abstract class Dispatcher
2022-03-03 08:14:05 -06:00
{
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)
{
2023-05-22 21:44:05 -05:00
Application.Debugger.LogDispatcher(nextItem.ToDebugPacketString());
2022-03-03 08:14:05 -06:00
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;
}
}
}