View | Details | Raw Unified | Return to bug 693366
Collapse All | Expand All

(-)a/mcs/class/System.ServiceModel/System.ServiceModel.Channels/CommunicationObject.cs (-42 / +72 lines)
Lines 36-43 namespace System.ServiceModel.Channels Link Here
36
	{
36
	{
37
		object mutex;
37
		object mutex;
38
		CommunicationState state = CommunicationState.Created;
38
		CommunicationState state = CommunicationState.Created;
39
		TimeSpan default_open_timeout = TimeSpan.FromMinutes (1), default_close_timeout = TimeSpan.FromMinutes (1);
40
		bool aborted;
39
		bool aborted;
40
		bool closing;
41
41
42
		protected CommunicationObject ()
42
		protected CommunicationObject ()
43
			: this (new object ())
43
			: this (new object ())
Lines 87-96 namespace System.ServiceModel.Channels Link Here
87
87
88
		public void Abort ()
88
		public void Abort ()
89
		{
89
		{
90
			if (State != CommunicationState.Closed) {
90
			if (aborted || (state == CommunicationState.Closed) || (state == CommunicationState.Closing))
91
				OnAbort ();
91
				return;
92
				ProcessClosed ();
92
93
			// note: an explicit call to Abort is a bit different from an internal abort
94
			aborted = true;
95
96
			if (!closing) {
97
				try {
98
					ProcessClosing ();
99
				}
100
				catch {
101
					ProcessClosed ();
102
					throw;
103
				}
93
			}
104
			}
105
106
			OnAbort ();
107
			ProcessClosed ();
94
		}
108
		}
95
109
96
		protected void Fault ()
110
		protected void Fault ()
Lines 101-107 namespace System.ServiceModel.Channels Link Here
101
		public IAsyncResult BeginClose (AsyncCallback callback,
115
		public IAsyncResult BeginClose (AsyncCallback callback,
102
			object state)
116
			object state)
103
		{
117
		{
104
			return BeginClose (default_close_timeout, callback, state);
118
			return BeginClose (DefaultCloseTimeout, callback, state);
105
		}
119
		}
106
120
107
		public IAsyncResult BeginClose (TimeSpan timeout,
121
		public IAsyncResult BeginClose (TimeSpan timeout,
Lines 116-122 namespace System.ServiceModel.Channels Link Here
116
		public IAsyncResult BeginOpen (AsyncCallback callback,
130
		public IAsyncResult BeginOpen (AsyncCallback callback,
117
			object state)
131
			object state)
118
		{
132
		{
119
			return BeginOpen (default_open_timeout, callback, state);
133
			return BeginOpen (DefaultOpenTimeout, callback, state);
120
		}
134
		}
121
135
122
		public IAsyncResult BeginOpen (TimeSpan timeout,
136
		public IAsyncResult BeginOpen (TimeSpan timeout,
Lines 128-145 namespace System.ServiceModel.Channels Link Here
128
142
129
		public void Close ()
143
		public void Close ()
130
		{
144
		{
131
			Close (default_close_timeout);
145
			Close (DefaultCloseTimeout);
132
		}
146
		}
133
147
134
		public void Close (TimeSpan timeout)
148
		public void Close (TimeSpan timeout)
135
		{
149
		{
136
			if (State == CommunicationState.Created)
150
			CommunicationState s = State;
137
				Abort ();
151
			if ((s == CommunicationState.Closed) || (s == CommunicationState.Closing))
138
			else {
152
				return;
139
				ProcessClosing ();
153
154
			bool fault = s == CommunicationState.Faulted;
155
156
			ProcessClosing ();
157
158
			if (fault || s == CommunicationState.Created)
159
				OnAbort ();
160
			else
140
				OnClose (timeout);
161
				OnClose (timeout);
141
				ProcessClosed ();
162
142
			}
163
			ProcessClosed ();
164
165
			if (fault)
166
				throw new CommunicationObjectFaultedException ();
143
		}
167
		}
144
168
145
		public void EndClose (IAsyncResult result)
169
		public void EndClose (IAsyncResult result)
Lines 161-167 namespace System.ServiceModel.Channels Link Here
161
185
162
		public void Open ()
186
		public void Open ()
163
		{
187
		{
164
			Open (default_open_timeout);
188
			Open (DefaultOpenTimeout);
165
		}
189
		}
166
190
167
		public void Open (TimeSpan timeout)
191
		public void Open (TimeSpan timeout)
Lines 184-192 namespace System.ServiceModel.Channels Link Here
184
		void ProcessClosing ()
208
		void ProcessClosing ()
185
		{
209
		{
186
			lock (ThisLock) {
210
			lock (ThisLock) {
187
				if (State == CommunicationState.Faulted)
211
				closing = true;
188
					throw new CommunicationObjectFaultedException ();
212
				if (state != CommunicationState.Closing)
189
				OnClosing ();
213
					OnClosing ();
190
				if (state != CommunicationState.Closing) {
214
				if (state != CommunicationState.Closing) {
191
					state = CommunicationState.Faulted;
215
					state = CommunicationState.Faulted;
192
					throw new InvalidOperationException (String.Format ("Communication object {0} has an overriden OnClosing method that does not call base OnClosing method (declared in {1} type).", this.GetType (), GetType ().GetMethod ("OnClosing", BindingFlags.NonPublic | BindingFlags.Instance).DeclaringType));
216
					throw new InvalidOperationException (String.Format ("Communication object {0} has an overriden OnClosing method that does not call base OnClosing method (declared in {1} type).", this.GetType (), GetType ().GetMethod ("OnClosing", BindingFlags.NonPublic | BindingFlags.Instance).DeclaringType));
Lines 199-212 namespace System.ServiceModel.Channels Link Here
199
			state = CommunicationState.Closing;
223
			state = CommunicationState.Closing;
200
			// This means, if this method is overriden, then
224
			// This means, if this method is overriden, then
201
			// Opening event is surpressed.
225
			// Opening event is surpressed.
202
			if (Closing != null)
226
			EventHandler handler = Closing;
203
				Closing (this, new EventArgs ());
227
			if (handler != null)
228
				handler (this, EventArgs.Empty);
204
		}
229
		}
205
230
206
		void ProcessClosed ()
231
		void ProcessClosed ()
207
		{
232
		{
208
			lock (ThisLock) {
233
			lock (ThisLock) {
209
				OnClosed ();
234
				if (state != CommunicationState.Closed)
235
					OnClosed ();
210
				if (state != CommunicationState.Closed) {
236
				if (state != CommunicationState.Closed) {
211
					state = CommunicationState.Faulted;
237
					state = CommunicationState.Faulted;
212
					throw new InvalidOperationException (String.Format ("Communication object {0} has an overriden OnClosed method that does not call base OnClosed method (declared in {1} type).", this.GetType (), GetType ().GetMethod ("OnClosed", BindingFlags.NonPublic | BindingFlags.Instance).DeclaringType));
238
					throw new InvalidOperationException (String.Format ("Communication object {0} has an overriden OnClosed method that does not call base OnClosed method (declared in {1} type).", this.GetType (), GetType ().GetMethod ("OnClosed", BindingFlags.NonPublic | BindingFlags.Instance).DeclaringType));
Lines 219-226 namespace System.ServiceModel.Channels Link Here
219
			state = CommunicationState.Closed;
245
			state = CommunicationState.Closed;
220
			// This means, if this method is overriden, then
246
			// This means, if this method is overriden, then
221
			// Closed event is surpressed.
247
			// Closed event is surpressed.
222
			if (Closed != null)
248
			EventHandler handler = Closed;
223
				Closed (this, new EventArgs ());
249
			if (handler != null)
250
				handler (this, EventArgs.Empty);
224
		}
251
		}
225
252
226
		protected abstract void OnEndClose (IAsyncResult result);
253
		protected abstract void OnEndClose (IAsyncResult result);
Lines 230-237 namespace System.ServiceModel.Channels Link Here
230
		void ProcessFaulted ()
257
		void ProcessFaulted ()
231
		{
258
		{
232
			lock (ThisLock) {
259
			lock (ThisLock) {
233
				if (State == CommunicationState.Faulted)
260
				// as documented: Fault does nothing if state is already Faulted or when Closed
234
					throw new CommunicationObjectFaultedException ();
261
				if (state == CommunicationState.Faulted || state == CommunicationState.Closed)
262
					return;
263
264
				// note: Faulted is already set when OnFaulted is called
265
				state = CommunicationState.Faulted;
235
				OnFaulted ();
266
				OnFaulted ();
236
				if (state != CommunicationState.Faulted) {
267
				if (state != CommunicationState.Faulted) {
237
					state = CommunicationState.Faulted; // FIXME: am not sure if this makes sense ...
268
					state = CommunicationState.Faulted; // FIXME: am not sure if this makes sense ...
Lines 242-252 namespace System.ServiceModel.Channels Link Here
242
273
243
		protected virtual void OnFaulted ()
274
		protected virtual void OnFaulted ()
244
		{
275
		{
245
			state = CommunicationState.Faulted;
246
			// This means, if this method is overriden, then
276
			// This means, if this method is overriden, then
247
			// Faulted event is surpressed.
277
			// Faulted event is surpressed.
248
			if (Faulted != null)
278
			EventHandler handler = Faulted;
249
				Faulted (this, new EventArgs ());
279
			if (handler != null)
280
				handler (this, EventArgs.Empty);
250
		}
281
		}
251
282
252
		protected abstract void OnOpen (TimeSpan timeout);
283
		protected abstract void OnOpen (TimeSpan timeout);
Lines 265-272 namespace System.ServiceModel.Channels Link Here
265
		protected virtual void OnOpened ()
296
		protected virtual void OnOpened ()
266
		{
297
		{
267
			state = CommunicationState.Opened;
298
			state = CommunicationState.Opened;
268
			if (Opened != null)
299
			EventHandler handler = Opened;
269
				Opened (this, new EventArgs ());
300
			if (handler != null)
301
				handler (this, EventArgs.Empty);
270
		}
302
		}
271
303
272
		void ProcessOpening ()
304
		void ProcessOpening ()
Lines 286-306 namespace System.ServiceModel.Channels Link Here
286
			state = CommunicationState.Opening;
318
			state = CommunicationState.Opening;
287
			// This means, if this method is overriden, then
319
			// This means, if this method is overriden, then
288
			// Opening event is surpressed.
320
			// Opening event is surpressed.
289
			if (Opening != null)
321
			EventHandler handler = Opening;
290
				Opening (this, new EventArgs ());
322
			if (handler != null)
323
				handler (this, EventArgs.Empty);
291
		}
324
		}
292
325
293
		protected void ThrowIfDisposed ()
326
		protected void ThrowIfDisposed ()
294
		{
327
		{
295
			if (IsDisposed)
328
			if (aborted)
296
				throw new ObjectDisposedException (String.Format ("This communication object {0} is already disposed.", GetCommunicationObjectType ()));
329
				throw new CommunicationObjectAbortedException ();
330
			if (state == CommunicationState.Faulted)
331
				throw new CommunicationObjectFaultedException ();
332
			// IsDisposed can be false and still we need to throw ObjectDisposedException
333
			if ((state == CommunicationState.Closing) || (state == CommunicationState.Closed))
334
				throw new ObjectDisposedException (String.Format ("This communication object {0} is already disposed (state {1}).", GetCommunicationObjectType (), State));
297
		}
335
		}
298
336
299
		protected void ThrowIfDisposedOrNotOpen ()
337
		protected void ThrowIfDisposedOrNotOpen ()
300
		{
338
		{
301
			ThrowIfDisposed ();
339
			ThrowIfDisposed ();
302
			if (State == CommunicationState.Faulted)
303
				throw new CommunicationObjectFaultedException ();
304
			if (State != CommunicationState.Opened)
340
			if (State != CommunicationState.Opened)
305
				throw new InvalidOperationException (String.Format ("The communication object {0} must be at opened state.", GetCommunicationObjectType ()));
341
				throw new InvalidOperationException (String.Format ("The communication object {0} must be at opened state.", GetCommunicationObjectType ()));
306
		}
342
		}
Lines 308-321 namespace System.ServiceModel.Channels Link Here
308
		protected void ThrowIfDisposedOrImmutable ()
344
		protected void ThrowIfDisposedOrImmutable ()
309
		{
345
		{
310
			ThrowIfDisposed ();
346
			ThrowIfDisposed ();
311
			// hmm, according to msdn, Closing is OK here.
347
			if ((state == CommunicationState.Opening) || (state == CommunicationState.Opened))
312
			switch (State) {
313
			case CommunicationState.Faulted:
314
				throw new CommunicationObjectFaultedException ();
315
			case CommunicationState.Opening:
316
			case CommunicationState.Opened:
317
				throw new InvalidOperationException (String.Format ("The communication object {0} is not at created state but at {1} state.", GetType (), State));
348
				throw new InvalidOperationException (String.Format ("The communication object {0} is not at created state but at {1} state.", GetType (), State));
318
			}
319
		}
349
		}
320
350
321
		protected virtual Type GetCommunicationObjectType ()
351
		protected virtual Type GetCommunicationObjectType ()
(-)a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/CommunicationObjectSyncTest.cs (-95 lines)
Lines 168-178 namespace MoonTest.ServiceModel { Link Here
168
		}
168
		}
169
169
170
		[TestMethod]
170
		[TestMethod]
171
#if NET_2_1
172
		[MoonlightBug]
173
#else
174
		[NUnit.Framework.Ignore]
175
#endif
176
		public void Create_Abort ()
171
		public void Create_Abort ()
177
		{
172
		{
178
			int closing = 0;
173
			int closing = 0;
Lines 237-247 namespace MoonTest.ServiceModel { Link Here
237
		}
232
		}
238
233
239
		[TestMethod]
234
		[TestMethod]
240
#if NET_2_1
241
		[MoonlightBug]
242
#else
243
		[NUnit.Framework.Ignore]
244
#endif
245
		public void Create_Close ()
235
		public void Create_Close ()
246
		{
236
		{
247
			int opening = 0;
237
			int opening = 0;
Lines 340-350 namespace MoonTest.ServiceModel { Link Here
340
		}
330
		}
341
331
342
		[TestMethod]
332
		[TestMethod]
343
#if NET_2_1
344
		[MoonlightBug]
345
#else
346
		[NUnit.Framework.Ignore]
347
#endif
348
		public void Create_Close_Fault ()
333
		public void Create_Close_Fault ()
349
		{
334
		{
350
			bool faulted = false;
335
			bool faulted = false;
Lines 361-371 namespace MoonTest.ServiceModel { Link Here
361
		}
346
		}
362
347
363
		[TestMethod]
348
		[TestMethod]
364
#if NET_2_1
365
		[MoonlightBug]
366
#else
367
		[NUnit.Framework.Ignore]
368
#endif
369
		public void Create_Open_Close_Abort ()
349
		public void Create_Open_Close_Abort ()
370
		{
350
		{
371
			int opening = 0;
351
			int opening = 0;
Lines 453-463 namespace MoonTest.ServiceModel { Link Here
453
		}
433
		}
454
434
455
		[TestMethod]
435
		[TestMethod]
456
#if NET_2_1
457
		[MoonlightBug]
458
#else
459
		[NUnit.Framework.Ignore]
460
#endif
461
		public void Create_Fault_Abort ()
436
		public void Create_Fault_Abort ()
462
		{
437
		{
463
			int opening = 0;
438
			int opening = 0;
Lines 546-556 namespace MoonTest.ServiceModel { Link Here
546
		}
521
		}
547
522
548
		[TestMethod]
523
		[TestMethod]
549
#if NET_2_1
550
		[MoonlightBug]
551
#else
552
		[NUnit.Framework.Ignore]
553
#endif
554
		public void Create_Fault_Open_Close ()
524
		public void Create_Fault_Open_Close ()
555
		{
525
		{
556
			int opening = 0;
526
			int opening = 0;
Lines 641-651 namespace MoonTest.ServiceModel { Link Here
641
		}
611
		}
642
612
643
		[TestMethod]
613
		[TestMethod]
644
#if NET_2_1
645
		[MoonlightBug]
646
#else
647
		[NUnit.Framework.Ignore]
648
#endif
649
		public void Create_Fault_Open_Abort_Close ()
614
		public void Create_Fault_Open_Abort_Close ()
650
		{
615
		{
651
			int opening = 0;
616
			int opening = 0;
Lines 733-743 namespace MoonTest.ServiceModel { Link Here
733
		}
698
		}
734
699
735
		[TestMethod]
700
		[TestMethod]
736
#if NET_2_1
737
		[MoonlightBug]
738
#else
739
		[NUnit.Framework.Ignore]
740
#endif
741
		public void Create_Open_Open ()
701
		public void Create_Open_Open ()
742
		{
702
		{
743
			int opening = 0;
703
			int opening = 0;
Lines 777-787 namespace MoonTest.ServiceModel { Link Here
777
		// ThrowIfDisposed throws an exception if the state is Closing, Closed or Faulted.
737
		// ThrowIfDisposed throws an exception if the state is Closing, Closed or Faulted.
778
738
779
		[TestMethod]
739
		[TestMethod]
780
#if NET_2_1
781
		[MoonlightBug]
782
#else
783
		[NUnit.Framework.Ignore]
784
#endif
785
		public void ThrowIfDisposed_Open_Close ()
740
		public void ThrowIfDisposed_Open_Close ()
786
		{
741
		{
787
			bool opening = false;
742
			bool opening = false;
Lines 843-853 namespace MoonTest.ServiceModel { Link Here
843
798
844
799
845
		[TestMethod]
800
		[TestMethod]
846
#if NET_2_1
847
		[MoonlightBug]
848
#else
849
		[NUnit.Framework.Ignore]
850
#endif
851
		public void ThrowIfDisposed_Fault_Abort ()
801
		public void ThrowIfDisposed_Fault_Abort ()
852
		{
802
		{
853
			bool opening = false;
803
			bool opening = false;
Lines 910-920 namespace MoonTest.ServiceModel { Link Here
910
		// ThrowIfDisposedOrImmutable throws an exception if the state is not Created.
860
		// ThrowIfDisposedOrImmutable throws an exception if the state is not Created.
911
861
912
		[TestMethod]
862
		[TestMethod]
913
#if NET_2_1
914
		[MoonlightBug]
915
#else
916
		[NUnit.Framework.Ignore]
917
#endif
918
		public void ThrowIfDisposedOrImmutable_Open_Close ()
863
		public void ThrowIfDisposedOrImmutable_Open_Close ()
919
		{
864
		{
920
			bool opening = false;
865
			bool opening = false;
Lines 979-989 namespace MoonTest.ServiceModel { Link Here
979
		}
924
		}
980
925
981
		[TestMethod]
926
		[TestMethod]
982
#if NET_2_1
983
		[MoonlightBug]
984
#else
985
		[NUnit.Framework.Ignore]
986
#endif
987
		public void ThrowIfDisposedOrImmutable_Fault_Abort ()
927
		public void ThrowIfDisposedOrImmutable_Fault_Abort ()
988
		{
928
		{
989
			bool opening = false;
929
			bool opening = false;
Lines 1050-1060 namespace MoonTest.ServiceModel { Link Here
1050
		// ThrowIfDisposedOrNotOpen throws an exception if the state is not Opened. 
990
		// ThrowIfDisposedOrNotOpen throws an exception if the state is not Opened. 
1051
991
1052
		[TestMethod]
992
		[TestMethod]
1053
#if NET_2_1
1054
		[MoonlightBug]
1055
#else
1056
		[NUnit.Framework.Ignore]
1057
#endif
1058
		public void ThrowIfDisposedOrNotOpen_Open_Close ()
993
		public void ThrowIfDisposedOrNotOpen_Open_Close ()
1059
		{
994
		{
1060
			bool opening = false;
995
			bool opening = false;
Lines 1119-1129 namespace MoonTest.ServiceModel { Link Here
1119
		}
1054
		}
1120
1055
1121
		[TestMethod]
1056
		[TestMethod]
1122
#if NET_2_1
1123
		[MoonlightBug]
1124
#else
1125
		[NUnit.Framework.Ignore]
1126
#endif
1127
		public void ThrowIfDisposedOrNotOpen_Fault_Abort ()
1057
		public void ThrowIfDisposedOrNotOpen_Fault_Abort ()
1128
		{
1058
		{
1129
			bool opening = false;
1059
			bool opening = false;
Lines 1196-1206 namespace MoonTest.ServiceModel { Link Here
1196
		}
1126
		}
1197
1127
1198
		[TestMethod]
1128
		[TestMethod]
1199
#if NET_2_1
1200
		[MoonlightBug]
1201
#else
1202
		[NUnit.Framework.Ignore]
1203
#endif
1204
		public void NoOnFault ()
1129
		public void NoOnFault ()
1205
		{
1130
		{
1206
			bool faulted = false;
1131
			bool faulted = false;
Lines 1223-1233 namespace MoonTest.ServiceModel { Link Here
1223
		}
1148
		}
1224
1149
1225
		[TestMethod]
1150
		[TestMethod]
1226
#if NET_2_1
1227
		[MoonlightBug]
1228
#else
1229
		[NUnit.Framework.Ignore]
1230
#endif
1231
		public void OnFaultThrowing ()
1151
		public void OnFaultThrowing ()
1232
		{
1152
		{
1233
			FaultCommunicationObject co = new FaultCommunicationObject ();
1153
			FaultCommunicationObject co = new FaultCommunicationObject ();
Lines 1239-1249 namespace MoonTest.ServiceModel { Link Here
1239
		}
1159
		}
1240
1160
1241
		[TestMethod]
1161
		[TestMethod]
1242
#if NET_2_1
1243
		[MoonlightBug]
1244
#else
1245
		[NUnit.Framework.Ignore]
1246
#endif
1247
		public void AbortWhileAborting ()
1162
		public void AbortWhileAborting ()
1248
		{
1163
		{
1249
			int closing = 0;
1164
			int closing = 0;
Lines 1267-1277 namespace MoonTest.ServiceModel { Link Here
1267
		}
1182
		}
1268
1183
1269
		[TestMethod]
1184
		[TestMethod]
1270
#if NET_2_1
1271
		[MoonlightBug]
1272
#else
1273
		[NUnit.Framework.Ignore]
1274
#endif
1275
		public void AbortWhileClosing ()
1185
		public void AbortWhileClosing ()
1276
		{
1186
		{
1277
			int closing = 0;
1187
			int closing = 0;
Lines 1303-1313 namespace MoonTest.ServiceModel { Link Here
1303
		}
1213
		}
1304
1214
1305
		[TestMethod]
1215
		[TestMethod]
1306
#if NET_2_1
1307
		[MoonlightBug]
1308
#else
1309
		[NUnit.Framework.Ignore]
1310
#endif
1311
		public void NoOnAbort ()
1216
		public void NoOnAbort ()
1312
		{
1217
		{
1313
			bool closing = false;
1218
			bool closing = false;

Return to bug 693366