From 50b8ab60f2d4d8a2cc7024012fc1333be7635276 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Tue, 16 Jul 2013 23:00:07 +0100 Subject: [PATCH] Revert "Revert "MSDN documentation is unclear about whether exiting a lock() block will trigger a Monitor.Wait() to exit, so avoid some locks that don't actually affect the state of the internal queues in the BlockingQueue class."" This reverts commit 21a09ad3ad42b24bce4fc04c6bcd6f7d9a80af08. After more analysis and discussion, it is apparant that the Count(), Contains() and GetQueueArray() cannot be made thread-safe anyway without external locking And this change appears to have a positive impact on performance. I still believe that Monitor.Exit() will not release any thread for Monitor.Wait(), as per http://msdn.microsoft.com/en-gb/library/vstudio/system.threading.monitor.exit%28v=vs.100%29.aspx so this should in theory make no difference, though mono implementation issues could possibly be coming into play. --- OpenSim/Framework/BlockingQueue.cs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/OpenSim/Framework/BlockingQueue.cs b/OpenSim/Framework/BlockingQueue.cs index 365816109b..cc016b07c3 100644 --- a/OpenSim/Framework/BlockingQueue.cs +++ b/OpenSim/Framework/BlockingQueue.cs @@ -58,7 +58,7 @@ namespace OpenSim.Framework { lock (m_queueSync) { - if (m_queue.Count < 1 && m_pqueue.Count < 1) + while (m_queue.Count < 1 && m_pqueue.Count < 1) { Monitor.Wait(m_queueSync); } @@ -91,6 +91,9 @@ namespace OpenSim.Framework public bool Contains(T item) { + if (m_queue.Count < 1 && m_pqueue.Count < 1) + return false; + lock (m_queueSync) { if (m_pqueue.Contains(item)) @@ -101,14 +104,14 @@ namespace OpenSim.Framework public int Count() { - lock (m_queueSync) - { - return m_queue.Count+m_pqueue.Count; - } + return m_queue.Count+m_pqueue.Count; } public T[] GetQueueArray() { + if (m_queue.Count < 1 && m_pqueue.Count < 1) + return new T[0]; + lock (m_queueSync) { return m_queue.ToArray();