comparison Implab/AbstractEvent.cs @ 145:706fccb85524 v2

RC: cancellation support for promises + tests
author cin
date Sun, 08 Mar 2015 02:52:27 +0300
parents 8c0b95069066
children e6d4b41f0101
comparison
equal deleted inserted replaced
144:8c0b95069066 145:706fccb85524
2 using Implab.Parallels; 2 using Implab.Parallels;
3 using System.Threading; 3 using System.Threading;
4 using System.Reflection; 4 using System.Reflection;
5 5
6 namespace Implab { 6 namespace Implab {
7 public abstract class AbstractEvent<THandler> : ICancelationToken, ICancellable { 7 public abstract class AbstractEvent<THandler> : ICancellationToken, ICancellable {
8 8
9 const int UNRESOLVED_SATE = 0; 9 const int UNRESOLVED_SATE = 0;
10 const int TRANSITIONAL_STATE = 1; 10 const int TRANSITIONAL_STATE = 1;
11 const int SUCCEEDED_STATE = 2; 11 const int SUCCEEDED_STATE = 2;
12 const int REJECTED_STATE = 3; 12 const int REJECTED_STATE = 3;
278 get { 278 get {
279 return m_error; 279 return m_error;
280 } 280 }
281 } 281 }
282 282
283 public bool AcceptIfRequested() { 283 public bool CancelOperationIfRequested() {
284 if (IsCancelRequested) 284 if (IsCancellationRequested) {
285 CancelOperation(CancelReason); 285 CancelOperation(CancellationReason);
286 return true;
287 }
288 return false;
286 } 289 }
287 290
288 public virtual void CancelOperation(Exception reason) { 291 public virtual void CancelOperation(Exception reason) {
289 SetCancelled(reason); 292 SetCancelled(reason);
290 } 293 }
291 294
292 public void CancelationRequested(Action<Exception> handler) { 295 public void CancellationRequested(Action<Exception> handler) {
293 Safe.ArgumentNotNull(handler, "handler"); 296 Safe.ArgumentNotNull(handler, "handler");
294 if (IsCancelRequested) 297 if (IsCancellationRequested)
295 handler(CancelReason); 298 handler(CancellationReason);
296 299
297 if (m_cancelationHandlers == null) 300 if (m_cancelationHandlers == null)
298 Interlocked.CompareExchange(ref m_cancelationHandlers, new MTQueue<Action<Exception>>(), null); 301 Interlocked.CompareExchange(ref m_cancelationHandlers, new MTQueue<Action<Exception>>(), null);
299 302
300 m_cancelationHandlers.Enqueue(handler); 303 m_cancelationHandlers.Enqueue(handler);
301 304
302 if (IsCancelRequested && m_cancelationHandlers.TryDequeue(out handler)) 305 if (IsCancellationRequested && m_cancelationHandlers.TryDequeue(out handler))
303 // TryDeque implies MemoryBarrier() 306 // TryDeque implies MemoryBarrier()
304 handler(m_cancelationReason); 307 handler(m_cancelationReason);
305 } 308 }
306 309
307 public bool IsCancelRequested { 310 public bool IsCancellationRequested {
308 get { 311 get {
309 do { 312 do {
310 if (m_cancelRequest == CANCEL_NOT_REQUESTED) 313 if (m_cancelRequest == CANCEL_NOT_REQUESTED)
311 return false; 314 return false;
312 if (m_cancelRequest == CANCEL_REQUESTED) 315 if (m_cancelRequest == CANCEL_REQUESTED)
314 Thread.MemoryBarrier(); 317 Thread.MemoryBarrier();
315 } while(true); 318 } while(true);
316 } 319 }
317 } 320 }
318 321
319 public Exception CancelReason { 322 public Exception CancellationReason {
320 get { 323 get {
321 do { 324 do {
322 Thread.MemoryBarrier(); 325 Thread.MemoryBarrier();
323 } while(m_cancelRequest == CANCEL_REQUESTING); 326 } while(m_cancelRequest == CANCEL_REQUESTING);
324 327
331 public void Cancel() { 334 public void Cancel() {
332 Cancel(null); 335 Cancel(null);
333 } 336 }
334 337
335 public void Cancel(Exception reason) { 338 public void Cancel(Exception reason) {
336 if (CANCEL_NOT_REQUESTED == Interlocked.CompareExchange(ref m_cancelRequest, CANCEL_REQUESTING)) { 339 if (CANCEL_NOT_REQUESTED == Interlocked.CompareExchange(ref m_cancelRequest, CANCEL_REQUESTING, CANCEL_NOT_REQUESTED)) {
337 m_cancelationReason = reason; 340 m_cancelationReason = reason;
338 m_cancelRequest = CANCEL_REQUESTED; 341 m_cancelRequest = CANCEL_REQUESTED;
339 if (m_cancelationHandlers != null) { 342 if (m_cancelationHandlers != null) {
340 Action<Exception> handler; 343 Action<Exception> handler;
341 while (m_cancelationHandlers.TryDequeue(out handler)) 344 while (m_cancelationHandlers.TryDequeue(out handler))