WaitHandle.cs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  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. namespace System.Threading
  12. {
  13. public abstract class WaitHandle : MarshalByRefObject, IDisposable
  14. {
  15. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  16. private static extern bool WaitAll_internal(WaitHandle[] handles, int ms, bool exitContext);
  17. static void CheckArray (WaitHandle [] handles)
  18. {
  19. if (handles == null)
  20. throw new ArgumentNullException ("waitHandles");
  21. int length = handles.Length;
  22. if (length > 64)
  23. throw new NotSupportedException ("Too many handles");
  24. foreach (WaitHandle w in handles) {
  25. if (w == null)
  26. throw new ArgumentNullException ("waitHandles", "null handle");
  27. if (w.os_handle == InvalidHandle)
  28. throw new ArgumentException ("null element found", "waitHandle");
  29. }
  30. }
  31. public static bool WaitAll(WaitHandle[] waitHandles)
  32. {
  33. CheckArray (waitHandles);
  34. return(WaitAll_internal(waitHandles, Timeout.Infinite, false));
  35. }
  36. public static bool WaitAll(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
  37. {
  38. CheckArray (waitHandles);
  39. return(WaitAll_internal(waitHandles, millisecondsTimeout, false));
  40. }
  41. public static bool WaitAll(WaitHandle[] waitHandles,
  42. TimeSpan timeout,
  43. bool exitContext)
  44. {
  45. CheckArray (waitHandles);
  46. long ms = (long) timeout.TotalMilliseconds;
  47. if (ms < -1 || ms > Int32.MaxValue)
  48. throw new ArgumentOutOfRangeException ("timeout");
  49. return (WaitAll_internal (waitHandles, (int) ms, exitContext));
  50. }
  51. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  52. private static extern int WaitAny_internal(WaitHandle[] handles, int ms, bool exitContext);
  53. // LAMESPEC: Doesn't specify how to signal failures
  54. public static int WaitAny(WaitHandle[] waitHandles)
  55. {
  56. CheckArray (waitHandles);
  57. return(WaitAny_internal(waitHandles, Timeout.Infinite, false));
  58. }
  59. public static int WaitAny(WaitHandle[] waitHandles,
  60. int millisecondsTimeout,
  61. bool exitContext)
  62. {
  63. CheckArray (waitHandles);
  64. return(WaitAny_internal(waitHandles, millisecondsTimeout, exitContext));
  65. }
  66. public static int WaitAny(WaitHandle[] waitHandles,
  67. TimeSpan timeout, bool exitContext)
  68. {
  69. CheckArray (waitHandles);
  70. long ms = (long) timeout.TotalMilliseconds;
  71. if (ms < -1 || ms > Int32.MaxValue)
  72. throw new ArgumentOutOfRangeException ("timeout");
  73. return (WaitAny_internal(waitHandles, (int) ms, exitContext));
  74. }
  75. [MonoTODO]
  76. public WaitHandle() {
  77. // FIXME
  78. }
  79. public const int WaitTimeout = 258;
  80. private IntPtr os_handle = InvalidHandle;
  81. public virtual IntPtr Handle {
  82. get {
  83. return(os_handle);
  84. }
  85. set {
  86. os_handle=value;
  87. }
  88. }
  89. public virtual void Close() {
  90. Dispose(true);
  91. GC.SuppressFinalize (this);
  92. }
  93. internal void CheckDisposed ()
  94. {
  95. if (disposed || os_handle == InvalidHandle)
  96. throw new ObjectDisposedException (GetType ().FullName);
  97. }
  98. [MethodImplAttribute(MethodImplOptions.InternalCall)]
  99. private extern bool WaitOne_internal(IntPtr handle, int ms, bool exitContext);
  100. public virtual bool WaitOne()
  101. {
  102. CheckDisposed ();
  103. return(WaitOne_internal(os_handle, Timeout.Infinite, false));
  104. }
  105. public virtual bool WaitOne(int millisecondsTimeout, bool exitContext)
  106. {
  107. CheckDisposed ();
  108. return(WaitOne_internal(os_handle, millisecondsTimeout, exitContext));
  109. }
  110. public virtual bool WaitOne(TimeSpan timeout, bool exitContext)
  111. {
  112. CheckDisposed ();
  113. long ms = (long) timeout.TotalMilliseconds;
  114. if (ms < -1 || ms > Int32.MaxValue)
  115. throw new ArgumentOutOfRangeException ("timeout");
  116. return (WaitOne_internal(os_handle, (int) ms, exitContext));
  117. }
  118. protected static readonly IntPtr InvalidHandle = IntPtr.Zero;
  119. private bool disposed = false;
  120. void IDisposable.Dispose() {
  121. Dispose(true);
  122. // Take yourself off the Finalization queue
  123. GC.SuppressFinalize(this);
  124. }
  125. protected virtual void Dispose(bool explicitDisposing) {
  126. // Check to see if Dispose has already been called.
  127. if (!disposed) {
  128. disposed=true;
  129. if (os_handle == InvalidHandle)
  130. return;
  131. lock (this) {
  132. if (os_handle != InvalidHandle) {
  133. NativeEventCalls.CloseEvent_internal (os_handle);
  134. os_handle = InvalidHandle;
  135. }
  136. }
  137. }
  138. }
  139. ~WaitHandle() {
  140. Dispose(false);
  141. }
  142. }
  143. }