|
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.ServiceModel.Channels
{
using System.Runtime;
class TransportReplyChannelAcceptor : ReplyChannelAcceptor
{
TransportManagerContainer transportManagerContainer;
TransportChannelListener listener;
public TransportReplyChannelAcceptor(TransportChannelListener listener)
: base(listener)
{
this.listener = listener;
}
protected override ReplyChannel OnCreateChannel()
{
return new TransportReplyChannel(this.ChannelManager, null);
}
protected override void OnOpening()
{
base.OnOpening();
this.transportManagerContainer = this.listener.GetTransportManagers();
this.listener = null;
}
protected override void OnAbort()
{
base.OnAbort();
if (this.transportManagerContainer != null && !TransferTransportManagers())
{
this.transportManagerContainer.Abort();
}
}
IAsyncResult DummyBeginClose(TimeSpan timeout, AsyncCallback callback, object state)
{
return new CompletedAsyncResult(callback, state);
}
void DummyEndClose(IAsyncResult result)
{
CompletedAsyncResult.End(result);
}
protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state)
{
ChainedBeginHandler begin1 = DummyBeginClose;
ChainedEndHandler end1 = DummyEndClose;
if (this.transportManagerContainer != null && !TransferTransportManagers())
{
begin1 = this.transportManagerContainer.BeginClose;
end1 = this.transportManagerContainer.EndClose;
}
return new ChainedAsyncResult(timeout, callback, state, base.OnBeginClose, base.OnEndClose, begin1, end1);
}
protected override void OnEndClose(IAsyncResult result)
{
ChainedAsyncResult.End(result);
}
protected override void OnClose(TimeSpan timeout)
{
TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
base.OnClose(timeoutHelper.RemainingTime());
if (this.transportManagerContainer != null && !TransferTransportManagers())
{
this.transportManagerContainer.Close(timeoutHelper.RemainingTime());
}
}
// used to decouple our channel and listener lifetimes
bool TransferTransportManagers()
{
TransportReplyChannel singletonChannel = (TransportReplyChannel)base.GetCurrentChannel();
if (singletonChannel == null)
{
return false;
}
else
{
return singletonChannel.TransferTransportManagers(this.transportManagerContainer);
}
}
// tracks TransportManager so that the channel can outlive the Listener
protected class TransportReplyChannel : ReplyChannel
{
TransportManagerContainer transportManagerContainer;
public TransportReplyChannel(ChannelManagerBase channelManager, EndpointAddress localAddress)
: base(channelManager, localAddress)
{
}
public bool TransferTransportManagers(TransportManagerContainer transportManagerContainer)
{
lock (ThisLock)
{
if (this.State != CommunicationState.Opened)
{
return false;
}
this.transportManagerContainer = transportManagerContainer;
return true;
}
}
protected override void OnAbort()
{
if (this.transportManagerContainer != null)
{
this.transportManagerContainer.Abort();
}
base.OnAbort();
}
protected override void OnClose(TimeSpan timeout)
{
TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
if (this.transportManagerContainer != null)
{
this.transportManagerContainer.Close(timeoutHelper.RemainingTime());
}
base.OnClose(timeoutHelper.RemainingTime());
}
IAsyncResult DummyBeginClose(TimeSpan timeout, AsyncCallback callback, object state)
{
return new CompletedAsyncResult(callback, state);
}
void DummyEndClose(IAsyncResult result)
{
CompletedAsyncResult.End(result);
}
protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state)
{
ChainedBeginHandler begin1 = DummyBeginClose;
ChainedEndHandler end1 = DummyEndClose;
if (this.transportManagerContainer != null)
{
begin1 = this.transportManagerContainer.BeginClose;
end1 = this.transportManagerContainer.EndClose;
}
return new ChainedAsyncResult(timeout, callback, state, begin1, end1,
base.OnBeginClose, base.OnEndClose);
}
protected override void OnEndClose(IAsyncResult result)
{
ChainedAsyncResult.End(result);
}
}
}
}
|