IOThreadCancellationTokenSource.cs 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. // <copyright>
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. // </copyright>
  4. namespace System.Runtime
  5. {
  6. using System;
  7. using System.Threading;
  8. class IOThreadCancellationTokenSource : IDisposable
  9. {
  10. static readonly Action<object> onCancel = Fx.ThunkCallback<object>(OnCancel);
  11. readonly TimeSpan timeout;
  12. CancellationTokenSource source;
  13. CancellationToken? token;
  14. IOThreadTimer timer;
  15. public IOThreadCancellationTokenSource(TimeSpan timeout)
  16. {
  17. TimeoutHelper.ThrowIfNegativeArgument(timeout);
  18. this.timeout = timeout;
  19. }
  20. public IOThreadCancellationTokenSource(int timeout)
  21. : this(TimeSpan.FromMilliseconds(timeout))
  22. {
  23. }
  24. // NOTE: this property is NOT threadsafe. Potential race condition could be caused if you are accessing it
  25. // via different threads.
  26. public CancellationToken Token
  27. {
  28. get
  29. {
  30. if (this.token == null)
  31. {
  32. if (this.timeout >= TimeoutHelper.MaxWait)
  33. {
  34. this.token = CancellationToken.None;
  35. }
  36. else
  37. {
  38. this.timer = new IOThreadTimer(onCancel, this, true);
  39. this.source = new CancellationTokenSource();
  40. this.timer.Set(this.timeout);
  41. this.token = this.source.Token;
  42. }
  43. }
  44. return this.token.Value;
  45. }
  46. }
  47. public void Dispose()
  48. {
  49. if (this.source != null)
  50. {
  51. Fx.Assert(this.timer != null, "timer should not be null.");
  52. if (this.timer.Cancel())
  53. {
  54. this.source.Dispose();
  55. this.source = null;
  56. }
  57. }
  58. }
  59. static void OnCancel(object obj)
  60. {
  61. Fx.Assert(obj != null, "obj should not be null.");
  62. IOThreadCancellationTokenSource thisPtr = (IOThreadCancellationTokenSource)obj;
  63. thisPtr.Cancel();
  64. }
  65. void Cancel()
  66. {
  67. Fx.Assert(this.source != null, "source should not be null.");
  68. this.source.Cancel();
  69. this.source.Dispose();
  70. this.source = null;
  71. }
  72. }
  73. }