RegisteredWaitHandle.cs 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. //
  2. // System.Threading.RegisteredWaitHandle.cs
  3. //
  4. // Author:
  5. // Dick Porter ([email protected])
  6. // Lluis Sanchez Gual ([email protected])
  7. //
  8. // (C) Ximian, Inc. http://www.ximian.com
  9. //
  10. namespace System.Threading
  11. {
  12. public sealed class RegisteredWaitHandle : MarshalByRefObject
  13. {
  14. WaitHandle _waitObject;
  15. WaitOrTimerCallback _callback;
  16. TimeSpan _timeout;
  17. object _state;
  18. bool _executeOnlyOnce;
  19. WaitHandle _finalEvent;
  20. ManualResetEvent _cancelEvent;
  21. int _callsInProcess;
  22. bool _unregistered;
  23. internal RegisteredWaitHandle (WaitHandle waitObject, WaitOrTimerCallback callback, object state, TimeSpan timeout, bool executeOnlyOnce)
  24. {
  25. _waitObject = waitObject;
  26. _callback = callback;
  27. _state = state;
  28. _timeout = timeout;
  29. _executeOnlyOnce = executeOnlyOnce;
  30. _finalEvent = null;
  31. _cancelEvent = new ManualResetEvent (false);
  32. _callsInProcess = 0;
  33. _unregistered = false;
  34. }
  35. internal void Wait (object state)
  36. {
  37. try
  38. {
  39. WaitHandle[] waits = new WaitHandle[] {_waitObject, _cancelEvent};
  40. do
  41. {
  42. int signal = WaitHandle.WaitAny (waits, _timeout, false);
  43. if (!_unregistered)
  44. {
  45. lock (this) { _callsInProcess++; }
  46. ThreadPool.QueueUserWorkItem (new WaitCallback (DoCallBack), (signal == WaitHandle.WaitTimeout));
  47. }
  48. }
  49. while (!_unregistered && !_executeOnlyOnce);
  50. }
  51. catch {}
  52. lock (this) {
  53. _unregistered = true;
  54. if (_callsInProcess == 0 && _finalEvent != null)
  55. NativeEventCalls.SetEvent_internal (_finalEvent.Handle);
  56. }
  57. }
  58. private void DoCallBack (object timedOut)
  59. {
  60. _callback (_state, (bool)timedOut);
  61. lock (this)
  62. {
  63. _callsInProcess--;
  64. if (_unregistered && _callsInProcess == 0 && _finalEvent != null)
  65. NativeEventCalls.SetEvent_internal (_finalEvent.Handle);
  66. }
  67. }
  68. public bool Unregister(WaitHandle waitObject)
  69. {
  70. lock (this)
  71. {
  72. if (_unregistered) return false;
  73. _finalEvent = waitObject;
  74. _unregistered = true;
  75. _cancelEvent.Set();
  76. return true;
  77. }
  78. }
  79. [MonoTODO]
  80. ~RegisteredWaitHandle() {
  81. // FIXME
  82. }
  83. }
  84. }