STLdoc
STLdocumentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
Public Types | Public Member Functions | Static Public Member Functions | Public Attributes | Private Member Functions | List of all members
Concurrency::details::_Task_impl_base Struct Referenceabstract

The base implementation of a first-class task. This class contains all the non-type specific implementation details of the task. More...

#include <ppltasks.h>

Inheritance diagram for Concurrency::details::_Task_impl_base:
Concurrency::details::_Task_impl< _ReturnType >

Public Types

enum  _TaskInternalState {
  _Created, _Started, _PendingCancel, _Completed,
  _Canceled
}
 
typedef _ContinuationTaskHandleBase_ContinuationList
 

Public Member Functions

 _Task_impl_base (_CancellationTokenState *_PTokenState, scheduler_ptr _Scheduler_arg)
 
virtual ~_Task_impl_base ()
 
task_status _Wait ()
 
virtual bool _CancelAndRunContinuations (bool _SynchronousCancel, bool _UserException, bool _PropagatedFromAncestor, const std::shared_ptr< _ExceptionHolder > &_ExHolder)=0
 Requests cancellation on the task and schedules continuations if the task can be transitioned to a terminal state. More...
 
bool _Cancel (bool _SynchronousCancel)
 
bool _CancelWithExceptionHolder (const std::shared_ptr< _ExceptionHolder > &_ExHolder, bool _PropagatedFromAncestor)
 
bool _CancelWithException (const std::exception_ptr &_Exception)
 
void _RegisterCancellation (std::weak_ptr< _Task_impl_base > _WeakPtr)
 
void _DeregisterCancellation ()
 
bool _IsCreated ()
 
bool _IsStarted ()
 
bool _IsPendingCancel ()
 
bool _IsCompleted ()
 
bool _IsCanceled ()
 
bool _HasUserException ()
 
const std::shared_ptr< _ExceptionHolder > & _GetExceptionHolder ()
 
bool _IsApartmentAware ()
 
void _SetAsync (bool _Async=true)
 
_TaskCreationCallstack _GetTaskCreationCallstack ()
 
void _SetTaskCreationCallstack (const _TaskCreationCallstack &_Callstack)
 
void _ScheduleTask (_UnrealizedChore_t *_PTaskHandle, _TaskInliningMode_t _InliningMode)
 Helper function to schedule the task on the Task Collection. More...
 
void _RunContinuation (_ContinuationTaskHandleBase *_PTaskHandle)
 Function executes a continuation. This function is recorded by a parent task implementation when a continuation is created in order to execute later. More...
 
void _ScheduleContinuationTask (_ContinuationTaskHandleBase *_PTaskHandle)
 
void _ScheduleContinuation (_ContinuationTaskHandleBase *_PTaskHandle)
 Schedule the actual continuation. This will either schedule the function on the continuation task's implementation if the task has completed or append it to a list of functions to execute when the task actually does complete. More...
 
void _RunTaskContinuations ()
 
scheduler_ptr _GetScheduler () const
 

Static Public Member Functions

static _CRTIMP2 bool __cdecl _IsNonBlockingThread ()
 
template<typename _ReturnType , typename _InternalReturnType >
static void _AsyncInit (const typename _Task_ptr< _ReturnType >::_Type &_OuterTask, const task< _InternalReturnType > &_UnwrappedTask)
 

Public Attributes

volatile _TaskInternalState _M_TaskState
 
bool _M_fFromAsync
 
bool _M_fUnwrappedTask
 
std::shared_ptr< _ExceptionHolder_M_exceptionHolder
 
std::mutex _M_ContinuationsCritSec
 
_ContinuationList _M_Continuations
 
_CancellationTokenState_M_pTokenState
 
_CancellationTokenRegistration_M_pRegistration
 
::Concurrency::details::_TaskCollection_t _M_TaskCollection
 
_TaskCreationCallstack _M_pTaskCreationCallstack
 
_TaskEventLogger _M_taskEventLogger
 

Private Member Functions

 _Task_impl_base (const _Task_impl_base &)
 
_Task_impl_base const & operator= (_Task_impl_base const &)
 

Detailed Description

The base implementation of a first-class task. This class contains all the non-type specific implementation details of the task.

Member Typedef Documentation

Member Enumeration Documentation

Enumerator
_Created 
_Started 
_PendingCancel 
_Completed 
_Canceled 
1455  {
1456  // Tracks the state of the task, rather than the task collection on which the task is scheduled
1457  _Created,
1458  _Started,
1460  _Completed,
1461  _Canceled
1462  };

Constructor & Destructor Documentation

Concurrency::details::_Task_impl_base::_Task_impl_base ( _CancellationTokenState _PTokenState,
scheduler_ptr  _Scheduler_arg 
)
inline
1466  _M_fFromAsync(false), _M_fUnwrappedTask(false),
1467  _M_pRegistration(nullptr), _M_Continuations(nullptr), _M_TaskCollection(_Scheduler_arg),
1468  _M_taskEventLogger(this)
1469  {
1470  // Set cancellation token
1471  _M_pTokenState = _PTokenState;
1472  _ASSERTE(_M_pTokenState != nullptr);
1475  }
_ContinuationList _M_Continuations
Definition: ppltasks.h:2032
::Concurrency::details::_TaskCollection_t _M_TaskCollection
Definition: ppltasks.h:2041
_TaskEventLogger _M_taskEventLogger
Definition: ppltasks.h:2046
_CancellationTokenState * _M_pTokenState
Definition: ppltasks.h:2035
#define _ASSERTE(expr)
Definition: crtdbg.h:707
volatile _TaskInternalState _M_TaskState
Definition: ppltasks.h:2017
static _CancellationTokenState * _None()
Definition: pplcancellation_token.h:332
_CancellationTokenRegistration * _M_pRegistration
Definition: ppltasks.h:2038
bool _M_fUnwrappedTask
Definition: ppltasks.h:2022
bool _M_fFromAsync
Definition: ppltasks.h:2020
long _Reference()
Definition: pplcancellation_token.h:62
virtual Concurrency::details::_Task_impl_base::~_Task_impl_base ( )
inlinevirtual
1478  {
1479  _ASSERTE(_M_pTokenState != nullptr);
1481  {
1483  }
1484  }
_CancellationTokenState * _M_pTokenState
Definition: ppltasks.h:2035
#define _ASSERTE(expr)
Definition: crtdbg.h:707
static _CancellationTokenState * _None()
Definition: pplcancellation_token.h:332
long _Release()
Definition: pplcancellation_token.h:73
Concurrency::details::_Task_impl_base::_Task_impl_base ( const _Task_impl_base )
private

Member Function Documentation

template<typename _ReturnType , typename _InternalReturnType >
static void Concurrency::details::_Task_impl_base::_AsyncInit ( const typename _Task_ptr< _ReturnType >::_Type _OuterTask,
const task< _InternalReturnType > &  _UnwrappedTask 
)
inlinestatic
1977  {
1978  _ASSERTE(_OuterTask->_M_fUnwrappedTask && !_OuterTask->_IsCanceled());
1979 
1980  //
1981  // We must ensure that continuations off _OuterTask (especially exception handling ones) continue to function in the
1982  // presence of an exception flowing out of the inner task _UnwrappedTask. This requires an exception handling continuation
1983  // off the inner task which does the appropriate funnelling to the outer one. We use _Then instead of then to prevent
1984  // the exception from being marked as observed by our internal continuation. This continuation must be scheduled regardless
1985  // of whether or not the _OuterTask task is canceled.
1986  //
1987  _UnwrappedTask._Then([_OuterTask] (task<_InternalReturnType> _AncestorTask) {
1988 
1989  if (_AncestorTask._GetImpl()->_IsCompleted())
1990  {
1991  _OuterTask->_FinalizeAndRunContinuations(_AncestorTask._GetImpl()->_GetResult());
1992  }
1993  else
1994  {
1995  _ASSERTE(_AncestorTask._GetImpl()->_IsCanceled());
1996  if (_AncestorTask._GetImpl()->_HasUserException())
1997  {
1998  // Set _PropagatedFromAncestor to false, since _AncestorTask is not an ancestor of _UnwrappedTask.
1999  // Instead, it is the enclosing task.
2000  _OuterTask->_CancelWithExceptionHolder(_AncestorTask._GetImpl()->_GetExceptionHolder(), false);
2001  }
2002  else
2003  {
2004  _OuterTask->_Cancel(true);
2005  }
2006  }
2007  }, nullptr, details::_DefaultAutoInline);
2008 
2009  }
Definition: pplinterface.h:226
#define _ASSERTE(expr)
Definition: crtdbg.h:707
bool Concurrency::details::_Task_impl_base::_Cancel ( bool  _SynchronousCancel)
inline
1598  {
1599  // Send in a dummy value for exception. It is not used when the first parameter is false.
1600  return _CancelAndRunContinuations(_SynchronousCancel, false, false, _M_exceptionHolder);
1601  }
std::shared_ptr< _ExceptionHolder > _M_exceptionHolder
Definition: ppltasks.h:2027
virtual bool _CancelAndRunContinuations(bool _SynchronousCancel, bool _UserException, bool _PropagatedFromAncestor, const std::shared_ptr< _ExceptionHolder > &_ExHolder)=0
Requests cancellation on the task and schedules continuations if the task can be transitioned to a te...
virtual bool Concurrency::details::_Task_impl_base::_CancelAndRunContinuations ( bool  _SynchronousCancel,
bool  _UserException,
bool  _PropagatedFromAncestor,
const std::shared_ptr< _ExceptionHolder > &  _ExHolder 
)
pure virtual

Requests cancellation on the task and schedules continuations if the task can be transitioned to a terminal state.

Parameters
_SynchronousCancelSet to true if the cancel takes place as a result of the task body encountering an exception, or because an ancestor or task_completion_event the task was registered with were canceled with an exception. A synchronous cancel is one that assures the task could not be running on a different thread at the time the cancellation is in progress. An asynchronous cancel is one where the thread performing the cancel has no control over the thread that could be executing the task, that is the task could execute concurrently while the cancellation is in progress.
_UserExceptionWhether an exception other than the internal runtime cancellation exceptions caused this cancellation.
_PropagatedFromAncestorWhether this exception came from an ancestor task or a task_completion_event as opposed to an exception that was encountered by the task itself. Only valid when _UserException is set to true.
_ExHolderThe exception holder that represents the exception. Only valid when _UserException is set to true.

Implemented in Concurrency::details::_Task_impl< _ReturnType >.

bool Concurrency::details::_Task_impl_base::_CancelWithException ( const std::exception_ptr &  _Exception)
inline
1610  {
1611  // This task was canceled because the task body encountered an exception.
1613  return _CancelAndRunContinuations(true, true, false, std::make_shared<_ExceptionHolder>(_Exception, _GetTaskCreationCallstack()));
1614  }
bool _HasUserException()
Definition: ppltasks.h:1667
virtual bool _CancelAndRunContinuations(bool _SynchronousCancel, bool _UserException, bool _PropagatedFromAncestor, const std::shared_ptr< _ExceptionHolder > &_ExHolder)=0
Requests cancellation on the task and schedules continuations if the task can be transitioned to a te...
#define _ASSERTE(expr)
Definition: crtdbg.h:707
_TaskCreationCallstack _GetTaskCreationCallstack()
Definition: ppltasks.h:1688
bool Concurrency::details::_Task_impl_base::_CancelWithExceptionHolder ( const std::shared_ptr< _ExceptionHolder > &  _ExHolder,
bool  _PropagatedFromAncestor 
)
inline
1604  {
1605  // This task was canceled because an ancestor task encountered an exception.
1606  return _CancelAndRunContinuations(true, true, _PropagatedFromAncestor, _ExHolder);
1607  }
virtual bool _CancelAndRunContinuations(bool _SynchronousCancel, bool _UserException, bool _PropagatedFromAncestor, const std::shared_ptr< _ExceptionHolder > &_ExHolder)=0
Requests cancellation on the task and schedules continuations if the task can be transitioned to a te...
void Concurrency::details::_Task_impl_base::_DeregisterCancellation ( )
inline
1633  {
1634  if (_M_pRegistration != nullptr)
1635  {
1638  _M_pRegistration = nullptr;
1639  }
1640  }
_CancellationTokenState * _M_pTokenState
Definition: ppltasks.h:2035
void _DeregisterCallback(_In_ _CancellationTokenRegistration *_PRegistration)
Definition: pplcancellation_token.h:418
_CancellationTokenRegistration * _M_pRegistration
Definition: ppltasks.h:2038
long _Release()
Definition: pplcancellation_token.h:73
const std::shared_ptr<_ExceptionHolder>& Concurrency::details::_Task_impl_base::_GetExceptionHolder ( )
inline
1673  {
1675  return _M_exceptionHolder;
1676  }
std::shared_ptr< _ExceptionHolder > _M_exceptionHolder
Definition: ppltasks.h:2027
bool _HasUserException()
Definition: ppltasks.h:1667
#define _ASSERTE(expr)
Definition: crtdbg.h:707
scheduler_ptr Concurrency::details::_Task_impl_base::_GetScheduler ( ) const
inline
2012  {
2014  }
::Concurrency::details::_TaskCollection_t _M_TaskCollection
Definition: ppltasks.h:2041
::Concurrency::scheduler_ptr _GetScheduler() const
Definition: pplwin.h:229
_TaskCreationCallstack Concurrency::details::_Task_impl_base::_GetTaskCreationCallstack ( )
inline
1689  {
1691  }
_TaskCreationCallstack _M_pTaskCreationCallstack
Definition: ppltasks.h:2044
bool Concurrency::details::_Task_impl_base::_HasUserException ( )
inline
1668  {
1669  return static_cast<bool>(_M_exceptionHolder);
1670  }
std::shared_ptr< _ExceptionHolder > _M_exceptionHolder
Definition: ppltasks.h:2027
bool Concurrency::details::_Task_impl_base::_IsApartmentAware ( )
inline
1679  {
1680  return _M_fFromAsync;
1681  }
bool _M_fFromAsync
Definition: ppltasks.h:2020
bool Concurrency::details::_Task_impl_base::_IsCanceled ( )
inline
1663  {
1664  return (_M_TaskState == _Canceled);
1665  }
volatile _TaskInternalState _M_TaskState
Definition: ppltasks.h:2017
bool Concurrency::details::_Task_impl_base::_IsCompleted ( )
inline
1658  {
1659  return (_M_TaskState == _Completed);
1660  }
volatile _TaskInternalState _M_TaskState
Definition: ppltasks.h:2017
bool Concurrency::details::_Task_impl_base::_IsCreated ( )
inline
1643  {
1644  return (_M_TaskState == _Created);
1645  }
volatile _TaskInternalState _M_TaskState
Definition: ppltasks.h:2017
static _CRTIMP2 bool __cdecl Concurrency::details::_Task_impl_base::_IsNonBlockingThread ( )
static
bool Concurrency::details::_Task_impl_base::_IsPendingCancel ( )
inline
1653  {
1654  return (_M_TaskState == _PendingCancel);
1655  }
volatile _TaskInternalState _M_TaskState
Definition: ppltasks.h:2017
bool Concurrency::details::_Task_impl_base::_IsStarted ( )
inline
1648  {
1649  return (_M_TaskState == _Started);
1650  }
volatile _TaskInternalState _M_TaskState
Definition: ppltasks.h:2017
void Concurrency::details::_Task_impl_base::_RegisterCancellation ( std::weak_ptr< _Task_impl_base _WeakPtr)
inline
1617  {
1619 
1620  auto _CancellationCallback = [_WeakPtr](){
1621  // Taking ownership of the task prevents dead lock during destruction
1622  // if the destructor waits for the cancellations to be finished
1623  auto _task = _WeakPtr.lock();
1624  if (_task != nullptr)
1625  _task->_Cancel(false);
1626  };
1627 
1628  _M_pRegistration = new details::_CancellationTokenCallback<decltype(_CancellationCallback)>(_CancellationCallback);
1630  }
_CancellationTokenRegistration * _RegisterCallback(TaskProc_t _PCallback, _In_ void *_PData, int _InitialRefs=1)
Definition: pplcancellation_token.h:386
_CancellationTokenState * _M_pTokenState
Definition: ppltasks.h:2035
#define _ASSERTE(expr)
Definition: crtdbg.h:707
_CancellationTokenRegistration * _M_pRegistration
Definition: ppltasks.h:2038
static bool _IsValid(_In_opt_ _CancellationTokenState *_PToken)
Definition: pplcancellation_token.h:337
void Concurrency::details::_Task_impl_base::_RunContinuation ( _ContinuationTaskHandleBase _PTaskHandle)
inline

Function executes a continuation. This function is recorded by a parent task implementation when a continuation is created in order to execute later.

Parameters
_PTaskHandleThe continuation task chore handle that need to be executed.
1744  {
1745  _Task_ptr_base _ImplBase = _PTaskHandle->_GetTaskImplBase();
1746  if (_IsCanceled() && !_PTaskHandle->_M_isTaskBasedContinuation)
1747  {
1748  if (_HasUserException())
1749  {
1750  // If the ancestor encountered an exception, transfer the exception to the continuation
1751  // This traverses down the tree to propagate the exception.
1752  _ImplBase->_CancelWithExceptionHolder(_GetExceptionHolder(), true);
1753  }
1754  else
1755  {
1756  // If the ancestor was canceled, then your own execution should be canceled.
1757  // This traverses down the tree to cancel it.
1758  _ImplBase->_Cancel(true);
1759  }
1760  }
1761  else
1762  {
1763  // This can only run when the ancestor has completed or it's a task based continuation that fires when a task is canceled
1764  // (with or without a user exception).
1765  _ASSERTE(_IsCompleted() || _PTaskHandle->_M_isTaskBasedContinuation);
1766  _ASSERTE(!_ImplBase->_IsCanceled());
1767  return _ImplBase->_ScheduleContinuationTask(_PTaskHandle);
1768  }
1769 
1770  // If the handle is not scheduled, we need to manually delete it.
1771  delete _PTaskHandle;
1772  }
bool _IsCompleted()
Definition: ppltasks.h:1657
bool _HasUserException()
Definition: ppltasks.h:1667
std::shared_ptr< _Task_impl_base > _Task_ptr_base
Definition: ppltasks.h:1287
bool _IsCanceled()
Definition: ppltasks.h:1662
#define _ASSERTE(expr)
Definition: crtdbg.h:707
const std::shared_ptr< _ExceptionHolder > & _GetExceptionHolder()
Definition: ppltasks.h:1672
void Concurrency::details::_Task_impl_base::_RunTaskContinuations ( )
inline
1902  {
1903  // The link list can no longer be modified at this point,
1904  // since all following up continuations will be scheduled by themselves.
1905  _ContinuationList _Cur = _M_Continuations, _Next;
1906  _M_Continuations = nullptr;
1907  while (_Cur)
1908  {
1909  // Current node might be deleted after running,
1910  // so we must fetch the next first.
1911  _Next = _Cur->_M_next;
1912  _RunContinuation(_Cur);
1913  _Cur = _Next;
1914  }
1915  }
_ContinuationList _M_Continuations
Definition: ppltasks.h:2032
void _RunContinuation(_ContinuationTaskHandleBase *_PTaskHandle)
Function executes a continuation. This function is recorded by a parent task implementation when a co...
Definition: ppltasks.h:1743
_ContinuationTaskHandleBase * _M_next
Definition: ppltasks.h:1292
_ContinuationTaskHandleBase * _ContinuationList
Definition: ppltasks.h:2029
void Concurrency::details::_Task_impl_base::_ScheduleContinuation ( _ContinuationTaskHandleBase _PTaskHandle)
inline

Schedule the actual continuation. This will either schedule the function on the continuation task's implementation if the task has completed or append it to a list of functions to execute when the task actually does complete.

Template Parameters
_FuncInputTypeThe input type of the task.
_FuncOutputTypeThe output type of the task.
1836  {
1837  enum { _Nothing, _Schedule, _Cancel, _CancelWithException } _Do = _Nothing;
1838 
1839  // If the task has canceled, cancel the continuation. If the task has completed, execute the continuation right away.
1840  // Otherwise, add it to the list of pending continuations
1841  {
1842  ::std::lock_guard<std::mutex> _LockHolder(_M_ContinuationsCritSec);
1843  if (_IsCompleted() || (_IsCanceled() && _PTaskHandle->_M_isTaskBasedContinuation))
1844  {
1845  _Do = _Schedule;
1846  }
1847  else if (_IsCanceled())
1848  {
1849  if (_HasUserException())
1850  {
1851  _Do = _CancelWithException;
1852  }
1853  else
1854  {
1855  _Do = _Cancel;
1856  }
1857  }
1858  else
1859  {
1860  // chain itself on the continuation chain.
1861  _PTaskHandle->_M_next = _M_Continuations;
1862  _M_Continuations = _PTaskHandle;
1863  }
1864  }
1865 
1866  // Cancellation and execution of continuations should be performed after releasing the lock. Continuations off of
1867  // async tasks may execute inline.
1868  switch (_Do)
1869  {
1870  case _Schedule:
1871  {
1872  _PTaskHandle->_GetTaskImplBase()->_ScheduleContinuationTask(_PTaskHandle);
1873  break;
1874  }
1875  case _Cancel:
1876  {
1877  // If the ancestor was canceled, then your own execution should be canceled.
1878  // This traverses down the tree to cancel it.
1879  _PTaskHandle->_GetTaskImplBase()->_Cancel(true);
1880 
1881  delete _PTaskHandle;
1882  break;
1883  }
1884  case _CancelWithException:
1885  {
1886  // If the ancestor encountered an exception, transfer the exception to the continuation
1887  // This traverses down the tree to propagate the exception.
1888  _PTaskHandle->_GetTaskImplBase()->_CancelWithExceptionHolder(_GetExceptionHolder(), true);
1889 
1890  delete _PTaskHandle;
1891  break;
1892  }
1893  case _Nothing:
1894  default:
1895  // In this case, we have inserted continuation to continuation chain,
1896  // nothing more need to be done, just leave.
1897  break;
1898  }
1899  }
bool _IsCompleted()
Definition: ppltasks.h:1657
bool _HasUserException()
Definition: ppltasks.h:1667
_ContinuationList _M_Continuations
Definition: ppltasks.h:2032
bool _IsCanceled()
Definition: ppltasks.h:1662
bool _Cancel(bool _SynchronousCancel)
Definition: ppltasks.h:1597
bool _CancelWithException(const std::exception_ptr &_Exception)
Definition: ppltasks.h:1609
std::mutex _M_ContinuationsCritSec
Definition: ppltasks.h:2031
virtual _Task_ptr_base _GetTaskImplBase() const =0
const std::shared_ptr< _ExceptionHolder > & _GetExceptionHolder()
Definition: ppltasks.h:1672
void Concurrency::details::_Task_impl_base::_ScheduleContinuationTask ( _ContinuationTaskHandleBase _PTaskHandle)
inline
1776  {
1777 
1779  // Ensure that the continuation runs in proper context (this might be on a Concurrency Runtime thread or in a different Windows Runtime apartment)
1780  if (_PTaskHandle->_M_continuationContext._HasCapturedContext())
1781  {
1782  // For those continuations need to be scheduled inside captured context, we will try to apply automatic inlining to their inline modes,
1783  // if they haven't been specified as _ForceInline yet. This change will encourage those continuations to be executed inline so that reduce
1784  // the cost of marshaling.
1785  // For normal continuations we won't do any change here, and their inline policies are completely decided by ._ThenImpl method.
1786  if (_PTaskHandle->_M_inliningMode != details::_ForceInline)
1787  {
1788  _PTaskHandle->_M_inliningMode = details::_DefaultAutoInline;
1789  }
1790  _ScheduleFuncWithAutoInline([_PTaskHandle]() {
1791  // Note that we cannot directly capture "this" pointer, instead, we should use _TaskImplPtr, a shared_ptr to the _Task_impl_base.
1792  // Because "this" pointer will be invalid as soon as _PTaskHandle get deleted. _PTaskHandle will be deleted after being scheduled.
1793  auto _TaskImplPtr = _PTaskHandle->_GetTaskImplBase();
1794  if (details::_ContextCallback::_CaptureCurrent() == _PTaskHandle->_M_continuationContext)
1795  {
1796  _TaskImplPtr->_ScheduleTask(_PTaskHandle, details::_ForceInline);
1797  }
1798  else
1799  {
1800  //
1801  // It's entirely possible that the attempt to marshal the call into a differing context will fail. In this case, we need to handle
1802  // the exception and mark the continuation as canceled with the appropriate exception. There is one slight hitch to this:
1803  //
1804  // NOTE: COM's legacy behavior is to swallow SEH exceptions and marshal them back as HRESULTS. This will in effect turn an SEH into
1805  // a C++ exception that gets tagged on the task. One unfortunate result of this is that various pieces of the task infrastructure will
1806  // not be in a valid state after this in /EHsc (due to the lack of destructors running, etc...).
1807  //
1808  _TRY_BEGIN
1809  _PTaskHandle->_M_continuationContext._CallInContext( [_PTaskHandle, _TaskImplPtr](){
1810  _TaskImplPtr->_ScheduleTask(_PTaskHandle, details::_ForceInline);
1811  });
1812  _CATCH_ALL
1813  _TaskImplPtr->_CancelWithException(std::current_exception());
1814  _CATCH_END
1815  }
1816  }, _PTaskHandle->_M_inliningMode);
1817  }
1818  else
1819  {
1820  _ScheduleTask(_PTaskHandle, _PTaskHandle->_M_inliningMode);
1821  }
1822  }
Definition: pplinterface.h:228
#define _TRY_BEGIN
Definition: xstddef:26
#define _CATCH_END
Definition: xstddef:29
_TaskEventLogger _M_taskEventLogger
Definition: ppltasks.h:2046
_CRTIMP2 void __thiscall _LogScheduleTask(bool _isContinuation)
Definition: pplinterface.h:226
static _ContextCallback _CaptureCurrent()
Definition: ppltasks.h:503
#define _CATCH_ALL
Definition: xstddef:28
void _ScheduleTask(_UnrealizedChore_t *_PTaskHandle, _TaskInliningMode_t _InliningMode)
Helper function to schedule the task on the Task Collection.
Definition: ppltasks.h:1707
exception_ptr current_exception() _NOEXCEPT
Definition: exception:366
static void _ScheduleFuncWithAutoInline(const std::function< void()> &_Func, _TaskInliningMode_t _InliningMode)
Schedule a functor with automatic inlining. Note that this is "fire and forget" scheduling, which cannot be waited on or canceled after scheduling. This schedule method will perform automatic inlining base on .
Definition: ppltasks.h:492
void Concurrency::details::_Task_impl_base::_ScheduleTask ( _UnrealizedChore_t _PTaskHandle,
_TaskInliningMode_t  _InliningMode 
)
inline

Helper function to schedule the task on the Task Collection.

Parameters
_PTaskHandleThe task chore handle that need to be executed.
_InliningModeThe inlining scheduling policy for current _PTaskHandle.
1708  {
1709  _TRY_BEGIN
1710  _M_TaskCollection._ScheduleTask(_PTaskHandle, _InliningMode);
1711  _CATCH(const task_canceled &)
1712  // task_canceled is a special exception thrown by cancel_current_task. The spec states that cancel_current_task
1713  // must be called from code that is executed within the task (throwing it from parallel work created by and waited
1714  // upon by the task is acceptable). We can safely assume that the task wrapper _PPLTaskHandle::operator() has seen
1715  // the exception and canceled the task. Swallow the exception here.
1716  _ASSERTE(_IsCanceled());
1717  _CATCH(const _Interruption_exception &)
1718  // The _TaskCollection will never be an interruption point since it has a none token.
1719  _ASSERTE(false);
1720  _CATCH_ALL
1721  // The exception could have come from two places:
1722  // 1. From the chore body, so it already should have been caught and canceled.
1723  // In this case swallow the exception.
1724  // 2. From trying to actually schedule the task on the scheduler.
1725  // In this case cancel the task with the current exception, otherwise the
1726  // task will never be signaled leading to deadlock when waiting on the task.
1727 
1728  if (!_HasUserException())
1729  {
1731  }
1732  _CATCH_END
1733  }
bool _HasUserException()
Definition: ppltasks.h:1667
#define _TRY_BEGIN
Definition: xstddef:26
#define _CATCH(x)
Definition: xstddef:27
bool _IsCanceled()
Definition: ppltasks.h:1662
#define _CATCH_END
Definition: xstddef:29
::Concurrency::details::_TaskCollection_t _M_TaskCollection
Definition: ppltasks.h:2041
if(_Source==NULL||_DestinationSize< _SourceSize)
Definition: corecrt_memcpy_s.h:48
bool _CancelWithException(const std::exception_ptr &_Exception)
Definition: ppltasks.h:1609
#define _ASSERTE(expr)
Definition: crtdbg.h:707
#define false
Definition: stdbool.h:16
#define _CATCH_ALL
Definition: xstddef:28
void _ScheduleTask(_TaskProcHandle_t *_Parameter, _TaskInliningMode _InliningMode)
Definition: pplwin.h:189
exception_ptr current_exception() _NOEXCEPT
Definition: exception:366
void Concurrency::details::_Task_impl_base::_SetAsync ( bool  _Async = true)
inline
1684  {
1685  _M_fFromAsync = _Async;
1686  }
bool _M_fFromAsync
Definition: ppltasks.h:2020
void Concurrency::details::_Task_impl_base::_SetTaskCreationCallstack ( const _TaskCreationCallstack _Callstack)
inline
1694  {
1695  _M_pTaskCreationCallstack = _Callstack;
1696  }
_TaskCreationCallstack _M_pTaskCreationCallstack
Definition: ppltasks.h:2044
task_status Concurrency::details::_Task_impl_base::_Wait ( )
inline
1487  {
1488  bool _DoWait = true;
1489 
1490  if (_IsNonBlockingThread())
1491  {
1492  // In order to prevent Windows Runtime STA threads from blocking the UI, calling task.wait() task.get() is illegal
1493  // if task has not been completed.
1494  if (!_IsCompleted() && !_IsCanceled())
1495  {
1496  _THROW_NCEE(invalid_operation, "Illegal to wait on a task in a Windows Runtime STA");
1497  }
1498  else
1499  {
1500  // Task Continuations are 'scheduled' *inside* the chore that is executing on the ancestor's task group. If a continuation
1501  // needs to be marshalled to a different apartment instead of scheduling, we make a synchronous cross-apartment COM
1502  // call to execute the continuation. If it then happens to do something which waits on the ancestor (say it calls .get(),
1503  // which task based continuations are wont to do), waiting on the task group results in waiting on the chore that is making
1504  // this synchronous callback, which causes a deadlock. To avoid this, we test the state of the ancestor's event,
1505  // and we will NOT wait on it if it has finished execution (which means now we are in the inline synchronous callback).
1506  _DoWait = false;
1507  }
1508  }
1509 
1510  if (_DoWait)
1511  {
1512  // If this task was created from a Windows Runtime async operation, do not attempt to inline it. The
1513  // async operation will take place on a thread in the appropriate apartment Simply wait for the completed
1514  // event to be set.
1515  if (_M_fFromAsync)
1516  {
1518  }
1519  else
1520  {
1521  // Wait on the task collection to complete. The task collection is guaranteed to still be
1522  // valid since the task must be still within scope so that the _Task_impl_base destructor
1523  // has not yet been called. This call to _Wait potentially inlines execution of work.
1524  _TRY_BEGIN
1525  // Invoking wait on a task collection resets the state of the task collection. This means that
1526  // if the task collection itself were canceled, or had encountered an exception, only the first
1527  // call to wait will receive this status. However, both cancellation and exceptions flowing through
1528  // tasks set state in the task impl itself.
1529 
1530  // When it returns cancelled, either work chore or the cancel thread should already have set task's state
1531  // properly -- cancelled state or completed state (because there was no interruption point).
1532  // For tasks with unwrapped tasks, we should not change the state of current task, since the unwrapped task are still running.
1534  _CATCH(details::_Interruption_exception&)
1535  // The _TaskCollection will never be an interruption point since it has a none token.
1536  _ASSERTE(false);
1537  _CATCH(task_canceled&)
1538  // task_canceled is a special exception thrown by cancel_current_task. The spec states that cancel_current_task
1539  // must be called from code that is executed within the task (throwing it from parallel work created by and waited
1540  // upon by the task is acceptable). We can safely assume that the task wrapper _PPLTaskHandle::operator() has seen
1541  // the exception and canceled the task. Swallow the exception here.
1542  _ASSERTE(_IsCanceled());
1543  _CATCH_ALL
1544  // It's possible the task body hasn't seen the exception; if so we need to cancel with exception here.
1545  if(!_HasUserException())
1546  {
1548  }
1549  // Rethrow will mark the exception as observed.
1550  _M_exceptionHolder->_RethrowUserException();
1551  _CATCH_END
1552 
1553  // If the lambda body for this task (executed or waited upon in _RunAndWait above) happened to return a task
1554  // which is to be unwrapped and plumbed to the output of this task, we must not only wait on the lambda body, we must
1555  // wait on the **INNER** body. It is in theory possible that we could inline such if we plumb a series of things through;
1556  // however, this takes the tact of simply waiting upon the completion signal.
1557  if (_M_fUnwrappedTask)
1558  {
1560  }
1561  }
1562  }
1563 
1564  if (_HasUserException())
1565  {
1566  _M_exceptionHolder->_RethrowUserException();
1567  }
1568  else if (_IsCanceled())
1569  {
1570  return canceled;
1571  }
1573  return completed;
1574  }
std::shared_ptr< _ExceptionHolder > _M_exceptionHolder
Definition: ppltasks.h:2027
bool _IsCompleted()
Definition: ppltasks.h:1657
bool _HasUserException()
Definition: ppltasks.h:1667
void _RunAndWait()
Definition: pplwin.h:213
#define _TRY_BEGIN
Definition: xstddef:26
#define _CATCH(x)
Definition: xstddef:27
bool _IsCanceled()
Definition: ppltasks.h:1662
#define _CATCH_END
Definition: xstddef:29
::Concurrency::details::_TaskCollection_t _M_TaskCollection
Definition: ppltasks.h:2041
if(_Source==NULL||_DestinationSize< _SourceSize)
Definition: corecrt_memcpy_s.h:48
bool _CancelWithException(const std::exception_ptr &_Exception)
Definition: ppltasks.h:1609
#define _ASSERTE(expr)
Definition: crtdbg.h:707
#define _THROW_NCEE(x, y)
Definition: xstddef:51
The tasks queued to the task_group or structured_task_group object completed successfully.
Definition: pplinterface.h:115
The task_group or structured_task_group object was canceled. One or more tasks may not have executed...
Definition: pplinterface.h:121
#define false
Definition: stdbool.h:16
#define _CATCH_ALL
Definition: xstddef:28
bool _M_fUnwrappedTask
Definition: ppltasks.h:2022
bool _M_fFromAsync
Definition: ppltasks.h:2020
static _CRTIMP2 bool __cdecl _IsNonBlockingThread()
exception_ptr current_exception() _NOEXCEPT
Definition: exception:366
void _Wait()
Definition: pplwin.h:218
_Task_impl_base const& Concurrency::details::_Task_impl_base::operator= ( _Task_impl_base const &  )
private

Member Data Documentation

_ContinuationList Concurrency::details::_Task_impl_base::_M_Continuations
std::mutex Concurrency::details::_Task_impl_base::_M_ContinuationsCritSec
std::shared_ptr<_ExceptionHolder> Concurrency::details::_Task_impl_base::_M_exceptionHolder
bool Concurrency::details::_Task_impl_base::_M_fFromAsync
bool Concurrency::details::_Task_impl_base::_M_fUnwrappedTask
_CancellationTokenRegistration* Concurrency::details::_Task_impl_base::_M_pRegistration
_TaskCreationCallstack Concurrency::details::_Task_impl_base::_M_pTaskCreationCallstack
_CancellationTokenState* Concurrency::details::_Task_impl_base::_M_pTokenState
::Concurrency::details::_TaskCollection_t Concurrency::details::_Task_impl_base::_M_TaskCollection
_TaskEventLogger Concurrency::details::_Task_impl_base::_M_taskEventLogger
volatile _TaskInternalState Concurrency::details::_Task_impl_base::_M_TaskState

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