WaitHandle.cs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. //
  2. // System.Threading.WaitHandle.cs
  3. //
  4. // Author:
  5. // Dick Porter ([email protected])
  6. // Gonzalo Paniagua Javier ([email protected]
  7. //
  8. // (C) 2002,2003 Ximian, Inc. (http://www.ximian.com)
  9. //
  10. using System.Runtime.CompilerServices;
  11. using System.Runtime.Remoting.Contexts;
  12. namespace System.Threading
  13. {
  14. public abstract class WaitHandle : MarshalByRefObject, IDisposable
  15. {
  16. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  17. private static extern bool WaitAll_internal(WaitHandle[] handles, int ms, bool exitContext);
  18. static void CheckArray (WaitHandle [] handles)
  19. {
  20. if (handles == null)
  21. throw new ArgumentNullException ("waitHandles");
  22. int length = handles.Length;
  23. if (length > 64)
  24. throw new NotSupportedException ("Too many handles");
  25. foreach (WaitHandle w in handles) {
  26. if (w == null)
  27. throw new ArgumentNullException ("waitHandles", "null handle");
  28. if (w.os_handle == InvalidHandle)
  29. throw new ArgumentException ("null element found", "waitHandle");
  30. }
  31. }
  32. public static bool WaitAll(WaitHandle[] waitHandles)
  33. {
  34. CheckArray (waitHandles);
  35. return(WaitAll_internal(waitHandles, Timeout.Infinite, false));
  36. }
  37. public static bool WaitAll(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
  38. {
  39. CheckArray (waitHandles);
  40. try {
  41. if (exitContext) SynchronizationAttribute.ExitContext ();
  42. return(WaitAll_internal(waitHandles, millisecondsTimeout, false));
  43. }
  44. finally {
  45. if (exitContext) SynchronizationAttribute.EnterContext ();
  46. }
  47. }
  48. public static bool WaitAll(WaitHandle[] waitHandles,
  49. TimeSpan timeout,
  50. bool exitContext)
  51. {
  52. CheckArray (waitHandles);
  53. long ms = (long) timeout.TotalMilliseconds;
  54. if (ms < -1 || ms > Int32.MaxValue)
  55. throw new ArgumentOutOfRangeException ("timeout");
  56. try {
  57. if (exitContext) SynchronizationAttribute.ExitContext ();
  58. return (WaitAll_internal (waitHandles, (int) ms, exitContext));
  59. }
  60. finally {
  61. if (exitContext) SynchronizationAttribute.EnterContext ();
  62. }
  63. }
  64. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  65. private static extern int WaitAny_internal(WaitHandle[] handles, int ms, bool exitContext);
  66. // LAMESPEC: Doesn't specify how to signal failures
  67. public static int WaitAny(WaitHandle[] waitHandles)
  68. {
  69. CheckArray (waitHandles);
  70. return(WaitAny_internal(waitHandles, Timeout.Infinite, false));
  71. }
  72. public static int WaitAny(WaitHandle[] waitHandles,
  73. int millisecondsTimeout,
  74. bool exitContext)
  75. {
  76. CheckArray (waitHandles);
  77. try {
  78. if (exitContext) SynchronizationAttribute.ExitContext ();
  79. return(WaitAny_internal(waitHandles, millisecondsTimeout, exitContext));
  80. }
  81. finally {
  82. if (exitContext) SynchronizationAttribute.EnterContext ();
  83. }
  84. }
  85. public static int WaitAny(WaitHandle[] waitHandles,
  86. TimeSpan timeout, bool exitContext)
  87. {
  88. CheckArray (waitHandles);
  89. long ms = (long) timeout.TotalMilliseconds;
  90. if (ms < -1 || ms > Int32.MaxValue)
  91. throw new ArgumentOutOfRangeException ("timeout");
  92. try {
  93. if (exitContext) SynchronizationAttribute.ExitContext ();
  94. return (WaitAny_internal(waitHandles, (int) ms, exitContext));
  95. }
  96. finally {
  97. if (exitContext) SynchronizationAttribute.EnterContext ();
  98. }
  99. }
  100. [MonoTODO]
  101. public WaitHandle() {
  102. // FIXME
  103. }
  104. public const int WaitTimeout = 258;
  105. private IntPtr os_handle = InvalidHandle;
  106. public virtual IntPtr Handle {
  107. get {
  108. return(os_handle);
  109. }
  110. set {
  111. os_handle=value;
  112. }
  113. }
  114. public virtual void Close() {
  115. Dispose(true);
  116. GC.SuppressFinalize (this);
  117. }
  118. internal void CheckDisposed ()
  119. {
  120. if (disposed || os_handle == InvalidHandle)
  121. throw new ObjectDisposedException (GetType ().FullName);
  122. }
  123. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  124. private extern bool WaitOne_internal(IntPtr handle, int ms, bool exitContext);
  125. public virtual bool WaitOne()
  126. {
  127. CheckDisposed ();
  128. return(WaitOne_internal(os_handle, Timeout.Infinite, false));
  129. }
  130. public virtual bool WaitOne(int millisecondsTimeout, bool exitContext)
  131. {
  132. CheckDisposed ();
  133. try {
  134. if (exitContext) SynchronizationAttribute.ExitContext ();
  135. return(WaitOne_internal(os_handle, millisecondsTimeout, exitContext));
  136. }
  137. finally {
  138. if (exitContext) SynchronizationAttribute.EnterContext ();
  139. }
  140. }
  141. public virtual bool WaitOne(TimeSpan timeout, bool exitContext)
  142. {
  143. CheckDisposed ();
  144. long ms = (long) timeout.TotalMilliseconds;
  145. if (ms < -1 || ms > Int32.MaxValue)
  146. throw new ArgumentOutOfRangeException ("timeout");
  147. try {
  148. if (exitContext) SynchronizationAttribute.ExitContext ();
  149. return (WaitOne_internal(os_handle, (int) ms, exitContext));
  150. }
  151. finally {
  152. if (exitContext) SynchronizationAttribute.EnterContext ();
  153. }
  154. }
  155. protected static readonly IntPtr InvalidHandle = IntPtr.Zero;
  156. private bool disposed = false;
  157. void IDisposable.Dispose() {
  158. Dispose(true);
  159. // Take yourself off the Finalization queue
  160. GC.SuppressFinalize(this);
  161. }
  162. protected virtual void Dispose(bool explicitDisposing) {
  163. // Check to see if Dispose has already been called.
  164. if (!disposed) {
  165. disposed=true;
  166. if (os_handle == InvalidHandle)
  167. return;
  168. lock (this) {
  169. if (os_handle != InvalidHandle) {
  170. NativeEventCalls.CloseEvent_internal (os_handle);
  171. os_handle = InvalidHandle;
  172. }
  173. }
  174. }
  175. }
  176. ~WaitHandle() {
  177. Dispose(false);
  178. }
  179. }
  180. }