BufferedMessageData.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. //------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //------------------------------------------------------------
  4. namespace System.ServiceModel.Channels
  5. {
  6. using System.Runtime;
  7. using System.Xml;
  8. abstract class BufferedMessageData : IBufferedMessageData
  9. {
  10. ArraySegment<byte> buffer;
  11. BufferManager bufferManager;
  12. int refCount;
  13. int outstandingReaders;
  14. bool multipleUsers;
  15. RecycledMessageState messageState;
  16. SynchronizedPool<RecycledMessageState> messageStatePool;
  17. public BufferedMessageData(SynchronizedPool<RecycledMessageState> messageStatePool)
  18. {
  19. this.messageStatePool = messageStatePool;
  20. }
  21. public ArraySegment<byte> Buffer
  22. {
  23. get { return buffer; }
  24. }
  25. public BufferManager BufferManager
  26. {
  27. get { return bufferManager; }
  28. }
  29. public virtual XmlDictionaryReaderQuotas Quotas
  30. {
  31. get { return XmlDictionaryReaderQuotas.Max; }
  32. }
  33. public abstract MessageEncoder MessageEncoder { get; }
  34. object ThisLock
  35. {
  36. get { return this; }
  37. }
  38. public void EnableMultipleUsers()
  39. {
  40. multipleUsers = true;
  41. }
  42. public void Close()
  43. {
  44. if (multipleUsers)
  45. {
  46. lock (ThisLock)
  47. {
  48. if (--this.refCount == 0)
  49. {
  50. DoClose();
  51. }
  52. }
  53. }
  54. else
  55. {
  56. DoClose();
  57. }
  58. }
  59. void DoClose()
  60. {
  61. bufferManager.ReturnBuffer(buffer.Array);
  62. if (outstandingReaders == 0)
  63. {
  64. bufferManager = null;
  65. buffer = new ArraySegment<byte>();
  66. OnClosed();
  67. }
  68. }
  69. public void DoReturnMessageState(RecycledMessageState messageState)
  70. {
  71. if (this.messageState == null)
  72. {
  73. this.messageState = messageState;
  74. }
  75. else
  76. {
  77. messageStatePool.Return(messageState);
  78. }
  79. }
  80. void DoReturnXmlReader(XmlDictionaryReader reader)
  81. {
  82. ReturnXmlReader(reader);
  83. outstandingReaders--;
  84. }
  85. public RecycledMessageState DoTakeMessageState()
  86. {
  87. RecycledMessageState messageState = this.messageState;
  88. if (messageState != null)
  89. {
  90. this.messageState = null;
  91. return messageState;
  92. }
  93. else
  94. {
  95. return messageStatePool.Take();
  96. }
  97. }
  98. XmlDictionaryReader DoTakeXmlReader()
  99. {
  100. XmlDictionaryReader reader = TakeXmlReader();
  101. outstandingReaders++;
  102. return reader;
  103. }
  104. public XmlDictionaryReader GetMessageReader()
  105. {
  106. if (multipleUsers)
  107. {
  108. lock (ThisLock)
  109. {
  110. return DoTakeXmlReader();
  111. }
  112. }
  113. else
  114. {
  115. return DoTakeXmlReader();
  116. }
  117. }
  118. public void OnXmlReaderClosed(XmlDictionaryReader reader)
  119. {
  120. if (multipleUsers)
  121. {
  122. lock (ThisLock)
  123. {
  124. DoReturnXmlReader(reader);
  125. }
  126. }
  127. else
  128. {
  129. DoReturnXmlReader(reader);
  130. }
  131. }
  132. protected virtual void OnClosed()
  133. {
  134. }
  135. public RecycledMessageState TakeMessageState()
  136. {
  137. if (multipleUsers)
  138. {
  139. lock (ThisLock)
  140. {
  141. return DoTakeMessageState();
  142. }
  143. }
  144. else
  145. {
  146. return DoTakeMessageState();
  147. }
  148. }
  149. protected abstract XmlDictionaryReader TakeXmlReader();
  150. public void Open()
  151. {
  152. lock (ThisLock)
  153. {
  154. this.refCount++;
  155. }
  156. }
  157. public void Open(ArraySegment<byte> buffer, BufferManager bufferManager)
  158. {
  159. this.refCount = 1;
  160. this.bufferManager = bufferManager;
  161. this.buffer = buffer;
  162. multipleUsers = false;
  163. }
  164. protected abstract void ReturnXmlReader(XmlDictionaryReader xmlReader);
  165. public void ReturnMessageState(RecycledMessageState messageState)
  166. {
  167. if (multipleUsers)
  168. {
  169. lock (ThisLock)
  170. {
  171. DoReturnMessageState(messageState);
  172. }
  173. }
  174. else
  175. {
  176. DoReturnMessageState(messageState);
  177. }
  178. }
  179. }
  180. }