singrdk/base/Services/NetStack/Runtime/DeMux.cs

92 lines
2.8 KiB
C#

// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
using NetStack.Common;
using Microsoft.Contracts;
using Microsoft.Singularity;
using System;
using System.Collections;
using System.Diagnostics;
using System.Net.IP;
using Drivers.Net;
using NetStack.NetDrivers;
using NetStack.Protocols;
namespace NetStack.Runtime
{
// Helper class to help feed packets from adapter into DeMultiplexer
public class DemuxAdapterArgs : Dispatcher.CallbackArgs
{
private IAdapter! adapter;
public DemuxAdapterArgs(IAdapter! adapter)
{
this.adapter = adapter;
base();
}
public IAdapter! Adapter { get { return adapter; } }
}
// This class provides the basic demultiplexing of packets as
// they come in from a network device. This component of the
// system is critical for several reasons. First, it is the place
// where backpressure is applied; this should be the only place
// in the system where packets are thrown away because of overload
// Second, it is the place where "flows" in the system are separated
// and where their resource controls are applied; subsequent
// processing can be done entirely with the resources (including
// potentially CPU resources) belonging to the "flow".
public class DeMultiplexer
{
// Private data
private Queue! rxQueue;
private Queue! tmpQueue;
[NotDelayed]
public DeMultiplexer()
{
this.rxQueue = new Queue();
this.tmpQueue = new Queue();
base();
}
// Add a new packet to the free list
public void TakeFreePacket(NetPacket! pkt)
{
IAdapter! adapter = (IAdapter!)pkt.AdapterContext;
pkt.Reset();
adapter.PopulateRxRing(pkt);
}
public bool PacketsReady { get { return rxQueue.Count > 0; } }
public NetPacket! GetReceivedPacket()
{
NetPacket! pkt = (NetPacket!)this.rxQueue.Dequeue();
DebugStub.Assert(pkt.AdapterContext != null);
return pkt;
}
public NetStatus OnAdapterReceive(Dispatcher.CallbackArgs ca)
{
DemuxAdapterArgs daa = (DemuxAdapterArgs!)ca;
IAdapter adapter = daa.Adapter;
adapter.GetReceivedPackets(this.tmpQueue);
while (tmpQueue.Count > 0) {
NetPacket! np = (NetPacket!)this.tmpQueue.Dequeue();
np.AdapterContext = adapter;
rxQueue.Enqueue(np);
}
Core.Instance().SignalInboundPackets();
return NetStatus.Code.RT_OK;
}
} // DeMultiplexer
} // NetStack
// End