C++ Rest SDK
The C++ REST SDK is a Microsoft project for cloud-based client-server communication in native code using a modern asynchronous C++ API design. This project aims to help C++ developers connect to and interact with services.
pplxcancellation_token.h
1 /***
2 * ==++==
3 *
4 * Copyright (c) Microsoft Corporation. All rights reserved.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * ==--==
17 * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
18 *
19 * Parallel Patterns Library : cancellation_token
20 *
21 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
22 ****/
23 
24 #pragma once
25 
26 #ifndef _PPLX_H
27 #error This header must not be included directly
28 #endif
29 
30 #ifndef _PPLXCANCELLATION_TOKEN_H
31 #define _PPLXCANCELLATION_TOKEN_H
32 
33 #if (defined(_MSC_VER) && (_MSC_VER >= 1800)) && !CPPREST_FORCE_PPLX
34 #error This file must not be included for Visual Studio 12 or later
35 #endif
36 
37 #include <string>
38 #include "pplx/pplxinterface.h"
39 
40 #pragma pack(push,_CRT_PACKING)
41 // All header files are required to be protected from the macro new
42 #pragma push_macro("new")
43 #undef new
44 
45 namespace pplx
46 {
47 
55 
56 class task_canceled : public std::exception
57 {
58 private:
59  std::string _message;
60 
61 public:
68 
69  explicit task_canceled(_In_z_ const char * _Message) throw()
70  : _message(_Message)
71  {
72  }
73 
77 
78  task_canceled() throw()
79  : exception()
80  {
81  }
82 
83  ~task_canceled() throw () {}
84 
85  const char* what() const CPPREST_NOEXCEPT
86  {
87  return _message.c_str();
88  }
89 };
90 
98 
99 class invalid_operation : public std::exception
100 {
101 private:
102  std::string _message;
103 
104 public:
111 
112  invalid_operation(_In_z_ const char * _Message) throw()
113  : _message(_Message)
114  {
115  }
116 
120 
122  : exception()
123  {
124  }
125 
126  ~invalid_operation() throw () {}
127 
128  const char* what() const CPPREST_NOEXCEPT
129  {
130  return _message.c_str();
131  }
132 };
133 
134 namespace details
135 {
136 
137  // Base class for all reference counted objects
139  {
140  public:
141 
142  virtual ~_RefCounter()
143  {
144  _ASSERTE(_M_refCount == 0);
145  }
146 
147  // Acquires a reference
148  // Returns the new reference count.
149  long _Reference()
150  {
151  long _Refcount = atomic_increment(_M_refCount);
152 
153  // 0 - 1 transition is illegal
154  _ASSERTE(_Refcount > 1);
155  return _Refcount;
156  }
157 
158  // Releases the reference
159  // Returns the new reference count
160  long _Release()
161  {
162  long _Refcount = atomic_decrement(_M_refCount);
163  _ASSERTE(_Refcount >= 0);
164 
165  if (_Refcount == 0)
166  {
167  _Destroy();
168  }
169 
170  return _Refcount;
171  }
172 
173  protected:
174 
175  // Allow derived classes to provide their own deleter
176  virtual void _Destroy()
177  {
178  delete this;
179  }
180 
181  // Only allow instantiation through derived class
182  _RefCounter(long _InitialCount = 1) : _M_refCount(_InitialCount)
183  {
184  _ASSERTE(_M_refCount > 0);
185  }
186 
187  // Reference count
188  atomic_long _M_refCount;
189  };
190 
192 
194  {
195  private:
196 
197  static const long _STATE_CLEAR = 0;
198  static const long _STATE_DEFER_DELETE = 1;
199  static const long _STATE_SYNCHRONIZE = 2;
200  static const long _STATE_CALLED = 3;
201 
202  public:
203 
204  _CancellationTokenRegistration(long _InitialRefs = 1) :
205  _RefCounter(_InitialRefs),
206  _M_state(_STATE_CALLED),
207  _M_pTokenState(NULL)
208  {
209  }
210 
211  _CancellationTokenState *_GetToken() const
212  {
213  return _M_pTokenState;
214  }
215 
216  protected:
217 
219  {
220  _ASSERTE(_M_state != _STATE_CLEAR);
221  }
222 
223  virtual void _Exec() = 0;
224 
225  private:
226 
227  friend class _CancellationTokenState;
228 
229  void _Invoke()
230  {
231  long tid = ::pplx::details::platform::GetCurrentThreadId();
232  _ASSERTE((tid & 0x3) == 0); // If this ever fires, we need a different encoding for this.
233 
234  long result = atomic_compare_exchange(_M_state, tid, _STATE_CLEAR);
235 
236  if (result == _STATE_CLEAR)
237  {
238  _Exec();
239 
240  result = atomic_compare_exchange(_M_state, _STATE_CALLED, tid);
241 
242  if (result == _STATE_SYNCHRONIZE)
243  {
244  _M_pSyncBlock->set();
245  }
246  }
247  _Release();
248  }
249 
250  atomic_long _M_state;
251  extensibility::event_t *_M_pSyncBlock;
252  _CancellationTokenState *_M_pTokenState;
253  };
254 
255  template<typename _Function>
257  {
258  public:
259 
260  _CancellationTokenCallback(const _Function& _Func) :
261  _M_function(_Func)
262  {
263  }
264 
265  protected:
266 
267  virtual void _Exec()
268  {
269  _M_function();
270  }
271 
272  private:
273 
274  _Function _M_function;
275  };
276 
278  {
279  public:
280 
281  CancellationTokenRegistration_TaskProc(TaskProc_t proc, _In_ void *pData, int initialRefs) :
282  _CancellationTokenRegistration(initialRefs), m_proc(proc), m_pData(pData)
283  {
284  }
285 
286  protected:
287 
288  virtual void _Exec()
289  {
290  m_proc(m_pData);
291  }
292 
293  private:
294 
295  TaskProc_t m_proc;
296  void *m_pData;
297 
298  };
299 
300  // The base implementation of a cancellation token.
302  {
303  protected:
305  {
306  private:
307  typedef struct _Node {
309  _Node *_M_next;
310  } Node;
311 
312  public:
313  TokenRegistrationContainer() : _M_begin(nullptr), _M_last(nullptr)
314  {
315  }
316 
318  {
319 #if defined(_MSC_VER)
320 #pragma warning(push)
321 #pragma warning(disable: 6001)
322 #endif
323  auto node = _M_begin;
324  while (node != nullptr)
325  {
326  Node* tmp = node;
327  node = node->_M_next;
328  ::free(tmp);
329  }
330 #if defined(_MSC_VER)
331 #pragma warning(pop)
332 #endif
333  }
334 
335  void swap(TokenRegistrationContainer& list)
336  {
337  std::swap(list._M_begin, _M_begin);
338  std::swap(list._M_last, _M_last);
339  }
340 
341  bool empty()
342  {
343  return _M_begin == nullptr;
344  }
345 
346  template<typename T>
347  void for_each(T lambda)
348  {
349  Node* node = _M_begin;
350 
351  while (node != nullptr)
352  {
353  lambda(node->_M_token);
354  node = node->_M_next;
355  }
356  }
357 
358  void push_back(_CancellationTokenRegistration* token)
359  {
360  Node* node = reinterpret_cast<Node*>(::malloc(sizeof(Node)));
361  if (node == nullptr)
362  {
363  throw ::std::bad_alloc();
364  }
365 
366  node->_M_token = token;
367  node->_M_next = nullptr;
368 
369  if (_M_begin == nullptr)
370  {
371  _M_begin = node;
372  }
373  else
374  {
375  _M_last->_M_next = node;
376  }
377 
378  _M_last = node;
379  }
380 
381  void remove(_CancellationTokenRegistration* token)
382  {
383  Node* node = _M_begin;
384  Node* prev = nullptr;
385 
386  while (node != nullptr)
387  {
388  if (node->_M_token == token) {
389  if (prev == nullptr)
390  {
391  _M_begin = node->_M_next;
392  }
393  else
394  {
395  prev->_M_next = node->_M_next;
396  }
397 
398  if (node->_M_next == nullptr)
399  {
400  _M_last = prev;
401  }
402 
403  ::free(node);
404  break;
405  }
406 
407  prev = node;
408  node = node->_M_next;
409  }
410  }
411 
412  private:
413  Node *_M_begin;
414  Node *_M_last;
415  };
416 
417  public:
418 
419  static _CancellationTokenState * _NewTokenState()
420  {
421  return new _CancellationTokenState();
422  }
423 
424  static _CancellationTokenState *_None()
425  {
426  return reinterpret_cast<_CancellationTokenState *>(2);
427  }
428 
429  static bool _IsValid(_In_opt_ _CancellationTokenState *_PToken)
430  {
431  return (_PToken != NULL && _PToken != _None());
432  }
433 
434  _CancellationTokenState() :
435  _M_stateFlag(0)
436  {
437  }
438 
439  ~_CancellationTokenState()
440  {
441  TokenRegistrationContainer rundownList;
442  {
443  extensibility::scoped_critical_section_t _Lock(_M_listLock);
444  _M_registrations.swap(rundownList);
445  }
446 
447  rundownList.for_each([](_CancellationTokenRegistration * pRegistration)
448  {
449  pRegistration->_M_state = _CancellationTokenRegistration::_STATE_SYNCHRONIZE;
450  pRegistration->_Release();
451  });
452  }
453 
454  bool _IsCanceled() const
455  {
456  return (_M_stateFlag != 0);
457  }
458 
459  void _Cancel()
460  {
461  if (atomic_compare_exchange(_M_stateFlag, 1l, 0l) == 0)
462  {
463  TokenRegistrationContainer rundownList;
464  {
465  extensibility::scoped_critical_section_t _Lock(_M_listLock);
466  _M_registrations.swap(rundownList);
467  }
468 
469  rundownList.for_each([](_CancellationTokenRegistration * pRegistration)
470  {
471  pRegistration->_Invoke();
472  });
473 
474  _M_stateFlag = 2;
475  _M_cancelComplete.set();
476  }
477  }
478 
479  _CancellationTokenRegistration *_RegisterCallback(TaskProc_t _PCallback, _In_ void *_PData, int _InitialRefs = 1)
480  {
481  _CancellationTokenRegistration *pRegistration = new CancellationTokenRegistration_TaskProc(_PCallback, _PData, _InitialRefs);
482  _RegisterCallback(pRegistration);
483  return pRegistration;
484  }
485 
486  void _RegisterCallback(_In_ _CancellationTokenRegistration *_PRegistration)
487  {
488  _PRegistration->_M_state = _CancellationTokenRegistration::_STATE_CLEAR;
489  _PRegistration->_Reference();
490  _PRegistration->_M_pTokenState = this;
491 
492  bool invoke = true;
493 
494  if (!_IsCanceled())
495  {
496  extensibility::scoped_critical_section_t _Lock(_M_listLock);
497 
498  if (!_IsCanceled())
499  {
500  invoke = false;
501  _M_registrations.push_back(_PRegistration);
502  }
503  }
504 
505  if (invoke)
506  {
507  _PRegistration->_Invoke();
508  }
509  }
510 
511  void _DeregisterCallback(_In_ _CancellationTokenRegistration *_PRegistration)
512  {
513  bool synchronize = false;
514 
515  {
516  extensibility::scoped_critical_section_t _Lock(_M_listLock);
517 
518  //
519  // If a cancellation has occurred, the registration list is guaranteed to be empty if we've observed it under the auspices of the
520  // lock. In this case, we must synchronize with the cancelling thread to guarantee that the cancellation is finished by the time
521  // we return from this method.
522  //
523  if (!_M_registrations.empty())
524  {
525  _M_registrations.remove(_PRegistration);
526  _PRegistration->_M_state = _CancellationTokenRegistration::_STATE_SYNCHRONIZE;
527  _PRegistration->_Release();
528  }
529  else
530  {
531  synchronize = true;
532  }
533  }
534 
535  //
536  // If the list is empty, we are in one of several situations:
537  //
538  // - The callback has already been made --> do nothing
539  // - The callback is about to be made --> flag it so it doesn't happen and return
540  // - The callback is in progress elsewhere --> synchronize with it
541  // - The callback is in progress on this thread --> do nothing
542  //
543  if (synchronize)
544  {
545  long result = atomic_compare_exchange(
546  _PRegistration->_M_state,
547  _CancellationTokenRegistration::_STATE_DEFER_DELETE,
548  _CancellationTokenRegistration::_STATE_CLEAR
549  );
550 
551  switch(result)
552  {
553  case _CancellationTokenRegistration::_STATE_CLEAR:
554  case _CancellationTokenRegistration::_STATE_CALLED:
555  break;
556  case _CancellationTokenRegistration::_STATE_DEFER_DELETE:
557  case _CancellationTokenRegistration::_STATE_SYNCHRONIZE:
558  _ASSERTE(false);
559  break;
560  default:
561  {
562  long tid = result;
563  if (tid == ::pplx::details::platform::GetCurrentThreadId())
564  {
565  //
566  // It is entirely legal for a caller to Deregister during a callback instead of having to provide their own synchronization
567  // mechanism between the two. In this case, we do *NOT* need to explicitly synchronize with the callback as doing so would
568  // deadlock. If the call happens during, skip any extra synchronization.
569  //
570  break;
571  }
572 
573  extensibility::event_t ev;
574  _PRegistration->_M_pSyncBlock = &ev;
575 
576  long result_1 = atomic_exchange(_PRegistration->_M_state, _CancellationTokenRegistration::_STATE_SYNCHRONIZE);
577 
578  if (result_1 != _CancellationTokenRegistration::_STATE_CALLED)
579  {
580  _PRegistration->_M_pSyncBlock->wait(::pplx::extensibility::event_t::timeout_infinite);
581  }
582 
583  break;
584  }
585  }
586  }
587  }
588 
589  private:
590 
591  // The flag for the token state (whether it is canceled or not)
592  atomic_long _M_stateFlag;
593 
594  // Notification of completion of cancellation of this token.
595  extensibility::event_t _M_cancelComplete; // Hmm.. where do we wait for it??
596 
597  // Lock to protect the registrations list
598  extensibility::critical_section_t _M_listLock;
599 
600  // The protected list of registrations
601  TokenRegistrationContainer _M_registrations;
602  };
603 
604 } // namespace details
605 
606 class cancellation_token_source;
607 class cancellation_token;
608 
609 
617 {
618 public:
619 
621  _M_pRegistration(NULL)
622  {
623  }
624 
626  {
627  _Clear();
628  }
629 
631  {
632  _Assign(_Src._M_pRegistration);
633  }
634 
636  {
637  _Move(_Src._M_pRegistration);
638  }
639 
641  {
642  if (this != &_Src)
643  {
644  _Clear();
645  _Assign(_Src._M_pRegistration);
646  }
647  return *this;
648  }
649 
651  {
652  if (this != &_Src)
653  {
654  _Clear();
655  _Move(_Src._M_pRegistration);
656  }
657  return *this;
658  }
659 
660  bool operator==(const cancellation_token_registration& _Rhs) const
661  {
662  return _M_pRegistration == _Rhs._M_pRegistration;
663  }
664 
665  bool operator!=(const cancellation_token_registration& _Rhs) const
666  {
667  return !(operator==(_Rhs));
668  }
669 
670 private:
671 
672  friend class cancellation_token;
673 
675  _M_pRegistration(_PRegistration)
676  {
677  }
678 
679  void _Clear()
680  {
681  if (_M_pRegistration != NULL)
682  {
683  _M_pRegistration->_Release();
684  }
685  _M_pRegistration = NULL;
686  }
687 
688  void _Assign(_In_ details::_CancellationTokenRegistration *_PRegistration)
689  {
690  if (_PRegistration != NULL)
691  {
692  _PRegistration->_Reference();
693  }
694  _M_pRegistration = _PRegistration;
695  }
696 
697  void _Move(_In_ details::_CancellationTokenRegistration *&_PRegistration)
698  {
699  _M_pRegistration = _PRegistration;
700  _PRegistration = NULL;
701  }
702 
703  details::_CancellationTokenRegistration *_M_pRegistration;
704 };
705 
706 
713 {
714 public:
715 
717 
725  {
726  return cancellation_token();
727  }
728 
730  {
731  _Assign(_Src._M_Impl);
732  }
733 
734  cancellation_token(cancellation_token&& _Src)
735  {
736  _Move(_Src._M_Impl);
737  }
738 
739  cancellation_token& operator=(const cancellation_token& _Src)
740  {
741  if (this != &_Src)
742  {
743  _Clear();
744  _Assign(_Src._M_Impl);
745  }
746  return *this;
747  }
748 
749  cancellation_token& operator=(cancellation_token&& _Src)
750  {
751  if (this != &_Src)
752  {
753  _Clear();
754  _Move(_Src._M_Impl);
755  }
756  return *this;
757  }
758 
759  bool operator==(const cancellation_token& _Src) const
760  {
761  return _M_Impl == _Src._M_Impl;
762  }
763 
764  bool operator!=(const cancellation_token& _Src) const
765  {
766  return !(operator==(_Src));
767  }
768 
769  ~cancellation_token()
770  {
771  _Clear();
772  }
773 
780  bool is_cancelable() const
781  {
782  return (_M_Impl != NULL);
783  }
784 
791  bool is_canceled() const
792  {
793  return (_M_Impl != NULL && _M_Impl->_IsCanceled());
794  }
795 
812  template<typename _Function>
814  {
815  if (_M_Impl == NULL)
816  {
817  // A callback cannot be registered if the token does not have an associated source.
818  throw invalid_operation();
819  }
820 #if defined(_MSC_VER)
821 #pragma warning(suppress: 28197)
822 #endif
824  _M_Impl->_RegisterCallback(_PCallback);
825  return cancellation_token_registration(_PCallback);
826  }
827 
836  void deregister_callback(const cancellation_token_registration& _Registration) const
837  {
838  _M_Impl->_DeregisterCallback(_Registration._M_pRegistration);
839  }
840 
841  _ImplType _GetImpl() const
842  {
843  return _M_Impl;
844  }
845 
846  _ImplType _GetImplValue() const
847  {
848  return (_M_Impl == NULL) ? ::pplx::details::_CancellationTokenState::_None() : _M_Impl;
849  }
850 
851  static cancellation_token _FromImpl(_ImplType _Impl)
852  {
853  return cancellation_token(_Impl);
854  }
855 
856 private:
857 
858  friend class cancellation_token_source;
859 
860  _ImplType _M_Impl;
861 
862  void _Clear()
863  {
864  if (_M_Impl != NULL)
865  {
866  _M_Impl->_Release();
867  }
868  _M_Impl = NULL;
869  }
870 
871  void _Assign(_ImplType _Impl)
872  {
873  if (_Impl != NULL)
874  {
875  _Impl->_Reference();
876  }
877  _M_Impl = _Impl;
878  }
879 
880  void _Move(_ImplType &_Impl)
881  {
882  _M_Impl = _Impl;
883  _Impl = NULL;
884  }
885 
886  cancellation_token() :
887  _M_Impl(NULL)
888  {
889  }
890 
891  cancellation_token(_ImplType _Impl) :
892  _M_Impl(_Impl)
893  {
894  if (_M_Impl == ::pplx::details::_CancellationTokenState::_None())
895  {
896  _M_Impl = NULL;
897  }
898 
899  if (_M_Impl != NULL)
900  {
901  _M_Impl->_Reference();
902  }
903  }
904 };
905 
910 {
911 public:
912 
913  typedef ::pplx::details::_CancellationTokenState * _ImplType;
914 
919  {
920  _M_Impl = new ::pplx::details::_CancellationTokenState;
921  }
922 
924  {
925  _Assign(_Src._M_Impl);
926  }
927 
929  {
930  _Move(_Src._M_Impl);
931  }
932 
934  {
935  if (this != &_Src)
936  {
937  _Clear();
938  _Assign(_Src._M_Impl);
939  }
940  return *this;
941  }
942 
944  {
945  if (this != &_Src)
946  {
947  _Clear();
948  _Move(_Src._M_Impl);
949  }
950  return *this;
951  }
952 
953  bool operator==(const cancellation_token_source& _Src) const
954  {
955  return _M_Impl == _Src._M_Impl;
956  }
957 
958  bool operator!=(const cancellation_token_source& _Src) const
959  {
960  return !(operator==(_Src));
961  }
962 
964  {
965  if (_M_Impl != NULL)
966  {
967  _M_Impl->_Release();
968  }
969  }
970 
979  {
980  return cancellation_token(_M_Impl);
981  }
982 
994  {
995  cancellation_token_source newSource;
996  _Src.register_callback( [newSource](){ newSource.cancel(); } );
997  return newSource;
998  }
999 
1014  template<typename _Iter>
1015  static cancellation_token_source create_linked_source(_Iter _Begin, _Iter _End)
1016  {
1017  cancellation_token_source newSource;
1018  for (_Iter _It = _Begin; _It != _End; ++_It)
1019  {
1020  _It->register_callback( [newSource](){ newSource.cancel(); } );
1021  }
1022  return newSource;
1023  }
1024 
1029  void cancel() const
1030  {
1031  _M_Impl->_Cancel();
1032  }
1033 
1034  _ImplType _GetImpl() const
1035  {
1036  return _M_Impl;
1037  }
1038 
1039  static cancellation_token_source _FromImpl(_ImplType _Impl)
1040  {
1041  return cancellation_token_source(_Impl);
1042  }
1043 
1044 private:
1045 
1046  _ImplType _M_Impl;
1047 
1048  void _Clear()
1049  {
1050  if (_M_Impl != NULL)
1051  {
1052  _M_Impl->_Release();
1053  }
1054  _M_Impl = NULL;
1055  }
1056 
1057  void _Assign(_ImplType _Impl)
1058  {
1059  if (_Impl != NULL)
1060  {
1061  _Impl->_Reference();
1062  }
1063  _M_Impl = _Impl;
1064  }
1065 
1066  void _Move(_ImplType &_Impl)
1067  {
1068  _M_Impl = _Impl;
1069  _Impl = NULL;
1070  }
1071 
1072  cancellation_token_source(_ImplType _Impl) :
1073  _M_Impl(_Impl)
1074  {
1075  if (_M_Impl == ::pplx::details::_CancellationTokenState::_None())
1076  {
1077  _M_Impl = NULL;
1078  }
1079 
1080  if (_M_Impl != NULL)
1081  {
1082  _M_Impl->_Reference();
1083  }
1084  }
1085 };
1086 
1087 } // namespace pplx
1088 
1089 #pragma pop_macro("new")
1090 #pragma pack(pop)
1091 
1092 #endif // _PPLXCANCELLATION_TOKEN_H
void(_pplx_cdecl * TaskProc_t)(void *)
An elementary abstraction for a task, defined as void (__cdecl * TaskProc_t)(void *)...
Definition: pplxinterface.h:59
invalid_operation(_In_z_ const char *_Message)
Constructs an invalid_operation object.
Definition: pplxcancellation_token.h:112
void cancel() const
Cancels the token. Any task_group, structured_task_group, or task which utilizes the token will be ca...
Definition: pplxcancellation_token.h:1029
cancellation_token_source()
Constructs a new cancellation_token_source. The source can be used to flag cancellation of some cance...
Definition: pplxcancellation_token.h:918
Definition: pplxcancellation_token.h:277
void deregister_callback(const cancellation_token_registration &_Registration) const
Removes a callback previously registered via the register method based on the cancellation_token_regi...
Definition: pplxcancellation_token.h:836
::pplx::cancellation_token_registration register_callback(const _Function &_Func) const
Registers a callback function with the token. If and when the token is canceled, the callback will be...
Definition: pplxcancellation_token.h:813
The pplx namespace provides classes and functions that give you access to the Concurrency Runtime...
Definition: pplx.h:81
Definition: pplxcancellation_token.h:138
This class describes an exception thrown by the PPL tasks layer in order to force the current task to...
Definition: pplxcancellation_token.h:56
The cancellation_token_source class represents the ability to cancel some cancelable operation...
Definition: pplxcancellation_token.h:909
bool is_canceled() const
Returns true if the token has been canceled.
Definition: pplxcancellation_token.h:791
task_canceled(_In_z_ const char *_Message)
Constructs a task_canceled object.
Definition: pplxcancellation_token.h:69
static cancellation_token_source create_linked_source(cancellation_token &_Src)
Creates a cancellation_token_source which is canceled when the provided token is canceled.
Definition: pplxcancellation_token.h:993
invalid_operation()
Constructs an invalid_operation object.
Definition: pplxcancellation_token.h:121
Definition: pplxcancellation_token.h:256
The cancellation_token class represents the ability to determine whether some operation has been requ...
Definition: pplxcancellation_token.h:712
The cancellation_token_registration class represents a callback notification from a cancellation_toke...
Definition: pplxcancellation_token.h:616
cancellation_token get_token() const
Returns a cancellation token associated with this source. The returned token can be polled for cancel...
Definition: pplxcancellation_token.h:978
task_canceled()
Constructs a task_canceled object.
Definition: pplxcancellation_token.h:78
Manual reset event
Definition: pplxlinux.h:84
static cancellation_token none()
Returns a cancellation token which can never be subject to cancellation.
Definition: pplxcancellation_token.h:724
Definition: pplxcancellation_token.h:193
static cancellation_token_source create_linked_source(_Iter _Begin, _Iter _End)
Creates a cancellation_token_source which is canceled when one of a series of tokens represented by a...
Definition: pplxcancellation_token.h:1015
bool is_cancelable() const
Returns an indication of whether this token can be canceled or not.
Definition: pplxcancellation_token.h:780
Definition: pplxcancellation_token.h:301
This class describes an exception thrown when an invalid operation is performed that is not more accu...
Definition: pplxcancellation_token.h:99