/VsIntegration/Nemerle.Compiler.Utils/Async/AsyncWorker.n

http://github.com/xxVisorxx/nemerle · Unknown · 189 lines · 154 code · 35 blank · 0 comment · 0 complexity · f35e5de75a6a01546535c3bafc7773f6 MD5 · raw file

  1. using Nemerle.Collections;
  2. using Nemerle.Text;
  3. using Nemerle.Utility;
  4. using System;
  5. using System.Linq;
  6. using System.Collections.Generic;
  7. using System.Threading;
  8. using System.Diagnostics;
  9. using SCG = System.Collections.Generic;
  10. //using System.Runtime.Remoting.Messaging;
  11. namespace Nemerle.Compiler.Utils.Async
  12. {
  13. /// <summary>
  14. /// Description of AsyncWorker.
  15. /// </summary>
  16. public module AsyncWorker
  17. {
  18. /// Set to true for debuding purpose!
  19. public IsRunSynchronously : bool = false;
  20. _requestsQueue : SCG.Queue[AsyncRequest] = SCG.Queue();
  21. _responseQueue : SCG.Queue[AsyncResponse] = SCG.Queue();
  22. _waitWork : AutoResetEvent = AutoResetEvent(false);
  23. _thread : Thread;
  24. mutable _curentWork : AsyncRequest;
  25. this()
  26. {
  27. def maxStackSize = 12 * 1024 * 1024 * if (System.IntPtr.Size == 8) 2 else 1;
  28. _thread = Thread(ThreadStart(ThreadProc), maxStackSize);
  29. _thread.Priority = ThreadPriority.BelowNormal;
  30. _thread.IsBackground = true;
  31. _thread.Name = "AsyncWorker";
  32. unless (IsRunSynchronously)
  33. _thread.Start();
  34. }
  35. mutable _isStop : bool;
  36. public IsCurrentThreadTheAsyncWorker : bool { get { Thread.CurrentThread.Equals(_thread) } }
  37. public CheckCurrentThreadIsTheAsyncWorker() : void
  38. {
  39. unless (IsRunSynchronously)
  40. assert(IsCurrentThreadTheAsyncWorker);
  41. }
  42. public Stop() : void
  43. {
  44. _isStop = true;
  45. def curentWork = _curentWork;
  46. when (curentWork != null)
  47. curentWork.Stop = true;
  48. unless (IsRunSynchronously)
  49. ignore(_waitWork.Set());
  50. }
  51. /// ?????????? ????????? ?????? ????????? ??????? ???? ??????????? ??????? ????
  52. /// ????????? ? ??????? ???????.
  53. private GetNextRequest() : AsyncRequest
  54. {
  55. lock (_requestsQueue)
  56. {
  57. def loop()
  58. {
  59. if (_requestsQueue.IsEmpty())
  60. null
  61. else
  62. {
  63. def request = _requestsQueue.Dequeue();
  64. if (_requestsQueue.Exists(x => request.IsForceOutBy(x)))
  65. {
  66. request.Stop = true;
  67. request.MarkAsCompleted();
  68. loop()
  69. }
  70. else
  71. request
  72. }
  73. }
  74. loop()
  75. }
  76. }
  77. public DoSynchronously() : bool
  78. {
  79. if (IsRunSynchronously)
  80. {
  81. ThreadProc();
  82. !_requestsQueue.IsEmpty()
  83. }
  84. else
  85. false
  86. }
  87. private ThreadProc() : void
  88. {
  89. def loop()
  90. {
  91. when (_requestsQueue.IsEmpty() && !_isStop && !IsRunSynchronously)
  92. ignore(_waitWork.WaitOne());
  93. Thread.Sleep(0);
  94. _curentWork = if (_isStop) null else GetNextRequest();
  95. when (!_isStop && _curentWork != null)
  96. try { _curentWork.DoWork(); }
  97. catch
  98. { | e =>
  99. Debug.WriteLine($"AsyncWorker thread exception($(e.GetType().Name)):");
  100. Debug.WriteLine($" $(e.Message)");
  101. //_ = e.StackTrace;
  102. _curentWork.MarkAsCompleted();
  103. }
  104. Thread.Sleep(10);
  105. unless (IsRunSynchronously)
  106. unless (_isStop)
  107. loop();
  108. }
  109. loop();
  110. }
  111. public GetResponse() : AsyncResponse
  112. {
  113. lock (_responseQueue)
  114. _responseQueue.Dequeue();
  115. }
  116. public GetResponses() : array[AsyncResponse]
  117. {
  118. lock (_responseQueue)
  119. {
  120. def result = _responseQueue.ToArray();
  121. _responseQueue.Clear();
  122. result
  123. }
  124. }
  125. public DispatchResponses() : void
  126. {
  127. foreach (response in GetResponses())
  128. response();
  129. }
  130. public AddResponse(response : AsyncResponse) : void
  131. {
  132. lock (_responseQueue)
  133. _responseQueue.Enqueue(response);
  134. }
  135. public AddWork(request : AsyncRequest) : void
  136. {
  137. when (_isStop)
  138. throw InvalidOperationException("The AsyncWorker is in stoped state");
  139. lock (_requestsQueue)
  140. _requestsQueue.Enqueue(request);
  141. //VladD2: ???? ? ???? ?????? ??????????? ?????? (_curentWork != null) ??????? ??????
  142. // ????? ??? ?????????? ??????? ?????? (????????, ?????? ?? ?????????? ??????? ?????),
  143. // ????? ?????????? _curentWork.Stop ? true.
  144. def curentWork = _curentWork;
  145. when (curentWork != null && curentWork.IsForceOutBy(request))
  146. {
  147. curentWork.Stop = true;
  148. curentWork.MarkAsCompleted();
  149. }
  150. unless (IsRunSynchronously)
  151. ignore(_waitWork.Set());
  152. }
  153. }
  154. }