SemaphoreLight.cs 2.5 KB

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