1 //------------------------------------------------------------ 2 // Copyright (c) Microsoft Corporation. All rights reserved. 3 //------------------------------------------------------------ 4 5 namespace System.ServiceModel.Channels 6 { 7 using System.Runtime; 8 9 class TransportReplyChannelAcceptor : ReplyChannelAcceptor 10 { 11 TransportManagerContainer transportManagerContainer; 12 TransportChannelListener listener; 13 TransportReplyChannelAcceptor(TransportChannelListener listener)14 public TransportReplyChannelAcceptor(TransportChannelListener listener) 15 : base(listener) 16 { 17 this.listener = listener; 18 } 19 OnCreateChannel()20 protected override ReplyChannel OnCreateChannel() 21 { 22 return new TransportReplyChannel(this.ChannelManager, null); 23 } 24 OnOpening()25 protected override void OnOpening() 26 { 27 base.OnOpening(); 28 this.transportManagerContainer = this.listener.GetTransportManagers(); 29 this.listener = null; 30 } 31 OnAbort()32 protected override void OnAbort() 33 { 34 base.OnAbort(); 35 if (this.transportManagerContainer != null && !TransferTransportManagers()) 36 { 37 this.transportManagerContainer.Abort(); 38 } 39 } 40 DummyBeginClose(TimeSpan timeout, AsyncCallback callback, object state)41 IAsyncResult DummyBeginClose(TimeSpan timeout, AsyncCallback callback, object state) 42 { 43 return new CompletedAsyncResult(callback, state); 44 } 45 DummyEndClose(IAsyncResult result)46 void DummyEndClose(IAsyncResult result) 47 { 48 CompletedAsyncResult.End(result); 49 } 50 OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state)51 protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state) 52 { 53 ChainedBeginHandler begin1 = DummyBeginClose; 54 ChainedEndHandler end1 = DummyEndClose; 55 if (this.transportManagerContainer != null && !TransferTransportManagers()) 56 { 57 begin1 = this.transportManagerContainer.BeginClose; 58 end1 = this.transportManagerContainer.EndClose; 59 } 60 61 return new ChainedAsyncResult(timeout, callback, state, base.OnBeginClose, base.OnEndClose, begin1, end1); 62 } 63 OnEndClose(IAsyncResult result)64 protected override void OnEndClose(IAsyncResult result) 65 { 66 ChainedAsyncResult.End(result); 67 } 68 OnClose(TimeSpan timeout)69 protected override void OnClose(TimeSpan timeout) 70 { 71 TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); 72 base.OnClose(timeoutHelper.RemainingTime()); 73 if (this.transportManagerContainer != null && !TransferTransportManagers()) 74 { 75 this.transportManagerContainer.Close(timeoutHelper.RemainingTime()); 76 } 77 } 78 79 // used to decouple our channel and listener lifetimes TransferTransportManagers()80 bool TransferTransportManagers() 81 { 82 TransportReplyChannel singletonChannel = (TransportReplyChannel)base.GetCurrentChannel(); 83 if (singletonChannel == null) 84 { 85 return false; 86 } 87 else 88 { 89 return singletonChannel.TransferTransportManagers(this.transportManagerContainer); 90 } 91 } 92 93 // tracks TransportManager so that the channel can outlive the Listener 94 protected class TransportReplyChannel : ReplyChannel 95 { 96 TransportManagerContainer transportManagerContainer; 97 TransportReplyChannel(ChannelManagerBase channelManager, EndpointAddress localAddress)98 public TransportReplyChannel(ChannelManagerBase channelManager, EndpointAddress localAddress) 99 : base(channelManager, localAddress) 100 { 101 } 102 TransferTransportManagers(TransportManagerContainer transportManagerContainer)103 public bool TransferTransportManagers(TransportManagerContainer transportManagerContainer) 104 { 105 lock (ThisLock) 106 { 107 if (this.State != CommunicationState.Opened) 108 { 109 return false; 110 } 111 112 this.transportManagerContainer = transportManagerContainer; 113 return true; 114 } 115 } 116 OnAbort()117 protected override void OnAbort() 118 { 119 if (this.transportManagerContainer != null) 120 { 121 this.transportManagerContainer.Abort(); 122 } 123 base.OnAbort(); 124 } 125 OnClose(TimeSpan timeout)126 protected override void OnClose(TimeSpan timeout) 127 { 128 TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); 129 if (this.transportManagerContainer != null) 130 { 131 this.transportManagerContainer.Close(timeoutHelper.RemainingTime()); 132 } 133 base.OnClose(timeoutHelper.RemainingTime()); 134 } 135 DummyBeginClose(TimeSpan timeout, AsyncCallback callback, object state)136 IAsyncResult DummyBeginClose(TimeSpan timeout, AsyncCallback callback, object state) 137 { 138 return new CompletedAsyncResult(callback, state); 139 } 140 DummyEndClose(IAsyncResult result)141 void DummyEndClose(IAsyncResult result) 142 { 143 CompletedAsyncResult.End(result); 144 } 145 OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state)146 protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state) 147 { 148 ChainedBeginHandler begin1 = DummyBeginClose; 149 ChainedEndHandler end1 = DummyEndClose; 150 if (this.transportManagerContainer != null) 151 { 152 begin1 = this.transportManagerContainer.BeginClose; 153 end1 = this.transportManagerContainer.EndClose; 154 } 155 156 return new ChainedAsyncResult(timeout, callback, state, begin1, end1, 157 base.OnBeginClose, base.OnEndClose); 158 } 159 OnEndClose(IAsyncResult result)160 protected override void OnEndClose(IAsyncResult result) 161 { 162 ChainedAsyncResult.End(result); 163 } 164 } 165 } 166 } 167