//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //------------------------------------------------------------ namespace System.ServiceModel.Channels { using System.Runtime; using System.Xml; abstract class BufferedMessageData : IBufferedMessageData { ArraySegment buffer; BufferManager bufferManager; int refCount; int outstandingReaders; bool multipleUsers; RecycledMessageState messageState; SynchronizedPool messageStatePool; public BufferedMessageData(SynchronizedPool messageStatePool) { this.messageStatePool = messageStatePool; } public ArraySegment Buffer { get { return buffer; } } public BufferManager BufferManager { get { return bufferManager; } } public virtual XmlDictionaryReaderQuotas Quotas { get { return XmlDictionaryReaderQuotas.Max; } } public abstract MessageEncoder MessageEncoder { get; } object ThisLock { get { return this; } } public void EnableMultipleUsers() { multipleUsers = true; } public void Close() { if (multipleUsers) { lock (ThisLock) { if (--this.refCount == 0) { DoClose(); } } } else { DoClose(); } } void DoClose() { bufferManager.ReturnBuffer(buffer.Array); if (outstandingReaders == 0) { bufferManager = null; buffer = new ArraySegment(); OnClosed(); } } public void DoReturnMessageState(RecycledMessageState messageState) { if (this.messageState == null) { this.messageState = messageState; } else { messageStatePool.Return(messageState); } } void DoReturnXmlReader(XmlDictionaryReader reader) { ReturnXmlReader(reader); outstandingReaders--; } public RecycledMessageState DoTakeMessageState() { RecycledMessageState messageState = this.messageState; if (messageState != null) { this.messageState = null; return messageState; } else { return messageStatePool.Take(); } } XmlDictionaryReader DoTakeXmlReader() { XmlDictionaryReader reader = TakeXmlReader(); outstandingReaders++; return reader; } public XmlDictionaryReader GetMessageReader() { if (multipleUsers) { lock (ThisLock) { return DoTakeXmlReader(); } } else { return DoTakeXmlReader(); } } public void OnXmlReaderClosed(XmlDictionaryReader reader) { if (multipleUsers) { lock (ThisLock) { DoReturnXmlReader(reader); } } else { DoReturnXmlReader(reader); } } protected virtual void OnClosed() { } public RecycledMessageState TakeMessageState() { if (multipleUsers) { lock (ThisLock) { return DoTakeMessageState(); } } else { return DoTakeMessageState(); } } protected abstract XmlDictionaryReader TakeXmlReader(); public void Open() { lock (ThisLock) { this.refCount++; } } public void Open(ArraySegment buffer, BufferManager bufferManager) { this.refCount = 1; this.bufferManager = bufferManager; this.buffer = buffer; multipleUsers = false; } protected abstract void ReturnXmlReader(XmlDictionaryReader xmlReader); public void ReturnMessageState(RecycledMessageState messageState) { if (multipleUsers) { lock (ThisLock) { DoReturnMessageState(messageState); } } else { DoReturnMessageState(messageState); } } } }