Mirror of Svelto.ECS because we're a fan of it
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

234 lines
4.8KB

  1. using System.Collections.Generic;
  2. using System.Threading;
  3. namespace Svelto.DataStructures
  4. {
  5. public class ThreadSafeQueue<T>
  6. {
  7. readonly Queue<T> m_Queue;
  8. readonly ReaderWriterLockSlim LockQ = new ReaderWriterLockSlim();
  9. public ThreadSafeQueue()
  10. {
  11. m_Queue = new Queue<T>();
  12. }
  13. public ThreadSafeQueue(int capacity)
  14. {
  15. m_Queue = new Queue<T>(capacity);
  16. }
  17. public ThreadSafeQueue(IEnumerable<T> collection)
  18. {
  19. m_Queue = new Queue<T>(collection);
  20. }
  21. public IEnumerator<T> GetEnumerator()
  22. {
  23. Queue<T> localQ;
  24. LockQ.EnterReadLock();
  25. try
  26. {
  27. localQ = new Queue<T>(m_Queue);
  28. }
  29. finally
  30. {
  31. LockQ.ExitReadLock();
  32. }
  33. foreach (T item in localQ)
  34. yield return item;
  35. }
  36. public void Enqueue(T item)
  37. {
  38. LockQ.EnterWriteLock();
  39. try
  40. {
  41. m_Queue.Enqueue(item);
  42. }
  43. finally
  44. {
  45. LockQ.ExitWriteLock();
  46. }
  47. }
  48. public T Dequeue()
  49. {
  50. LockQ.EnterWriteLock();
  51. try
  52. {
  53. return m_Queue.Dequeue();
  54. }
  55. finally
  56. {
  57. LockQ.ExitWriteLock();
  58. }
  59. }
  60. public void EnqueueAll(IEnumerable<T> ItemsToQueue)
  61. {
  62. LockQ.EnterWriteLock();
  63. try
  64. {
  65. foreach (T item in ItemsToQueue)
  66. m_Queue.Enqueue(item);
  67. }
  68. finally
  69. {
  70. LockQ.ExitWriteLock();
  71. }
  72. }
  73. public FasterList<T> DequeueAll()
  74. {
  75. LockQ.EnterWriteLock();
  76. try
  77. {
  78. FasterList<T> returnList = new FasterList<T>();
  79. while (m_Queue.Count > 0)
  80. returnList.Add(m_Queue.Dequeue());
  81. return returnList;
  82. }
  83. finally
  84. {
  85. LockQ.ExitWriteLock();
  86. }
  87. }
  88. public void DequeueAllInto(FasterList<T> list)
  89. {
  90. LockQ.EnterWriteLock();
  91. try
  92. {
  93. while (m_Queue.Count > 0)
  94. list.Add(m_Queue.Dequeue());
  95. }
  96. finally
  97. {
  98. LockQ.ExitWriteLock();
  99. }
  100. }
  101. public void DequeueInto(FasterList<T> list, int count)
  102. {
  103. LockQ.EnterWriteLock();
  104. try
  105. {
  106. int originalSize = m_Queue.Count;
  107. while (m_Queue.Count > 0 && originalSize - m_Queue.Count < count)
  108. list.Add(m_Queue.Dequeue());
  109. }
  110. finally
  111. {
  112. LockQ.ExitWriteLock();
  113. }
  114. }
  115. public FasterList<U> DequeueAllAs<U>() where U:class
  116. {
  117. LockQ.EnterWriteLock();
  118. try
  119. {
  120. FasterList<U> returnList = new FasterList<U>();
  121. while (m_Queue.Count > 0)
  122. returnList.Add(m_Queue.Dequeue() as U);
  123. return returnList;
  124. }
  125. finally
  126. {
  127. LockQ.ExitWriteLock();
  128. }
  129. }
  130. public T Peek()
  131. {
  132. LockQ.EnterWriteLock();
  133. try
  134. {
  135. T item = default(T);
  136. if (m_Queue.Count > 0)
  137. item = m_Queue.Peek();
  138. return item;
  139. }
  140. finally
  141. {
  142. LockQ.ExitWriteLock();
  143. }
  144. }
  145. public void Clear()
  146. {
  147. LockQ.EnterWriteLock();
  148. try
  149. {
  150. m_Queue.Clear();
  151. }
  152. finally
  153. {
  154. LockQ.ExitWriteLock();
  155. }
  156. }
  157. public bool TryDequeue(out T item)
  158. {
  159. LockQ.EnterWriteLock();
  160. try
  161. {
  162. if (m_Queue.Count > 0)
  163. {
  164. item = m_Queue.Dequeue();
  165. return true;
  166. }
  167. else
  168. {
  169. item = default(T);
  170. return false;
  171. }
  172. }
  173. finally
  174. {
  175. LockQ.ExitWriteLock();
  176. }
  177. }
  178. public int Count
  179. {
  180. get
  181. {
  182. LockQ.EnterWriteLock();
  183. try
  184. {
  185. return m_Queue.Count;
  186. }
  187. finally
  188. {
  189. LockQ.ExitWriteLock();
  190. }
  191. }
  192. }
  193. }
  194. }