PageRenderTime 48ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

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

https://github.com/bmizerany/jungerl
C# | 222 lines | 146 code | 26 blank | 50 comment | 14 complexity | c72b25d099dc18bc8f9d5418795fd244 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;
  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. init();
  49. }
  50. public virtual void close()
  51. {
  52. status = closing;
  53. }
  54. /*Add an object to the tail of the queue.
  55. * @param o Object to insert in the queue
  56. */
  57. public virtual void put(System.Object o)
  58. {
  59. lock(this)
  60. {
  61. Bucket b = new Bucket(this, o);
  62. if (tail != null)
  63. {
  64. tail.setNext(b);
  65. tail = b;
  66. }
  67. else
  68. {
  69. // queue was empty but has one element now
  70. head = (tail = b);
  71. }
  72. count++;
  73. // notify any waiting tasks
  74. //UPGRADE_TODO: threading!
  75. System.Threading.Monitor.PulseAll(this);
  76. }
  77. }
  78. /*Retrieve an object from the head of the queue, or block until
  79. * one arrives.
  80. *
  81. * @return The object at the head of the queue.
  82. */
  83. public virtual System.Object get()
  84. {
  85. lock(this)
  86. {
  87. System.Object o = null;
  88. while ((o = tryGet()) == null)
  89. {
  90. try
  91. {
  92. //UPGRADE_TODO: threading!
  93. System.Threading.Monitor.Wait(this);
  94. }
  95. catch (System.Threading.ThreadInterruptedException)
  96. {
  97. }
  98. }
  99. return o;
  100. }
  101. }
  102. /*Retrieve an object from the head of the queue, blocking until
  103. * one arrives or until timeout occurs.
  104. *
  105. * @param timeout Maximum time to block on queue, in ms. Use 0 to poll the queue.
  106. *
  107. * @exception InterruptedException if the operation times out.
  108. *
  109. * @return The object at the head of the queue, or null if none arrived in time.
  110. */
  111. public virtual System.Object get(long timeout)
  112. {
  113. lock(this)
  114. {
  115. if (status == closed)
  116. return null;
  117. long currentTime = SupportClass.currentTimeMillis();
  118. long stopTime = currentTime + timeout;
  119. System.Object o = null;
  120. while (true)
  121. {
  122. if ((o = tryGet()) != null)
  123. return o;
  124. currentTime = SupportClass.currentTimeMillis();
  125. if (stopTime <= currentTime)
  126. throw new System.Threading.ThreadInterruptedException("Get operation timed out");
  127. try
  128. {
  129. //UPGRADE_TODO: threading!
  130. System.Threading.Monitor.Wait(this, new TimeSpan((stopTime - currentTime)*TimeSpan.TicksPerMillisecond));
  131. }
  132. catch (System.Threading.ThreadInterruptedException)
  133. {
  134. // ignore, but really should retry operation instead
  135. }
  136. }
  137. }
  138. }
  139. // attempt to retrieve message from queue head
  140. public virtual System.Object tryGet()
  141. {
  142. System.Object o = null;
  143. if (head != null)
  144. {
  145. o = head.getContents();
  146. head = head.getNext();
  147. count--;
  148. if (head == null)
  149. {
  150. tail = null;
  151. count = 0;
  152. }
  153. }
  154. return o;
  155. }
  156. public virtual int getCount()
  157. {
  158. lock(this)
  159. {
  160. return count;
  161. }
  162. }
  163. /*
  164. * The Bucket class. The queue is implemented as a linked list
  165. * of Buckets. The container holds the queued object and a
  166. * reference to the next Bucket. */
  167. internal class Bucket
  168. {
  169. private void InitBlock(GenericQueue enclosingInstance)
  170. {
  171. this.enclosingInstance = enclosingInstance;
  172. }
  173. private GenericQueue enclosingInstance;
  174. private Bucket next;
  175. private System.Object contents;
  176. public Bucket(GenericQueue enclosingInstance, System.Object o)
  177. {
  178. InitBlock(enclosingInstance);
  179. next = null;
  180. contents = o;
  181. }
  182. public virtual void setNext(Bucket newNext)
  183. {
  184. next = newNext;
  185. }
  186. public virtual Bucket getNext()
  187. {
  188. return next;
  189. }
  190. public virtual System.Object getContents()
  191. {
  192. return contents;
  193. }
  194. }
  195. }
  196. }