aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
authorMelanie2012-08-28 22:17:17 +0200
committerMelanie2012-08-28 22:17:17 +0200
commit378a79e7cc6be3191dea41b617c05febd7ee5cbe (patch)
tree83db0a848126405f0e12d833c90022fa49bee85c /OpenSim/Region
parentFix a nullref while object is being created (diff)
downloadopensim-SC-378a79e7cc6be3191dea41b617c05febd7ee5cbe.zip
opensim-SC-378a79e7cc6be3191dea41b617c05febd7ee5cbe.tar.gz
opensim-SC-378a79e7cc6be3191dea41b617c05febd7ee5cbe.tar.bz2
opensim-SC-378a79e7cc6be3191dea41b617c05febd7ee5cbe.tar.xz
Add a queue with two priority levels. This is a drop in replacement for
the BlockingQueue from OMV, but allows two priorities.
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs113
1 files changed, 111 insertions, 2 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 7042c9a..f9ba14c 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -110,7 +110,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
110 /// <summary>Handlers for incoming packets</summary> 110 /// <summary>Handlers for incoming packets</summary>
111 //PacketEventDictionary packetEvents = new PacketEventDictionary(); 111 //PacketEventDictionary packetEvents = new PacketEventDictionary();
112 /// <summary>Incoming packets that are awaiting handling</summary> 112 /// <summary>Incoming packets that are awaiting handling</summary>
113 private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>(); 113 //private OpenMetaverse.BlockingQueue<IncomingPacket> packetInbox = new OpenMetaverse.BlockingQueue<IncomingPacket>();
114
115 private DoubleQueue<IncomingPacket> packetInbox = new DoubleQueue<IncomingPacket>();
116
114 /// <summary></summary> 117 /// <summary></summary>
115 //private UDPClientCollection m_clients = new UDPClientCollection(); 118 //private UDPClientCollection m_clients = new UDPClientCollection();
116 /// <summary>Bandwidth throttle for this UDP server</summary> 119 /// <summary>Bandwidth throttle for this UDP server</summary>
@@ -919,7 +922,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
919 #endregion Ping Check Handling 922 #endregion Ping Check Handling
920 923
921 // Inbox insertion 924 // Inbox insertion
922 packetInbox.Enqueue(new IncomingPacket((LLClientView)client, packet)); 925 if (packet.Type == PacketType.AgentUpdate ||
926 packet.Type == PacketType.ChatFromViewer)
927 packetInbox.EnqueueHigh(new IncomingPacket((LLClientView)client, packet));
928 else
929 packetInbox.EnqueueLow(new IncomingPacket((LLClientView)client, packet));
923 } 930 }
924 931
925 #region BinaryStats 932 #region BinaryStats
@@ -1519,4 +1526,106 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1519 } 1526 }
1520 } 1527 }
1521 } 1528 }
1529
1530 internal class DoubleQueue<T> where T:class
1531 {
1532 private Queue<T> m_lowQueue = new Queue<T>();
1533 private Queue<T> m_highQueue = new Queue<T>();
1534
1535 private object m_syncRoot = new object();
1536 private Semaphore m_s = new Semaphore(0, 1);
1537
1538 public DoubleQueue()
1539 {
1540 }
1541
1542 public virtual int Count
1543 {
1544 get { return m_highQueue.Count + m_lowQueue.Count; }
1545 }
1546
1547 public virtual void Enqueue(T data)
1548 {
1549 Enqueue(m_lowQueue, data);
1550 }
1551
1552 public virtual void EnqueueLow(T data)
1553 {
1554 Enqueue(m_lowQueue, data);
1555 }
1556
1557 public virtual void EnqueueHigh(T data)
1558 {
1559 Enqueue(m_highQueue, data);
1560 }
1561
1562 private void Enqueue(Queue<T> q, T data)
1563 {
1564 lock (m_syncRoot)
1565 {
1566 m_lowQueue.Enqueue(data);
1567 m_s.WaitOne(0);
1568 m_s.Release();
1569 }
1570 }
1571
1572 public virtual T Dequeue()
1573 {
1574 return Dequeue(Timeout.Infinite);
1575 }
1576
1577 public virtual T Dequeue(int tmo)
1578 {
1579 return Dequeue(TimeSpan.FromMilliseconds(tmo));
1580 }
1581
1582 public virtual T Dequeue(TimeSpan wait)
1583 {
1584 T res = null;
1585
1586 if (!Dequeue(wait, ref res))
1587 return null;
1588
1589 return res;
1590 }
1591
1592 public bool Dequeue(int timeout, ref T res)
1593 {
1594 return Dequeue(TimeSpan.FromMilliseconds(timeout), ref res);
1595 }
1596
1597 public bool Dequeue(TimeSpan wait, ref T res)
1598 {
1599 if (!m_s.WaitOne(wait))
1600 return false;
1601
1602 lock (m_syncRoot)
1603 {
1604 if (m_highQueue.Count > 0)
1605 res = m_highQueue.Dequeue();
1606 else
1607 res = m_lowQueue.Dequeue();
1608
1609 if (m_highQueue.Count == 0 || m_lowQueue.Count == 0)
1610 return true;
1611
1612 m_s.Release();
1613
1614 return true;
1615 }
1616 }
1617
1618 public virtual void Clear()
1619 {
1620
1621 lock (m_syncRoot)
1622 {
1623 // Make sure sem count is 0
1624 m_s.WaitOne(0);
1625
1626 m_lowQueue.Clear();
1627 m_highQueue.Clear();
1628 }
1629 }
1630 }
1522} 1631}