Update Reference Sources to .NET Framework 4.6
[mono.git] / mcs / class / referencesource / System.ServiceModel / System / ServiceModel / Dispatcher / ErrorHandlingAcceptor.cs
1 //-----------------------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //-----------------------------------------------------------------------------
4
5 namespace System.ServiceModel.Dispatcher
6 {
7     using System;
8     using System.Runtime;
9     using System.ServiceModel;
10
11     class ErrorHandlingAcceptor
12     {
13         readonly ChannelDispatcher dispatcher;
14         readonly IListenerBinder binder;
15
16         internal ErrorHandlingAcceptor(IListenerBinder binder, ChannelDispatcher dispatcher)
17         {
18             if (binder == null)
19             {
20                 Fx.Assert("binder is null");
21             }
22             if (dispatcher == null)
23             {
24                 Fx.Assert("dispatcher is null");
25             }
26
27             this.binder = binder;
28             this.dispatcher = dispatcher;
29         }
30
31         internal void Close()
32         {
33             try
34             {
35                 this.binder.Listener.Close();
36             }
37             catch (Exception e)
38             {
39                 if (Fx.IsFatal(e))
40                 {
41                     throw;
42                 }
43                 this.HandleError(e);
44             }
45         }
46
47         void HandleError(Exception e)
48         {
49             if (this.dispatcher != null)
50             {
51                 this.dispatcher.HandleError(e);
52             }
53         }
54
55         void HandleErrorOrAbort(Exception e)
56         {
57             if ((this.dispatcher == null) || !this.dispatcher.HandleError(e))
58             {
59                 // We only stop if the listener faults.  It is a 
60
61
62             }
63         }
64
65         internal bool TryAccept(TimeSpan timeout, out IChannelBinder channelBinder)
66         {
67             try
68             {
69                 channelBinder = this.binder.Accept(timeout);
70                 if (channelBinder != null)
71                 {
72                     this.dispatcher.PendingChannels.Add(channelBinder.Channel);
73                 }
74                 return true;
75             }
76             catch (CommunicationObjectAbortedException)
77             {
78                 channelBinder = null;
79                 return true;
80             }
81             catch (CommunicationObjectFaultedException)
82             {
83                 channelBinder = null;
84                 return true;
85             }
86             catch (TimeoutException)
87             {
88                 channelBinder = null;
89                 return false;
90             }
91             catch (CommunicationException e)
92             {
93                 this.HandleError(e);
94                 channelBinder = null;
95                 return false;
96             }
97             catch (Exception e)
98             {
99                 if (Fx.IsFatal(e))
100                 {
101                     throw;
102                 }
103                 this.HandleErrorOrAbort(e);
104                 channelBinder = null;
105                 return false;
106             }
107         }
108
109         internal IAsyncResult BeginTryAccept(TimeSpan timeout, AsyncCallback callback, object state)
110         {
111             try
112             {
113                 return this.binder.BeginAccept(timeout, callback, state);
114             }
115             catch (CommunicationObjectAbortedException)
116             {
117                 return new ErrorHandlingCompletedAsyncResult(true, callback, state);
118             }
119             catch (CommunicationObjectFaultedException)
120             {
121                 return new ErrorHandlingCompletedAsyncResult(true, callback, state);
122             }
123             catch (TimeoutException)
124             {
125                 return new ErrorHandlingCompletedAsyncResult(false, callback, state);
126             }
127             catch (CommunicationException e)
128             {
129                 this.HandleError(e);
130                 return new ErrorHandlingCompletedAsyncResult(false, callback, state);
131             }
132             catch (Exception e)
133             {
134                 if (Fx.IsFatal(e))
135                 {
136                     throw;
137                 }
138                 this.HandleErrorOrAbort(e);
139                 return new ErrorHandlingCompletedAsyncResult(false, callback, state);
140             }
141         }
142
143         internal bool EndTryAccept(IAsyncResult result, out IChannelBinder channelBinder)
144         {
145             ErrorHandlingCompletedAsyncResult handlerResult = result as ErrorHandlingCompletedAsyncResult;
146             if (handlerResult != null)
147             {
148                 channelBinder = null;
149                 return ErrorHandlingCompletedAsyncResult.End(handlerResult);
150             }
151             else
152             {
153                 try
154                 {
155                     channelBinder = this.binder.EndAccept(result);
156                     if (channelBinder != null)
157                     {
158                         this.dispatcher.PendingChannels.Add(channelBinder.Channel);
159                     }
160                     return true;
161                 }
162                 catch (CommunicationObjectAbortedException)
163                 {
164                     channelBinder = null;
165                     return true;
166                 }
167                 catch (CommunicationObjectFaultedException)
168                 {
169                     channelBinder = null;
170                     return true;
171                 }
172                 catch (TimeoutException)
173                 {
174                     channelBinder = null;
175                     return false;
176                 }
177                 catch (CommunicationException e)
178                 {
179                     this.HandleError(e);
180                     channelBinder = null;
181                     return false;
182                 }
183                 catch (Exception e)
184                 {
185                     if (Fx.IsFatal(e))
186                     {
187                         throw;
188                     }
189                     this.HandleErrorOrAbort(e);
190                     channelBinder = null;
191                     return false;
192                 }
193             }
194         }
195
196         internal void WaitForChannel()
197         {
198             try
199             {
200                 this.binder.Listener.WaitForChannel(TimeSpan.MaxValue);
201             }
202             catch (CommunicationObjectAbortedException) { }
203             catch (CommunicationObjectFaultedException) { }
204             catch (CommunicationException e)
205             {
206                 this.HandleError(e);
207             }
208             catch (Exception e)
209             {
210                 if (Fx.IsFatal(e))
211                 {
212                     throw;
213                 }
214                 this.HandleErrorOrAbort(e);
215             }
216         }
217
218         internal IAsyncResult BeginWaitForChannel(AsyncCallback callback, object state)
219         {
220             try
221             {
222                 return this.binder.Listener.BeginWaitForChannel(TimeSpan.MaxValue, callback, state);
223             }
224             catch (CommunicationObjectAbortedException)
225             {
226                 return new WaitCompletedAsyncResult(callback, state);
227             }
228             catch (CommunicationObjectFaultedException)
229             {
230                 return new WaitCompletedAsyncResult(callback, state);
231             }
232             catch (CommunicationException e)
233             {
234                 this.HandleError(e);
235                 return new WaitCompletedAsyncResult(callback, state);
236             }
237             catch (Exception e)
238             {
239                 if (Fx.IsFatal(e))
240                 {
241                     throw;
242                 }
243                 this.HandleErrorOrAbort(e);
244                 return new WaitCompletedAsyncResult(callback, state);
245             }
246         }
247
248         internal void EndWaitForChannel(IAsyncResult result)
249         {
250             WaitCompletedAsyncResult handlerResult = result as WaitCompletedAsyncResult;
251             if (handlerResult != null)
252             {
253                 WaitCompletedAsyncResult.End(handlerResult);
254             }
255             else
256             {
257                 try
258                 {
259                     this.binder.Listener.EndWaitForChannel(result);
260                 }
261                 catch (CommunicationObjectAbortedException) { }
262                 catch (CommunicationObjectFaultedException) { }
263                 catch (CommunicationException e)
264                 {
265                     this.HandleError(e);
266                 }
267                 catch (Exception e)
268                 {
269                     if (Fx.IsFatal(e))
270                     {
271                         throw;
272                     }
273                     this.HandleErrorOrAbort(e);
274                 }
275             }
276         }
277
278         class ErrorHandlingCompletedAsyncResult : CompletedAsyncResult<bool>
279         {
280             internal ErrorHandlingCompletedAsyncResult(bool data, AsyncCallback callback, object state)
281                 : base(data, callback, state)
282             {
283             }
284         }
285
286         class WaitCompletedAsyncResult : CompletedAsyncResult
287         {
288             internal WaitCompletedAsyncResult(AsyncCallback callback, object state)
289                 : base(callback, state)
290             {
291             }
292         }
293     }
294 }