204 lines
4.9 KiB
C#
204 lines
4.9 KiB
C#
|
//------------------------------------------------------------
|
||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
//------------------------------------------------------------
|
||
|
namespace System.ServiceModel.Channels
|
||
|
{
|
||
|
using System.Runtime;
|
||
|
using System.Xml;
|
||
|
|
||
|
abstract class BufferedMessageData : IBufferedMessageData
|
||
|
{
|
||
|
ArraySegment<byte> buffer;
|
||
|
BufferManager bufferManager;
|
||
|
int refCount;
|
||
|
int outstandingReaders;
|
||
|
bool multipleUsers;
|
||
|
RecycledMessageState messageState;
|
||
|
SynchronizedPool<RecycledMessageState> messageStatePool;
|
||
|
|
||
|
public BufferedMessageData(SynchronizedPool<RecycledMessageState> messageStatePool)
|
||
|
{
|
||
|
this.messageStatePool = messageStatePool;
|
||
|
}
|
||
|
|
||
|
public ArraySegment<byte> 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<byte>();
|
||
|
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<byte> 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);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|