STLdoc
STLdocumentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
Classes | Public Member Functions | Static Public Member Functions | Private Attributes | List of all members
Concurrency::details::_CancellationTokenState Class Reference

#include <pplcancellation_token.h>

Inheritance diagram for Concurrency::details::_CancellationTokenState:
Concurrency::details::_RefCounter

Classes

class  TokenRegistrationContainer
 

Public Member Functions

 _CancellationTokenState ()
 
 ~_CancellationTokenState ()
 
bool _IsCanceled () const
 
void _Cancel ()
 
_CancellationTokenRegistration_RegisterCallback (TaskProc_t _PCallback, _In_ void *_PData, int _InitialRefs=1)
 
void _RegisterCallback (_In_ _CancellationTokenRegistration *_PRegistration)
 
void _DeregisterCallback (_In_ _CancellationTokenRegistration *_PRegistration)
 
- Public Member Functions inherited from Concurrency::details::_RefCounter
virtual ~_RefCounter ()
 
long _Reference ()
 
long _Release ()
 

Static Public Member Functions

static _CancellationTokenState_CancellationTokenState::_NewTokenState ()
 
static _CancellationTokenState_None ()
 
static bool _IsValid (_In_opt_ _CancellationTokenState *_PToken)
 

Private Attributes

atomic_long _M_stateFlag
 
extensibility::event_t _M_cancelComplete
 
extensibility::critical_section_t _M_listLock
 
TokenRegistrationContainer _M_registrations
 

Additional Inherited Members

- Protected Member Functions inherited from Concurrency::details::_RefCounter
virtual void _Destroy ()
 
 _RefCounter (long _InitialCount=1)
 
- Protected Attributes inherited from Concurrency::details::_RefCounter
volatile long _M_refCount
 

Constructor & Destructor Documentation

Concurrency::details::_CancellationTokenState::_CancellationTokenState ( )
inline
338  :
339  _M_stateFlag(0)
340  {
341  }
atomic_long _M_stateFlag
Definition: pplcancellation_token.h:496
Concurrency::details::_CancellationTokenState::~_CancellationTokenState ( )
inline
344  {
345  TokenRegistrationContainer rundownList;
346  {
348  _M_registrations.swap(rundownList);
349  }
350 
351  rundownList.for_each([](_CancellationTokenRegistration * pRegistration)
352  {
353  pRegistration->_M_state = _CancellationTokenRegistration::_STATE_SYNCHRONIZE;
354  pRegistration->_Release();
355  });
356  }
static const long _STATE_SYNCHRONIZE
Definition: pplcancellation_token.h:110
void swap(TokenRegistrationContainer &list)
Definition: pplcancellation_token.h:239
extensibility::critical_section_t _M_listLock
Definition: pplcancellation_token.h:502
TokenRegistrationContainer _M_registrations
Definition: pplcancellation_token.h:505
critical_section_t::scoped_lock scoped_critical_section_t
Definition: pplconcrt.h:34

Member Function Documentation

void Concurrency::details::_CancellationTokenState::_Cancel ( )
inline
364  {
365  if (atomic_compare_exchange(_M_stateFlag, 1l, 0l) == 0)
366  {
367  TokenRegistrationContainer rundownList;
368  {
370  _M_registrations.swap(rundownList);
371  }
372 
373  rundownList.for_each([](_CancellationTokenRegistration * pRegistration)
374  {
375  pRegistration->_Invoke();
376  });
377 
378  _M_stateFlag = 2;
380  }
381  }
_T atomic_compare_exchange(std::atomic< _T > &_Target, _T _Exchange, _T _Comparand)
Definition: pplinterface.h:146
extensibility::event_t _M_cancelComplete
Definition: pplcancellation_token.h:499
_CRTIMP void set()
Signals the event.
void swap(TokenRegistrationContainer &list)
Definition: pplcancellation_token.h:239
atomic_long _M_stateFlag
Definition: pplcancellation_token.h:496
extensibility::critical_section_t _M_listLock
Definition: pplcancellation_token.h:502
TokenRegistrationContainer _M_registrations
Definition: pplcancellation_token.h:505
critical_section_t::scoped_lock scoped_critical_section_t
Definition: pplconcrt.h:34
static _CancellationTokenState* Concurrency::details::_CancellationTokenState::_CancellationTokenState::_NewTokenState ( )
inlinestatic
324  {
325  return new _CancellationTokenState();
326  }
_CancellationTokenState()
Definition: pplcancellation_token.h:338
void Concurrency::details::_CancellationTokenState::_DeregisterCallback ( _In_ _CancellationTokenRegistration _PRegistration)
inline
416  {
417  bool synchronize = false;
418 
419  {
421 
422  //
423  // If a cancellation has occurred, the registration list is guaranteed to be empty if we've observed it under the auspices of the
424  // lock. In this case, we must synchronize with the cancelling thread to guarantee that the cancellation is finished by the time
425  // we return from this method.
426  //
427  if (!_M_registrations.empty())
428  {
429  _M_registrations.remove(_PRegistration);
430  _PRegistration->_M_state = _CancellationTokenRegistration::_STATE_SYNCHRONIZE;
431  _PRegistration->_Release();
432  }
433  else
434  {
435  synchronize = true;
436  }
437  }
438 
439  //
440  // If the list is empty, we are in one of several situations:
441  //
442  // - The callback has already been made --> do nothing
443  // - The callback is about to be made --> flag it so it doesn't happen and return
444  // - The callback is in progress elsewhere --> synchronize with it
445  // - The callback is in progress on this thread --> do nothing
446  //
447  if (synchronize)
448  {
449  long result = atomic_compare_exchange(
450  _PRegistration->_M_state,
453  );
454 
455  switch(result)
456  {
459  break;
462  _ASSERTE(false);
463  break;
464  default:
465  {
466  long tid = result;
468  {
469  //
470  // It is entirely legal for a caller to Deregister during a callback instead of having to provide their own synchronization
471  // mechanism between the two. In this case, we do *NOT* need to explicitly synchronize with the callback as doing so would
472  // deadlock. If the call happens during, skip any extra synchronization.
473  //
474  break;
475  }
476 
478  _PRegistration->_M_pSyncBlock = &ev;
479 
480  long result_1 = atomic_exchange(_PRegistration->_M_state, _CancellationTokenRegistration::_STATE_SYNCHRONIZE);
481 
483  {
484  _PRegistration->_M_pSyncBlock->wait(::Concurrency::extensibility::event_t::timeout_infinite);
485  }
486 
487  break;
488  }
489  }
490  }
491  }
static const long _STATE_CALLED
Definition: pplcancellation_token.h:111
_T atomic_exchange(std::atomic< _T > &_Target, _T _Value)
Definition: pplinterface.h:154
static const long _STATE_DEFER_DELETE
Definition: pplcancellation_token.h:109
static const long _STATE_SYNCHRONIZE
Definition: pplcancellation_token.h:110
_T atomic_compare_exchange(std::atomic< _T > &_Target, _T _Exchange, _T _Comparand)
Definition: pplinterface.h:146
_CRTIMP long __cdecl GetCurrentThreadId()
::Concurrency::event event_t
Definition: pplconcrt.h:31
#define _ASSERTE(expr)
Definition: crtdbg.h:216
void remove(_CancellationTokenRegistration *token)
Definition: pplcancellation_token.h:285
static const unsigned int timeout_infinite
Value indicating that a wait should never time out.
Definition: concrt.h:4076
extensibility::critical_section_t _M_listLock
Definition: pplcancellation_token.h:502
TokenRegistrationContainer _M_registrations
Definition: pplcancellation_token.h:505
static const long _STATE_CLEAR
Definition: pplcancellation_token.h:108
critical_section_t::scoped_lock scoped_critical_section_t
Definition: pplconcrt.h:34
bool Concurrency::details::_CancellationTokenState::_IsCanceled ( ) const
inline
359  {
360  return (_M_stateFlag != 0);
361  }
atomic_long _M_stateFlag
Definition: pplcancellation_token.h:496
static bool Concurrency::details::_CancellationTokenState::_IsValid ( _In_opt_ _CancellationTokenState _PToken)
inlinestatic
334  {
335  return (_PToken != NULL && _PToken != _None());
336  }
#define NULL
Definition: crtdbg.h:30
static _CancellationTokenState * _None()
Definition: pplcancellation_token.h:328
static _CancellationTokenState* Concurrency::details::_CancellationTokenState::_None ( )
inlinestatic
329  {
330  return reinterpret_cast<_CancellationTokenState *>(2);
331  }
_CancellationTokenState()
Definition: pplcancellation_token.h:338
_CancellationTokenRegistration* Concurrency::details::_CancellationTokenState::_RegisterCallback ( TaskProc_t  _PCallback,
_In_ void _PData,
int  _InitialRefs = 1 
)
inline
384  {
385  _CancellationTokenRegistration *pRegistration = new CancellationTokenRegistration_TaskProc(_PCallback, _PData, _InitialRefs);
386  _RegisterCallback(pRegistration);
387  return pRegistration;
388  }
_CancellationTokenRegistration * _RegisterCallback(TaskProc_t _PCallback, _In_ void *_PData, int _InitialRefs=1)
Definition: pplcancellation_token.h:383
void Concurrency::details::_CancellationTokenState::_RegisterCallback ( _In_ _CancellationTokenRegistration _PRegistration)
inline
391  {
392  _PRegistration->_M_state = _CancellationTokenRegistration::_STATE_CLEAR;
393  _PRegistration->_Reference();
394  _PRegistration->_M_pTokenState = this;
395 
396  bool invoke = true;
397 
398  if (!_IsCanceled())
399  {
401 
402  if (!_IsCanceled())
403  {
404  invoke = false;
405  _M_registrations.push_back(_PRegistration);
406  }
407  }
408 
409  if (invoke)
410  {
411  _PRegistration->_Invoke();
412  }
413  }
void push_back(_CancellationTokenRegistration *token)
Definition: pplcancellation_token.h:262
bool _IsCanceled() const
Definition: pplcancellation_token.h:358
extensibility::critical_section_t _M_listLock
Definition: pplcancellation_token.h:502
TokenRegistrationContainer _M_registrations
Definition: pplcancellation_token.h:505
static const long _STATE_CLEAR
Definition: pplcancellation_token.h:108
critical_section_t::scoped_lock scoped_critical_section_t
Definition: pplconcrt.h:34

Member Data Documentation

extensibility::event_t Concurrency::details::_CancellationTokenState::_M_cancelComplete
private
extensibility::critical_section_t Concurrency::details::_CancellationTokenState::_M_listLock
private
TokenRegistrationContainer Concurrency::details::_CancellationTokenState::_M_registrations
private
atomic_long Concurrency::details::_CancellationTokenState::_M_stateFlag
private

The documentation for this class was generated from the following file: