2 // CommunicationObject.cs
5 // Atsushi Enomoto <atsushi@ximian.com>
7 // Copyright (C) 2005 Novell, Inc. http://www.novell.com
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:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
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.
29 using System.ServiceModel;
30 using System.Threading;
32 namespace System.ServiceModel.Channels
34 public abstract class CommunicationObject : ICommunicationObject
37 CommunicationState state = CommunicationState.Created;
38 TimeSpan default_open_timeout = TimeSpan.FromMinutes (1), default_close_timeout = TimeSpan.FromMinutes (1);
39 bool aborted, on_closed_called;
41 protected CommunicationObject ()
42 : this (new object ())
46 protected CommunicationObject (object mutex)
53 public event EventHandler Closed;
55 public event EventHandler Closing;
57 public event EventHandler Faulted;
59 public event EventHandler Opened;
61 public event EventHandler Opening;
67 public CommunicationState State {
71 protected bool IsDisposed {
72 get { return state == CommunicationState.Closed; }
75 protected object ThisLock {
79 protected internal abstract TimeSpan DefaultCloseTimeout { get; }
81 protected internal abstract TimeSpan DefaultOpenTimeout { get; }
89 if (State != CommunicationState.Closed) {
96 protected void Fault ()
98 state = CommunicationState.Faulted;
102 public IAsyncResult BeginClose (AsyncCallback callback,
105 return BeginClose (default_close_timeout, callback, state);
108 public IAsyncResult BeginClose (TimeSpan timeout,
109 AsyncCallback callback, object state)
111 if (State == CommunicationState.Created)
112 return new EventHandler (delegate { Abort (); }).BeginInvoke (null, null, callback, state);
114 return OnBeginClose (timeout, callback, state);
117 public IAsyncResult BeginOpen (AsyncCallback callback,
120 return BeginOpen (default_open_timeout, callback, state);
123 public IAsyncResult BeginOpen (TimeSpan timeout,
124 AsyncCallback callback, object state)
127 return OnBeginOpen (timeout, callback, state);
132 Close (default_close_timeout);
135 public void Close (TimeSpan timeout)
137 if (State == CommunicationState.Created)
146 public void EndClose (IAsyncResult result)
148 if (State == CommunicationState.Created || State == CommunicationState.Closed) {
149 if (!result.IsCompleted)
150 result.AsyncWaitHandle.WaitOne ();
157 public void EndOpen (IAsyncResult result)
165 Open (default_open_timeout);
168 public void Open (TimeSpan timeout)
175 protected abstract void OnAbort ();
177 protected abstract IAsyncResult OnBeginClose (TimeSpan timeout,
178 AsyncCallback callback, object state);
180 protected abstract IAsyncResult OnBeginOpen (TimeSpan timeout,
181 AsyncCallback callback, object state);
183 protected abstract void OnClose (TimeSpan timeout);
185 void ProcessClosing ()
187 if (State == CommunicationState.Faulted)
188 throw new CommunicationObjectFaultedException ();
189 state = CommunicationState.Closing;
193 protected virtual void OnClosing ()
195 // This means, if this method is overriden, then
196 // Opening event is surpressed.
198 Closing (this, new EventArgs ());
201 void ProcessClosed ()
203 state = CommunicationState.Closed;
204 on_closed_called = false;
206 if (!on_closed_called)
207 throw new InvalidOperationException ("OnClosed method is implemented but it did not call its base OnClosed method");
210 protected virtual void OnClosed ()
212 // This means, if this method is overriden, then
213 // Closed event is surpressed.
215 Closed (this, new EventArgs ());
216 on_closed_called = true;
219 protected abstract void OnEndClose (IAsyncResult result);
221 protected abstract void OnEndOpen (IAsyncResult result);
224 protected virtual void OnFaulted ()
226 // This means, if this method is overriden, then
227 // Opened event is surpressed.
229 Faulted (this, new EventArgs ());
232 protected abstract void OnOpen (TimeSpan timeout);
234 void ProcessOpened ()
236 state = CommunicationState.Opened;
240 protected virtual void OnOpened ()
242 // This means, if this method is overriden, then
243 // Opened event is surpressed.
245 Opened (this, new EventArgs ());
248 void ProcessOpening ()
250 ThrowIfDisposedOrImmutable ();
251 state = CommunicationState.Opening;
255 protected virtual void OnOpening ()
257 // This means, if this method is overriden, then
258 // Opening event is surpressed.
260 Opening (this, new EventArgs ());
263 protected void ThrowIfDisposed ()
266 throw new ObjectDisposedException (String.Format ("This communication object {0} is already disposed.", GetCommunicationObjectType ()));
269 protected void ThrowIfDisposedOrNotOpen ()
272 if (State == CommunicationState.Faulted)
273 throw new CommunicationObjectFaultedException ();
274 if (State != CommunicationState.Opened)
275 throw new InvalidOperationException (String.Format ("The communication object {0} must be at opened state.", GetCommunicationObjectType ()));
278 protected void ThrowIfDisposedOrImmutable ()
281 // hmm, according to msdn, Closing is OK here.
283 case CommunicationState.Faulted:
284 throw new CommunicationObjectFaultedException ();
285 case CommunicationState.Opening:
286 case CommunicationState.Opened:
287 throw new InvalidOperationException (String.Format ("The communication object {0} is not at created state.", GetType ()));
291 protected virtual Type GetCommunicationObjectType ()
299 class SimpleAsyncResult : IAsyncResult
301 CommunicationState comm_state;
304 public SimpleAsyncResult (
305 CommunicationState communicationState,
306 TimeSpan timeout, AsyncCallback callback,
309 comm_state = communicationState;
310 async_state = asyncState;
313 public object AsyncState {
314 get { return async_state; }
318 public WaitHandle AsyncWaitHandle {
319 get { throw new NotImplementedException (); }
323 public bool CompletedSynchronously {
324 get { throw new NotImplementedException (); }
328 public bool IsCompleted {
329 get { throw new NotImplementedException (); }