AscynLock.cs 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. // this code is borrowed from RxOfficial(rx.codeplex.com) and modified
  2. using System;
  3. using System.Collections.Generic;
  4. namespace UniRx.InternalUtil
  5. {
  6. /// <summary>
  7. /// Asynchronous lock.
  8. /// </summary>
  9. internal sealed class AsyncLock : IDisposable
  10. {
  11. private readonly Queue<Action> queue = new Queue<Action>();
  12. private bool isAcquired = false;
  13. private bool hasFaulted = false;
  14. /// <summary>
  15. /// Queues the action for execution. If the caller acquires the lock and becomes the owner,
  16. /// the queue is processed. If the lock is already owned, the action is queued and will get
  17. /// processed by the owner.
  18. /// </summary>
  19. /// <param name="action">Action to queue for execution.</param>
  20. /// <exception cref="ArgumentNullException"><paramref name="action"/> is null.</exception>
  21. public void Wait(Action action)
  22. {
  23. if (action == null)
  24. throw new ArgumentNullException("action");
  25. var isOwner = false;
  26. lock (queue)
  27. {
  28. if (!hasFaulted)
  29. {
  30. queue.Enqueue(action);
  31. isOwner = !isAcquired;
  32. isAcquired = true;
  33. }
  34. }
  35. if (isOwner)
  36. {
  37. while (true)
  38. {
  39. var work = default(Action);
  40. lock (queue)
  41. {
  42. if (queue.Count > 0)
  43. work = queue.Dequeue();
  44. else
  45. {
  46. isAcquired = false;
  47. break;
  48. }
  49. }
  50. try
  51. {
  52. work();
  53. }
  54. catch
  55. {
  56. lock (queue)
  57. {
  58. queue.Clear();
  59. hasFaulted = true;
  60. }
  61. throw;
  62. }
  63. }
  64. }
  65. }
  66. /// <summary>
  67. /// Clears the work items in the queue and drops further work being queued.
  68. /// </summary>
  69. public void Dispose()
  70. {
  71. lock (queue)
  72. {
  73. queue.Clear();
  74. hasFaulted = true;
  75. }
  76. }
  77. }
  78. }