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_NewTokenState ()
 
static _CancellationTokenState_None ()
 
static bool _IsValid (_In_opt_ _CancellationTokenState *_PToken)
 

Private Attributes

atomic_long _M_stateFlag
 
std::mutex _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
342  :
343  _M_stateFlag(0)
344  {
345  }
atomic_long _M_stateFlag
Definition: pplcancellation_token.h:499
Concurrency::details::_CancellationTokenState::~_CancellationTokenState ( )
inline
348  {
349  TokenRegistrationContainer _RundownList;
350  {
351  std::lock_guard<std::mutex> _Lock(_M_listLock);
352  _M_registrations.swap(_RundownList);
353  }
354 
355  _RundownList.for_each([](_CancellationTokenRegistration * _PRegistration)
356  {
357  _PRegistration->_M_state = _CancellationTokenRegistration::_STATE_SYNCHRONIZE;
358  _PRegistration->_Release();
359  });
360  }
void swap(TokenRegistrationContainer &_List)
Definition: pplcancellation_token.h:252
static const long _STATE_SYNCHRONIZE
Definition: pplcancellation_token.h:112
std::mutex _M_listLock
Definition: pplcancellation_token.h:502
TokenRegistrationContainer _M_registrations
Definition: pplcancellation_token.h:505

Member Function Documentation

void Concurrency::details::_CancellationTokenState::_Cancel ( )
inline
368  {
369  if (atomic_compare_exchange(_M_stateFlag, 1l, 0l) == 0)
370  {
371  TokenRegistrationContainer _RundownList;
372  {
373  std::lock_guard<std::mutex> _Lock(_M_listLock);
374  _M_registrations.swap(_RundownList);
375  }
376 
377  _RundownList.for_each([](_CancellationTokenRegistration * _PRegistration)
378  {
379  _PRegistration->_Invoke();
380  });
381 
382  _M_stateFlag = 2;
383  }
384  }
void swap(TokenRegistrationContainer &_List)
Definition: pplcancellation_token.h:252
_T atomic_compare_exchange(std::atomic< _T > &_Target, _T _Exchange, _T _Comparand)
Definition: pplinterface.h:238
std::mutex _M_listLock
Definition: pplcancellation_token.h:502
atomic_long _M_stateFlag
Definition: pplcancellation_token.h:499
TokenRegistrationContainer _M_registrations
Definition: pplcancellation_token.h:505
void Concurrency::details::_CancellationTokenState::_DeregisterCallback ( _In_ _CancellationTokenRegistration _PRegistration)
inline
419  {
420  bool _Synchronize = false;
421 
422  {
423  std::lock_guard<std::mutex> _Lock(_M_listLock);
424 
425  //
426  // If a cancellation has occurred, the registration list is guaranteed to be empty if we've observed it under the auspices of the
427  // lock. In this case, we must synchronize with the cancelling thread to guarantee that the cancellation is finished by the time
428  // we return from this method.
429  //
430  if (!_M_registrations.empty())
431  {
432  _M_registrations.remove(_PRegistration);
433  _PRegistration->_M_state = _CancellationTokenRegistration::_STATE_SYNCHRONIZE;
434  _PRegistration->_Release();
435  }
436  else
437  {
438  _Synchronize = true;
439  }
440  }
441 
442  //
443  // If the list is empty, we are in one of several situations:
444  //
445  // - The callback has already been made --> do nothing
446  // - The callback is about to be made --> flag it so it doesn't happen and return
447  // - The callback is in progress elsewhere --> synchronize with it
448  // - The callback is in progress on this thread --> do nothing
449  //
450  if (_Synchronize)
451  {
452  long _Result = atomic_compare_exchange(
453  _PRegistration->_M_state,
456  );
457 
458  switch(_Result)
459  {
462  break;
465  _ASSERTE(false);
466  break;
467  default:
468  {
470  {
471  //
472  // It is entirely legal for a caller to Deregister during a callback instead of having to provide their own synchronization
473  // mechanism between the two. In this case, we do *NOT* need to explicitly synchronize with the callback as doing so would
474  // deadlock. If the call happens during, skip any extra synchronization.
475  //
476  break;
477  }
478 
479  long _Result_1 = atomic_exchange(_PRegistration->_M_state, _CancellationTokenRegistration::_STATE_SYNCHRONIZE);
480 
482  {
483  std::unique_lock<std::mutex> _Lock(_PRegistration->_M_Mutex);
484  _PRegistration->_M_CondVar.wait(_Lock,
485  [_PRegistration]{ return _PRegistration->_M_signaled; });
486 
487  _ASSERTE(_PRegistration->_M_signaled);
488  }
489 
490  break;
491  }
492  }
493  }
494  }
static const long _STATE_CALLED
Definition: pplcancellation_token.h:113
_CRTIMP2 long __cdecl GetCurrentThreadId()
_T atomic_exchange(std::atomic< _T > &_Target, _T _Value)
Definition: pplinterface.h:246
static const long _STATE_DEFER_DELETE
Definition: pplcancellation_token.h:111
static const long _STATE_SYNCHRONIZE
Definition: pplcancellation_token.h:112
_T atomic_compare_exchange(std::atomic< _T > &_Target, _T _Exchange, _T _Comparand)
Definition: pplinterface.h:238
void remove(_CancellationTokenRegistration *_Token)
Definition: pplcancellation_token.h:290
std::mutex _M_listLock
Definition: pplcancellation_token.h:502
TokenRegistrationContainer _M_registrations
Definition: pplcancellation_token.h:505
static const long _STATE_CLEAR
Definition: pplcancellation_token.h:110
bool Concurrency::details::_CancellationTokenState::_IsCanceled ( ) const
inline
363  {
364  return (_M_stateFlag != 0);
365  }
atomic_long _M_stateFlag
Definition: pplcancellation_token.h:499
static bool Concurrency::details::_CancellationTokenState::_IsValid ( _In_opt_ _CancellationTokenState _PToken)
inlinestatic
338  {
339  return (_PToken != NULL && _PToken != _None());
340  }
#define NULL
Definition: vcruntime.h:236
static _CancellationTokenState * _None()
Definition: pplcancellation_token.h:332
static _CancellationTokenState* Concurrency::details::_CancellationTokenState::_NewTokenState ( )
inlinestatic
328  {
329  return new _CancellationTokenState();
330  }
_CancellationTokenState()
Definition: pplcancellation_token.h:342
static _CancellationTokenState* Concurrency::details::_CancellationTokenState::_None ( )
inlinestatic
333  {
334  return reinterpret_cast<_CancellationTokenState *>(2);
335  }
_CancellationTokenState()
Definition: pplcancellation_token.h:342
_CancellationTokenRegistration* Concurrency::details::_CancellationTokenState::_RegisterCallback ( TaskProc_t  _PCallback,
_In_ void _PData,
int  _InitialRefs = 1 
)
inline
387  {
388  _CancellationTokenRegistration *_PRegistration = new CancellationTokenRegistration_TaskProc(_PCallback, _PData, _InitialRefs);
389  _RegisterCallback(_PRegistration);
390  return _PRegistration;
391  }
_CancellationTokenRegistration * _RegisterCallback(TaskProc_t _PCallback, _In_ void *_PData, int _InitialRefs=1)
Definition: pplcancellation_token.h:386
void Concurrency::details::_CancellationTokenState::_RegisterCallback ( _In_ _CancellationTokenRegistration _PRegistration)
inline
394  {
395  _PRegistration->_M_state = _CancellationTokenRegistration::_STATE_CLEAR;
396  _PRegistration->_Reference();
397  _PRegistration->_M_pTokenState = this;
398 
399  bool _Invoke = true;
400 
401  if (!_IsCanceled())
402  {
403  std::lock_guard<std::mutex> _Lock(_M_listLock);
404 
405  if (!_IsCanceled())
406  {
407  _Invoke = false;
408  _M_registrations.push_back(_PRegistration);
409  }
410  }
411 
412  if (_Invoke)
413  {
414  _PRegistration->_Invoke();
415  }
416  }
bool _IsCanceled() const
Definition: pplcancellation_token.h:362
std::mutex _M_listLock
Definition: pplcancellation_token.h:502
TokenRegistrationContainer _M_registrations
Definition: pplcancellation_token.h:505
static const long _STATE_CLEAR
Definition: pplcancellation_token.h:110
void push_back(_CancellationTokenRegistration *_Token)
Definition: pplcancellation_token.h:275

Member Data Documentation

std::mutex 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: