SemaphoreLight.cs 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. using System;
  2. using System.Threading;
  3. namespace Renci.SshNet.Common
  4. {
  5. /// <summary>
  6. /// Light implementation of SemaphoreSlim.
  7. /// </summary>
  8. public class SemaphoreLight
  9. {
  10. private readonly 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. /// <exception cref="ArgumentOutOfRangeException"><paramref name="initialCount"/> is a negative number.</exception>
  18. public SemaphoreLight(int initialCount)
  19. {
  20. if (initialCount < 0 )
  21. throw new ArgumentOutOfRangeException("initialCount", "The value cannot be negative.");
  22. _currentCount = initialCount;
  23. }
  24. /// <summary>
  25. /// Gets the current count of the <see cref="SemaphoreLight"/>.
  26. /// </summary>
  27. public int CurrentCount { get { return _currentCount; } }
  28. /// <summary>
  29. /// Exits the <see cref="SemaphoreLight"/> once.
  30. /// </summary>
  31. /// <returns>The previous count of the <see cref="SemaphoreLight"/>.</returns>
  32. public int Release()
  33. {
  34. return Release(1);
  35. }
  36. /// <summary>
  37. /// Exits the <see cref="SemaphoreLight"/> a specified number of times.
  38. /// </summary>
  39. /// <param name="releaseCount">The number of times to exit the semaphore.</param>
  40. /// <returns>The previous count of the <see cref="SemaphoreLight"/>.</returns>
  41. public int Release(int releaseCount)
  42. {
  43. var oldCount = _currentCount;
  44. lock (_lock)
  45. {
  46. _currentCount += releaseCount;
  47. Monitor.Pulse(_lock);
  48. }
  49. return oldCount;
  50. }
  51. /// <summary>
  52. /// Blocks the current thread until it can enter the <see cref="SemaphoreLight"/>.
  53. /// </summary>
  54. public void Wait()
  55. {
  56. lock (_lock)
  57. {
  58. while (_currentCount < 1)
  59. {
  60. Monitor.Wait(_lock);
  61. }
  62. _currentCount--;
  63. Monitor.Pulse(_lock);
  64. }
  65. }
  66. }
  67. }