PageRenderTime 43ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/otp.net/Otp/GenericQueue.cs

https://github.com/gebi/jungerl
C# | 242 lines | 165 code | 27 blank | 50 comment | 24 complexity | 0328b68a0e345f28d7c7efba7c70d925 MD5 | raw file
Possible License(s): LGPL-2.1, BSD-3-Clause, AGPL-1.0
  1. /*``The contents of this file are subject to the Erlang Public License,
  2. * Version 1.1, (the "License"); you may not use this file except in
  3. * compliance with the License. You should have received a copy of the
  4. * Erlang Public License along with this software. If not, it can be
  5. * retrieved via the world wide web at http://www.erlang.org/.
  6. *
  7. * Software distributed under the License is distributed on an "AS IS"
  8. * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
  9. * the License for the specific language governing rights and limitations
  10. * under the License.
  11. *
  12. * The Initial Developer of the Original Code is Ericsson Utvecklings AB.
  13. * Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
  14. * AB. All Rights Reserved.''
  15. *
  16. * Converted from Java to C# by Vlad Dumitrescu (vlad_Dumitrescu@hotmail.com)
  17. */
  18. namespace Otp
  19. {
  20. /*This class implements a generic FIFO queue. There is no upper
  21. * bound on the length of the queue, items are linked.
  22. */
  23. using System;
  24. public class GenericQueue
  25. {
  26. private const int open = 0;
  27. private const int closing = 1;
  28. private const int closed = 2;
  29. private int status = closed;
  30. private Bucket head;
  31. private Bucket tail;
  32. private int count;
  33. private void init()
  34. {
  35. head = null;
  36. tail = null;
  37. count = 0;
  38. }
  39. /*Create an empty queue */
  40. public GenericQueue()
  41. {
  42. init();
  43. status = open;
  44. }
  45. /*Clear a queue */
  46. public virtual void flush()
  47. {
  48. close();
  49. init();
  50. status = open;
  51. }
  52. public virtual void close()
  53. {
  54. status = closing;
  55. init();
  56. try
  57. {
  58. System.Threading.Monitor.PulseAll(this);
  59. }
  60. catch
  61. {
  62. }
  63. status = closed;
  64. }
  65. /*Add an object to the tail of the queue.
  66. * @param o Object to insert in the queue
  67. */
  68. public virtual void put(System.Object o)
  69. {
  70. lock(this)
  71. {
  72. Bucket b = new Bucket(this, o);
  73. if (tail != null)
  74. {
  75. tail.setNext(b);
  76. tail = b;
  77. }
  78. else
  79. {
  80. // queue was empty but has one element now
  81. head = (tail = b);
  82. }
  83. count++;
  84. // notify any waiting tasks
  85. //UPGRADE_TODO: threading!
  86. System.Threading.Monitor.PulseAll(this);
  87. }
  88. }
  89. private System.Object get(bool once)
  90. {
  91. lock(this)
  92. {
  93. System.Object o = null;
  94. while ((o = tryGet()) == null && !once && status == open)
  95. {
  96. try
  97. {
  98. //UPGRADE_TODO: threading!
  99. System.Threading.Monitor.Wait(this);
  100. }
  101. catch (System.Threading.ThreadInterruptedException)
  102. {
  103. }
  104. }
  105. return o;
  106. }
  107. }
  108. /*Retrieve an object from the head of the queue, or block until
  109. * one arrives.
  110. *
  111. * @return The object at the head of the queue.
  112. */
  113. public virtual System.Object get()
  114. {
  115. return get(false);
  116. }
  117. /*Retrieve an object from the head of the queue, blocking until
  118. * one arrives or until timeout occurs.
  119. *
  120. * @param timeout Maximum time to block on queue, in ms. Use 0 to poll the queue.
  121. *
  122. * @exception InterruptedException if the operation times out.
  123. *
  124. * @return The object at the head of the queue, or null if none arrived in time.
  125. */
  126. public virtual System.Object get(long timeout)
  127. {
  128. if (timeout == -1)
  129. return get(false);
  130. else if (timeout == 0)
  131. return get(true);
  132. lock(this)
  133. {
  134. if (status != open)
  135. return null;
  136. long currentTime = SupportClass.currentTimeMillis();
  137. long stopTime = currentTime + timeout;
  138. System.Object o = null;
  139. while (true)
  140. {
  141. if (status != open || (o = tryGet()) != null)
  142. return o;
  143. currentTime = SupportClass.currentTimeMillis();
  144. if (stopTime <= currentTime)
  145. throw new System.Threading.ThreadInterruptedException("Get operation timed out");
  146. try
  147. {
  148. //UPGRADE_TODO: threading!
  149. System.Threading.Monitor.Wait(this, new TimeSpan((stopTime - currentTime)*TimeSpan.TicksPerMillisecond));
  150. }
  151. catch (System.Threading.ThreadInterruptedException)
  152. {
  153. // ignore, but really should retry operation instead
  154. }
  155. }
  156. }
  157. }
  158. // attempt to retrieve message from queue head
  159. public virtual System.Object tryGet()
  160. {
  161. System.Object o = null;
  162. if (head != null)
  163. {
  164. o = head.getContents();
  165. head = head.getNext();
  166. count--;
  167. if (head == null)
  168. {
  169. tail = null;
  170. count = 0;
  171. }
  172. }
  173. return o;
  174. }
  175. public virtual int getCount()
  176. {
  177. lock(this)
  178. {
  179. return count;
  180. }
  181. }
  182. /*
  183. * The Bucket class. The queue is implemented as a linked list
  184. * of Buckets. The container holds the queued object and a
  185. * reference to the next Bucket. */
  186. internal class Bucket
  187. {
  188. private void InitBlock(GenericQueue enclosingInstance)
  189. {
  190. this.enclosingInstance = enclosingInstance;
  191. }
  192. private GenericQueue enclosingInstance;
  193. private Bucket next;
  194. private System.Object contents;
  195. public Bucket(GenericQueue enclosingInstance, System.Object o)
  196. {
  197. InitBlock(enclosingInstance);
  198. next = null;
  199. contents = o;
  200. }
  201. public virtual void setNext(Bucket newNext)
  202. {
  203. next = newNext;
  204. }
  205. public virtual Bucket getNext()
  206. {
  207. return next;
  208. }
  209. public virtual System.Object getContents()
  210. {
  211. return contents;
  212. }
  213. }
  214. }
  215. }