2009-07-11 Michael Barker <mike@middlesoft.co.uk>
[mono.git] / mcs / class / System.ServiceModel / System.ServiceModel.Channels / ReplyChannelBase.cs
1 //
2 // ReplyChannelBase.cs
3 //
4 // Author:
5 //      Atsushi Enomoto <atsushi@ximian.com>
6 //
7 // Copyright (C) 2006 Novell, Inc.  http://www.novell.com
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28 using System;
29 using System.Collections.Generic;
30 using System.IO;
31 using System.Net;
32 using System.Net.Security;
33 using System.ServiceModel;
34 using System.ServiceModel.Description;
35 using System.ServiceModel.Security;
36 using System.Threading;
37
38 namespace System.ServiceModel.Channels
39 {
40         internal abstract class ReplyChannelBase : ChannelBase, IReplyChannel
41         {
42                 public ReplyChannelBase (ChannelListenerBase listener)
43                         : base (listener)
44                 {
45                 }
46
47                 public abstract EndpointAddress LocalAddress { get; }
48
49                 protected override void OnAbort ()
50                 {
51                         OnClose (TimeSpan.Zero);
52                 }
53
54                 protected override void OnClose (TimeSpan timeout)
55                 {
56                         if (CurrentAsyncThread != null)
57                                 if (!CancelAsync (timeout))
58                                         CurrentAsyncThread.Abort ();
59                 }
60
61                 public virtual bool CancelAsync (TimeSpan timeout)
62                 {
63                         // FIXME: It should wait for the actual completion.
64                         return CurrentAsyncResult == null;
65                         //return CurrentAsyncResult == null || CurrentAsyncResult.AsyncWaitHandle.WaitOne (timeout);
66                 }
67
68                 public virtual bool TryReceiveRequest ()
69                 {
70                         RequestContext dummy;
71                         return TryReceiveRequest (DefaultReceiveTimeout, out dummy);
72                 }
73
74                 public abstract bool TryReceiveRequest (TimeSpan timeout, out RequestContext context);
75
76                 delegate bool TryReceiveDelegate (TimeSpan timeout, out RequestContext context);
77                 TryReceiveDelegate try_recv_delegate;
78
79                 protected Thread CurrentAsyncThread { get; private set; }
80                 protected IAsyncResult CurrentAsyncResult { get; private set; }
81
82                 public virtual IAsyncResult BeginTryReceiveRequest (TimeSpan timeout, AsyncCallback callback, object state)
83                 {
84                         if (CurrentAsyncResult != null)
85                                 throw new InvalidOperationException ("Another async TryReceiveRequest operation is in progress");
86                         if (try_recv_delegate == null)
87                                 try_recv_delegate = new TryReceiveDelegate (delegate (TimeSpan tout, out RequestContext ctx) {
88                                         if (CurrentAsyncResult != null)
89                                                 CurrentAsyncThread = Thread.CurrentThread;
90                                         try {
91                                                 return TryReceiveRequest (tout, out ctx);
92                                         } finally {
93                                                 CurrentAsyncResult = null;
94                                                 CurrentAsyncThread = null;
95                                         }
96                                         });
97                         RequestContext dummy;
98                         CurrentAsyncResult = try_recv_delegate.BeginInvoke (timeout, out dummy, callback, state);
99                         return CurrentAsyncResult;
100                 }
101
102                 public virtual bool EndTryReceiveRequest (IAsyncResult result)
103                 {
104                         RequestContext dummy;
105                         return EndTryReceiveRequest (result, out dummy);
106                 }
107
108                 public virtual bool EndTryReceiveRequest (IAsyncResult result, out RequestContext context)
109                 {
110                         if (try_recv_delegate == null)
111                                 throw new InvalidOperationException ("BeginTryReceiveRequest operation has not started");
112                         return try_recv_delegate.EndInvoke (out context, result);
113                 }
114
115                 public virtual bool WaitForRequest ()
116                 {
117                         return WaitForRequest (DefaultReceiveTimeout);
118                 }
119
120                 public abstract bool WaitForRequest (TimeSpan timeout);
121
122                 delegate bool WaitDelegate (TimeSpan timeout);
123                 WaitDelegate wait_delegate;
124
125                 public virtual IAsyncResult BeginWaitForRequest (TimeSpan timeout, AsyncCallback callback, object state)
126                 {
127                         if (wait_delegate == null)
128                                 wait_delegate = new WaitDelegate (WaitForRequest);
129                         return wait_delegate.BeginInvoke (timeout, callback, state);
130                 }
131
132                 public virtual bool EndWaitForRequest (IAsyncResult result)
133                 {
134                         if (wait_delegate == null)
135                                 throw new InvalidOperationException ("BeginWaitForRequest operation has not started");
136                         return wait_delegate.EndInvoke (result);
137                 }
138
139                 public virtual RequestContext ReceiveRequest ()
140                 {
141                         return ReceiveRequest (DefaultReceiveTimeout);
142                 }
143
144                 public abstract RequestContext ReceiveRequest (TimeSpan timeout);
145
146                 public virtual IAsyncResult BeginReceiveRequest (AsyncCallback callback, object state)
147                 {
148                         return BeginReceiveRequest (DefaultReceiveTimeout, callback, state);
149                 }
150
151                 Func<TimeSpan,RequestContext> recv_delegate;
152                 public virtual IAsyncResult BeginReceiveRequest (TimeSpan timeout, AsyncCallback callback, object state)
153                 {
154                         if (recv_delegate == null)
155                                 recv_delegate = new Func<TimeSpan,RequestContext> (ReceiveRequest);
156                         return recv_delegate.BeginInvoke (timeout, callback, state);
157                 }
158
159                 public virtual RequestContext EndReceiveRequest (IAsyncResult result)
160                 {
161                         if (recv_delegate == null)
162                                 throw new InvalidOperationException ("BeginReceiveRequest operation has not started");
163                         return recv_delegate.EndInvoke (result);
164                 }
165
166                 protected override IAsyncResult OnBeginOpen (TimeSpan timeout,
167                         AsyncCallback callback, object state)
168                 {
169                         throw new NotImplementedException ();
170                 }
171
172                 protected override void OnEndOpen (IAsyncResult result)
173                 {
174                         throw new NotImplementedException ();
175                 }
176
177                 [MonoTODO]
178                 protected override IAsyncResult OnBeginClose (TimeSpan timeout,
179                         AsyncCallback callback, object state)
180                 {
181                         throw new NotImplementedException ();
182                 }
183
184                 [MonoTODO]
185                 protected override void OnEndClose (IAsyncResult result)
186                 {
187                         throw new NotImplementedException ();
188                 }
189         }
190 }