SemaphoreLight.cs 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading;
  6. namespace Renci.SshNet.Common
  7. {
  8. public class SemaphoreLight
  9. {
  10. private object _lock = new object();
  11. private int _currentCount;
  12. /// <summary>
  13. /// Initializes a new instance of the <see cref="SemaphoreLight"/> class, specifying
  14. /// the initial number of requests that can be granted concurrently.
  15. /// </summary>
  16. /// <param name="initialCount">The initial number of requests for the semaphore that can be granted concurrently.</param>
  17. public SemaphoreLight(int initialCount)
  18. {
  19. if (initialCount < 0 )
  20. throw new ArgumentOutOfRangeException("The initial argument is negative");
  21. this._currentCount = initialCount;
  22. }
  23. /// <summary>
  24. /// Gets the current count of the <see cref="SemaphoreLight"/>.
  25. /// </summary>
  26. public int CurrentCount { get { return this._currentCount; } }
  27. /// <summary>
  28. /// Exits the <see cref="SemaphoreLight"/> once.
  29. /// </summary>
  30. /// <returns>The previous count of the <see cref="SemaphoreLight"/>.</returns>
  31. public int Release()
  32. {
  33. return this.Release(1);
  34. }
  35. /// <summary>
  36. /// Exits the <see cref="SemaphoreLight"/> a specified number of times.
  37. /// </summary>
  38. /// <param name="releaseCount">The number of times to exit the semaphore.</param>
  39. /// <returns>The previous count of the <see cref="SemaphoreLight"/>.</returns>
  40. public int Release(int releaseCount)
  41. {
  42. var oldCount = this._currentCount;
  43. lock (this._lock)
  44. {
  45. this._currentCount += releaseCount;
  46. Monitor.Pulse(this._lock);
  47. }
  48. return oldCount;
  49. }
  50. /// <summary>
  51. /// Blocks the current thread until it can enter the <see cref="SemaphoreLight"/>.
  52. /// </summary>
  53. public void Wait()
  54. {
  55. lock (this._lock)
  56. {
  57. while (this._currentCount < 1)
  58. {
  59. Monitor.Wait(this._lock);
  60. }
  61. this._currentCount--;
  62. Monitor.Pulse(this._lock);
  63. }
  64. }
  65. }
  66. }