diff options
author | Justin Clark-Casey (justincc) | 2013-07-16 21:54:00 +0100 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2013-07-16 22:03:49 +0100 |
commit | 21a09ad3ad42b24bce4fc04c6bcd6f7d9a80af08 (patch) | |
tree | f08f178dcc35e59eb6b4d946ca57d459c7cceff8 /OpenSim | |
parent | In the pursuit of using less CPU: now trying to avoid blocking queues altoget... (diff) | |
download | opensim-SC-21a09ad3ad42b24bce4fc04c6bcd6f7d9a80af08.zip opensim-SC-21a09ad3ad42b24bce4fc04c6bcd6f7d9a80af08.tar.gz opensim-SC-21a09ad3ad42b24bce4fc04c6bcd6f7d9a80af08.tar.bz2 opensim-SC-21a09ad3ad42b24bce4fc04c6bcd6f7d9a80af08.tar.xz |
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 42e2a0d66eaa7e322bce817e9e2cc9a288de167b
Reverting because unfortunately this introduces race conditions because Contains(), Count() and GetQueueArray() may now end up returning the wrong result if another thread performs a simultaneous update on m_queue.
Code such as PollServiceRequestManager.Stop() relies on the count being correct otherwise a request may be lost.
Also, though some of the internal queue methods do not affect state, they are not thread-safe and could return the wrong result generating the same problem
lock() generates Monitor.Enter() and Monitor.Exit() under the covers. Monitor.Exit() does not cause Monitor.Wait() to exist, only Pulse() and PulseAll() will do this
Reverted with agreement.
Diffstat (limited to 'OpenSim')
-rw-r--r-- | OpenSim/Framework/BlockingQueue.cs | 13 |
1 files changed, 5 insertions, 8 deletions
diff --git a/OpenSim/Framework/BlockingQueue.cs b/OpenSim/Framework/BlockingQueue.cs index cc016b0..3658161 100644 --- a/OpenSim/Framework/BlockingQueue.cs +++ b/OpenSim/Framework/BlockingQueue.cs | |||
@@ -58,7 +58,7 @@ namespace OpenSim.Framework | |||
58 | { | 58 | { |
59 | lock (m_queueSync) | 59 | lock (m_queueSync) |
60 | { | 60 | { |
61 | while (m_queue.Count < 1 && m_pqueue.Count < 1) | 61 | if (m_queue.Count < 1 && m_pqueue.Count < 1) |
62 | { | 62 | { |
63 | Monitor.Wait(m_queueSync); | 63 | Monitor.Wait(m_queueSync); |
64 | } | 64 | } |
@@ -91,9 +91,6 @@ namespace OpenSim.Framework | |||
91 | 91 | ||
92 | public bool Contains(T item) | 92 | public bool Contains(T item) |
93 | { | 93 | { |
94 | if (m_queue.Count < 1 && m_pqueue.Count < 1) | ||
95 | return false; | ||
96 | |||
97 | lock (m_queueSync) | 94 | lock (m_queueSync) |
98 | { | 95 | { |
99 | if (m_pqueue.Contains(item)) | 96 | if (m_pqueue.Contains(item)) |
@@ -104,14 +101,14 @@ namespace OpenSim.Framework | |||
104 | 101 | ||
105 | public int Count() | 102 | public int Count() |
106 | { | 103 | { |
107 | return m_queue.Count+m_pqueue.Count; | 104 | lock (m_queueSync) |
105 | { | ||
106 | return m_queue.Count+m_pqueue.Count; | ||
107 | } | ||
108 | } | 108 | } |
109 | 109 | ||
110 | public T[] GetQueueArray() | 110 | public T[] GetQueueArray() |
111 | { | 111 | { |
112 | if (m_queue.Count < 1 && m_pqueue.Count < 1) | ||
113 | return new T[0]; | ||
114 | |||
115 | lock (m_queueSync) | 112 | lock (m_queueSync) |
116 | { | 113 | { |
117 | return m_queue.ToArray(); | 114 | return m_queue.ToArray(); |