using System.Collections.Generic; using System.Threading; namespace Svelto.DataStructures { public class ThreadSafeQueue { readonly Queue m_Queue; readonly ReaderWriterLockSlim LockQ = new ReaderWriterLockSlim(); public ThreadSafeQueue() { m_Queue = new Queue(); } public ThreadSafeQueue(int capacity) { m_Queue = new Queue(capacity); } public ThreadSafeQueue(IEnumerable collection) { m_Queue = new Queue(collection); } public IEnumerator GetEnumerator() { Queue localQ; LockQ.EnterReadLock(); try { localQ = new Queue(m_Queue); } finally { LockQ.ExitReadLock(); } foreach (T item in localQ) yield return item; } public void Enqueue(T item) { LockQ.EnterWriteLock(); try { m_Queue.Enqueue(item); } finally { LockQ.ExitWriteLock(); } } public T Dequeue() { LockQ.EnterWriteLock(); try { return m_Queue.Dequeue(); } finally { LockQ.ExitWriteLock(); } } public void EnqueueAll(IEnumerable ItemsToQueue) { LockQ.EnterWriteLock(); try { foreach (T item in ItemsToQueue) m_Queue.Enqueue(item); } finally { LockQ.ExitWriteLock(); } } public FasterList DequeueAll() { LockQ.EnterWriteLock(); try { FasterList returnList = new FasterList(); while (m_Queue.Count > 0) returnList.Add(m_Queue.Dequeue()); return returnList; } finally { LockQ.ExitWriteLock(); } } public void DequeueAllInto(FasterList list) { LockQ.EnterWriteLock(); try { while (m_Queue.Count > 0) list.Add(m_Queue.Dequeue()); } finally { LockQ.ExitWriteLock(); } } public void DequeueInto(FasterList list, int count) { LockQ.EnterWriteLock(); try { int originalSize = m_Queue.Count; while (m_Queue.Count > 0 && originalSize - m_Queue.Count < count) list.Add(m_Queue.Dequeue()); } finally { LockQ.ExitWriteLock(); } } public FasterList DequeueAllAs() where U:class { LockQ.EnterWriteLock(); try { FasterList returnList = new FasterList(); while (m_Queue.Count > 0) returnList.Add(m_Queue.Dequeue() as U); return returnList; } finally { LockQ.ExitWriteLock(); } } public T Peek() { LockQ.EnterWriteLock(); try { T item = default(T); if (m_Queue.Count > 0) item = m_Queue.Peek(); return item; } finally { LockQ.ExitWriteLock(); } } public void Clear() { LockQ.EnterWriteLock(); try { m_Queue.Clear(); } finally { LockQ.ExitWriteLock(); } } public bool TryDequeue(out T item) { LockQ.EnterWriteLock(); try { if (m_Queue.Count > 0) { item = m_Queue.Dequeue(); return true; } else { item = default(T); return false; } } finally { LockQ.ExitWriteLock(); } } public int Count { get { LockQ.EnterWriteLock(); try { return m_Queue.Count; } finally { LockQ.ExitWriteLock(); } } } } }