diff --git a/Lidgren.Network/NetPeer.Fragmentation.cs b/Lidgren.Network/NetPeer.Fragmentation.cs index 5b8cd01..8c1ea93 100644 --- a/Lidgren.Network/NetPeer.Fragmentation.cs +++ b/Lidgren.Network/NetPeer.Fragmentation.cs @@ -73,6 +73,8 @@ namespace Lidgren.Network private void HandleReleasedFragment(NetIncomingMessage im) { + VerifyNetworkThread(); + // // read fragmentation header and combine fragments // diff --git a/Lidgren.Network/NetQueue.cs b/Lidgren.Network/NetQueue.cs index 524a35c..9f19e45 100644 --- a/Lidgren.Network/NetQueue.cs +++ b/Lidgren.Network/NetQueue.cs @@ -20,8 +20,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. using System; using System.Diagnostics; using System.Collections.Generic; - -// @TODO: examine performance characteristics of using SpinLock when using .Net 4.0 +using System.Threading; namespace Lidgren.Network { @@ -46,7 +45,7 @@ namespace Lidgren.Network // [7] item // private T[] m_items; - private readonly object m_lock; + private readonly ReaderWriterLockSlim m_lock = new ReaderWriterLockSlim(); private int m_size; private int m_head; @@ -65,7 +64,6 @@ namespace Lidgren.Network /// public NetQueue(int initialCapacity) { - m_lock = new object(); m_items = new T[initialCapacity]; } @@ -74,7 +72,8 @@ namespace Lidgren.Network /// public void Enqueue(T item) { - lock (m_lock) + m_lock.EnterWriteLock(); + try { if (m_size == m_items.Length) SetCapacity(m_items.Length + 8); @@ -83,6 +82,10 @@ namespace Lidgren.Network m_items[slot] = item; m_size++; } + finally + { + m_lock.ExitWriteLock(); + } } /// @@ -90,7 +93,8 @@ namespace Lidgren.Network /// public void Enqueue(IEnumerable items) { - lock (m_lock) + m_lock.EnterWriteLock(); + try { foreach (var item in items) { @@ -102,6 +106,10 @@ namespace Lidgren.Network m_size++; } } + finally + { + m_lock.ExitWriteLock(); + } } /// @@ -109,7 +117,8 @@ namespace Lidgren.Network /// public void EnqueueFirst(T item) { - lock (m_lock) + m_lock.EnterWriteLock(); + try { if (m_size >= m_items.Length) SetCapacity(m_items.Length + 8); @@ -120,9 +129,13 @@ namespace Lidgren.Network m_items[m_head] = item; m_size++; } + finally + { + m_lock.ExitWriteLock(); + } } - // must be called from within a lock(m_lock) ! + // must be called from within a write locked m_lock! private void SetCapacity(int newCapacity) { if (m_size == 0) @@ -163,7 +176,8 @@ namespace Lidgren.Network return false; } - lock (m_lock) + m_lock.EnterWriteLock(); + try { if (m_size == 0) { @@ -179,6 +193,10 @@ namespace Lidgren.Network return true; } + finally + { + m_lock.ExitWriteLock(); + } } /// @@ -189,7 +207,8 @@ namespace Lidgren.Network if (m_size == 0) return 0; - lock (m_lock) + m_lock.EnterWriteLock(); + try { int added = m_size; while (m_size > 0) @@ -203,6 +222,10 @@ namespace Lidgren.Network } return added; } + finally + { + m_lock.ExitWriteLock(); + } } /// @@ -213,12 +236,17 @@ namespace Lidgren.Network if (m_size == 0) return default(T); - lock (m_lock) + m_lock.EnterReadLock(); + try { if (m_size == 0) return default(T); return m_items[(m_head + offset) % m_items.Length]; } + finally + { + m_lock.ExitReadLock(); + } } /// @@ -226,7 +254,8 @@ namespace Lidgren.Network /// public bool Contains(T item) { - lock (m_lock) + m_lock.EnterReadLock(); + try { int ptr = m_head; for (int i = 0; i < m_size; i++) @@ -243,8 +272,12 @@ namespace Lidgren.Network } ptr = (ptr + 1) % m_items.Length; } + return false; + } + finally + { + m_lock.ExitReadLock(); } - return false; } /// @@ -252,7 +285,8 @@ namespace Lidgren.Network /// public T[] ToArray() { - lock (m_lock) + m_lock.EnterReadLock(); + try { T[] retval = new T[m_size]; int ptr = m_head; @@ -264,6 +298,10 @@ namespace Lidgren.Network } return retval; } + finally + { + m_lock.ExitReadLock(); + } } /// @@ -271,13 +309,18 @@ namespace Lidgren.Network /// public void Clear() { - lock (m_lock) + m_lock.EnterWriteLock(); + try { for (int i = 0; i < m_items.Length; i++) m_items[i] = default(T); m_head = 0; m_size = 0; } + finally + { + m_lock.ExitWriteLock(); + } } } }