CommunicationObjectManager.cs 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //-----------------------------------------------------------------------------
  4. namespace System.ServiceModel.Channels
  5. {
  6. using System.Diagnostics;
  7. using System.ServiceModel;
  8. using System.Collections.Generic;
  9. using System.Collections;
  10. internal class CommunicationObjectManager<ItemType> : LifetimeManager where ItemType : class, ICommunicationObject
  11. {
  12. bool inputClosed;
  13. Hashtable table;
  14. public CommunicationObjectManager(object mutex)
  15. : base(mutex)
  16. {
  17. this.table = new Hashtable();
  18. }
  19. public void Add(ItemType item)
  20. {
  21. bool added = false;
  22. lock (this.ThisLock)
  23. {
  24. if (this.State == LifetimeState.Opened && !this.inputClosed)
  25. {
  26. if (this.table.ContainsKey(item))
  27. return;
  28. this.table.Add(item, item);
  29. base.IncrementBusyCountWithoutLock();
  30. item.Closed += this.OnItemClosed;
  31. added = true;
  32. }
  33. }
  34. if (!added)
  35. {
  36. item.Abort();
  37. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ObjectDisposedException(this.GetType().ToString()));
  38. }
  39. }
  40. public void CloseInput()
  41. {
  42. //Abort can reenter this call as a result of
  43. //close timeout, Closing input twice is not a
  44. //FailFast case.
  45. this.inputClosed = true;
  46. }
  47. public void DecrementActivityCount()
  48. {
  49. this.DecrementBusyCount();
  50. }
  51. public void IncrementActivityCount()
  52. {
  53. this.IncrementBusyCount();
  54. }
  55. void OnItemClosed(object sender, EventArgs args)
  56. {
  57. this.Remove((ItemType)sender);
  58. }
  59. public void Remove(ItemType item)
  60. {
  61. lock (this.ThisLock)
  62. {
  63. if (!this.table.ContainsKey(item))
  64. return;
  65. this.table.Remove(item);
  66. }
  67. item.Closed -= this.OnItemClosed;
  68. base.DecrementBusyCount();
  69. }
  70. public ItemType[] ToArray()
  71. {
  72. lock (this.ThisLock)
  73. {
  74. int index = 0;
  75. ItemType[] items = new ItemType[this.table.Keys.Count];
  76. foreach (ItemType item in this.table.Keys)
  77. items[index++] = item;
  78. return items;
  79. }
  80. }
  81. }
  82. }