Mercurial > pub > ImplabNet
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)) |