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