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

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
 
::Concurrency::extensibility::critical_section_t _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 
1648  {
1649  // Tracks the state of the task, rather than the task collection on which the task is scheduled
1650  _Created,
1651  _Started,
1653  _Completed,
1654  _Canceled
1655  };

Constructor & Destructor Documentation

Concurrency::details::_Task_impl_base::_Task_impl_base ( _CancellationTokenState _PTokenState,
scheduler_ptr  _Scheduler_arg 
)
inline
1659  _M_fFromAsync(false), _M_fUnwrappedTask(false),
1660  _M_pRegistration(nullptr), _M_Continuations(nullptr), _M_TaskCollection(_Scheduler_arg),
1661  _M_taskEventLogger(this)
1662  {
1663  // Set cancelation token
1664  _M_pTokenState = _PTokenState;
1665  _ASSERTE(_M_pTokenState != nullptr);
1668  }
_ContinuationList _M_Continuations
Definition: ppltasks.h:2296
::Concurrency::details::_TaskCollection_t _M_TaskCollection
Definition: ppltasks.h:2305
_TaskEventLogger _M_taskEventLogger
Definition: ppltasks.h:2310
_CancellationTokenState * _M_pTokenState
Definition: ppltasks.h:2299
#define _ASSERTE(expr)
Definition: crtdbg.h:216
volatile _TaskInternalState _M_TaskState
Definition: ppltasks.h:2281
static _CancellationTokenState * _None()
Definition: pplcancellation_token.h:328
_CancellationTokenRegistration * _M_pRegistration
Definition: ppltasks.h:2302
bool _M_fUnwrappedTask
Definition: ppltasks.h:2286
bool _M_fFromAsync
Definition: ppltasks.h:2284
long _Reference()
Definition: pplcancellation_token.h:60
virtual Concurrency::details::_Task_impl_base::~_Task_impl_base ( )
inlinevirtual
1671  {
1672  _ASSERTE(_M_pTokenState != nullptr);
1674  {
1676  }
1677  }
_CancellationTokenState * _M_pTokenState
Definition: ppltasks.h:2299
#define _ASSERTE(expr)
Definition: crtdbg.h:216
static _CancellationTokenState * _None()
Definition: pplcancellation_token.h:328
long _Release()
Definition: pplcancellation_token.h:71
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
2241  {
2242  _ASSERTE(_OuterTask->_M_fUnwrappedTask && !_OuterTask->_IsCanceled());
2243 
2244  //
2245  // We must ensure that continuations off _OuterTask (especially exception handling ones) continue to function in the
2246  // presence of an exception flowing out of the inner task _UnwrappedTask. This requires an exception handling continuation
2247  // off the inner task which does the appropriate funnelling to the outer one. We use _Then instead of then to prevent
2248  // the exception from being marked as observed by our internal continuation. This continuation must be scheduled regardless
2249  // of whether or not the _OuterTask task is canceled.
2250  //
2251  _UnwrappedTask._Then([_OuterTask] (task<_InternalReturnType> _AncestorTask) {
2252 
2253  if (_AncestorTask._GetImpl()->_IsCompleted())
2254  {
2255  _OuterTask->_FinalizeAndRunContinuations(_AncestorTask._GetImpl()->_GetResult());
2256  }
2257  else
2258  {
2259  _ASSERTE(_AncestorTask._GetImpl()->_IsCanceled());
2260  if (_AncestorTask._GetImpl()->_HasUserException())
2261  {
2262  // Set _PropagatedFromAncestor to false, since _AncestorTask is not an ancestor of _UnwrappedTask.
2263  // Instead, it is the enclosing task.
2264  _OuterTask->_CancelWithExceptionHolder(_AncestorTask._GetImpl()->_GetExceptionHolder(), false);
2265  }
2266  else
2267  {
2268  _OuterTask->_Cancel(true);
2269  }
2270  }
2271  }, nullptr, details::_DefaultAutoInline);
2272 
2273  }
#define _ASSERTE(expr)
Definition: crtdbg.h:216
bool Concurrency::details::_Task_impl_base::_Cancel ( bool  _SynchronousCancel)
inline
1811  {
1812  // Send in a dummy value for exception. It is not used when the first parameter is false.
1813  return _CancelAndRunContinuations(_SynchronousCancel, false, false, _M_exceptionHolder);
1814  }
std::shared_ptr< _ExceptionHolder > _M_exceptionHolder
Definition: ppltasks.h:2291
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
1832  {
1833  // This task was canceled because the task body encountered an exception.
1835  return _CancelAndRunContinuations(true, true, false, std::make_shared<_ExceptionHolder>(_Exception, _GetTaskCreationCallstack()));
1836  }
bool _HasUserException()
Definition: ppltasks.h:1889
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:216
_TaskCreationCallstack _GetTaskCreationCallstack()
Definition: ppltasks.h:1910
bool Concurrency::details::_Task_impl_base::_CancelWithExceptionHolder ( const std::shared_ptr< _ExceptionHolder > &  _ExHolder,
bool  _PropagatedFromAncestor 
)
inline
1817  {
1818  // This task was canceled because an ancestor task encountered an exception.
1819  return _CancelAndRunContinuations(true, true, _PropagatedFromAncestor, _ExHolder);
1820  }
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
1855  {
1856  if (_M_pRegistration != nullptr)
1857  {
1860  _M_pRegistration = nullptr;
1861  }
1862  }
_CancellationTokenState * _M_pTokenState
Definition: ppltasks.h:2299
void _DeregisterCallback(_In_ _CancellationTokenRegistration *_PRegistration)
Definition: pplcancellation_token.h:415
_CancellationTokenRegistration * _M_pRegistration
Definition: ppltasks.h:2302
long _Release()
Definition: pplcancellation_token.h:71
const std::shared_ptr<_ExceptionHolder>& Concurrency::details::_Task_impl_base::_GetExceptionHolder ( )
inline
1895  {
1897  return _M_exceptionHolder;
1898  }
std::shared_ptr< _ExceptionHolder > _M_exceptionHolder
Definition: ppltasks.h:2291
bool _HasUserException()
Definition: ppltasks.h:1889
#define _ASSERTE(expr)
Definition: crtdbg.h:216
scheduler_ptr Concurrency::details::_Task_impl_base::_GetScheduler ( ) const
inline
2276  {
2278  }
::Concurrency::details::_TaskCollection_t _M_TaskCollection
Definition: ppltasks.h:2305
::Concurrency::scheduler_ptr _GetScheduler() const
Definition: pplconcrt.h:231
_TaskCreationCallstack Concurrency::details::_Task_impl_base::_GetTaskCreationCallstack ( )
inline
1911  {
1913  }
_TaskCreationCallstack _M_pTaskCreationCallstack
Definition: ppltasks.h:2308
bool Concurrency::details::_Task_impl_base::_HasUserException ( )
inline
1890  {
1891  return static_cast<bool>(_M_exceptionHolder);
1892  }
std::shared_ptr< _ExceptionHolder > _M_exceptionHolder
Definition: ppltasks.h:2291
bool Concurrency::details::_Task_impl_base::_IsApartmentAware ( )
inline
1901  {
1902  return _M_fFromAsync;
1903  }
bool _M_fFromAsync
Definition: ppltasks.h:2284
bool Concurrency::details::_Task_impl_base::_IsCanceled ( )
inline
1885  {
1886  return (_M_TaskState == _Canceled);
1887  }
volatile _TaskInternalState _M_TaskState
Definition: ppltasks.h:2281
bool Concurrency::details::_Task_impl_base::_IsCompleted ( )
inline
1880  {
1881  return (_M_TaskState == _Completed);
1882  }
volatile _TaskInternalState _M_TaskState
Definition: ppltasks.h:2281
bool Concurrency::details::_Task_impl_base::_IsCreated ( )
inline
1865  {
1866  return (_M_TaskState == _Created);
1867  }
volatile _TaskInternalState _M_TaskState
Definition: ppltasks.h:2281
bool Concurrency::details::_Task_impl_base::_IsPendingCancel ( )
inline
1875  {
1876  return (_M_TaskState == _PendingCancel);
1877  }
volatile _TaskInternalState _M_TaskState
Definition: ppltasks.h:2281
bool Concurrency::details::_Task_impl_base::_IsStarted ( )
inline
1870  {
1871  return (_M_TaskState == _Started);
1872  }
volatile _TaskInternalState _M_TaskState
Definition: ppltasks.h:2281
void Concurrency::details::_Task_impl_base::_RegisterCancellation ( std::weak_ptr< _Task_impl_base _WeakPtr)
inline
1839  {
1841 
1842  auto _CancellationCallback = [_WeakPtr](){
1843  // Taking ownership of the task prevents dead lock during destruction
1844  // if the destructor waits for the cancellations to be finished
1845  auto _task = _WeakPtr.lock();
1846  if (_task != nullptr)
1847  _task->_Cancel(false);
1848  };
1849 
1850  _M_pRegistration = new details::_CancellationTokenCallback<decltype(_CancellationCallback)>(_CancellationCallback);
1852  }
_CancellationTokenRegistration * _RegisterCallback(TaskProc_t _PCallback, _In_ void *_PData, int _InitialRefs=1)
Definition: pplcancellation_token.h:383
_CancellationTokenState * _M_pTokenState
Definition: ppltasks.h:2299
#define _ASSERTE(expr)
Definition: crtdbg.h:216
_CancellationTokenRegistration * _M_pRegistration
Definition: ppltasks.h:2302
static bool _IsValid(_In_opt_ _CancellationTokenState *_PToken)
Definition: pplcancellation_token.h:333
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.
1965  {
1966  _Task_ptr_base _ImplBase = _PTaskHandle->_GetTaskImplBase();
1967  if (_IsCanceled() && !_PTaskHandle->_M_isTaskBasedContinuation)
1968  {
1969  if (_HasUserException())
1970  {
1971  // If the ancestor encountered an exception, transfer the exception to the continuation
1972  // This traverses down the tree to propagate the exception.
1973  _ImplBase->_CancelWithExceptionHolder(_GetExceptionHolder(), true);
1974  }
1975  else
1976  {
1977  // If the ancestor was canceled, then your own execution should be canceled.
1978  // This traverses down the tree to cancel it.
1979  _ImplBase->_Cancel(true);
1980  }
1981  }
1982  else
1983  {
1984  // This can only run when the ancestor has completed or it's a task based continuation that fires when a task is canceled
1985  // (with or without a user exception).
1986  _ASSERTE(_IsCompleted() || _PTaskHandle->_M_isTaskBasedContinuation);
1987  _ASSERTE(!_ImplBase->_IsCanceled());
1988  return _ImplBase->_ScheduleContinuationTask(_PTaskHandle);
1989  }
1990 
1991  // If the handle is not scheduled, we need to manually delete it.
1992  delete _PTaskHandle;
1993  }
bool _IsCompleted()
Definition: ppltasks.h:1879
bool _HasUserException()
Definition: ppltasks.h:1889
std::shared_ptr< _Task_impl_base > _Task_ptr_base
Definition: ppltasks.h:1390
bool _IsCanceled()
Definition: ppltasks.h:1884
#define _ASSERTE(expr)
Definition: crtdbg.h:216
const std::shared_ptr< _ExceptionHolder > & _GetExceptionHolder()
Definition: ppltasks.h:1894
void Concurrency::details::_Task_impl_base::_RunTaskContinuations ( )
inline
2134  {
2135  // The link list can no longer be modified at this point,
2136  // since all following up continuations will be scheduled by themselves.
2137  _ContinuationList _Cur = _M_Continuations, _Next;
2138  _M_Continuations = nullptr;
2139  while (_Cur)
2140  {
2141  // Current node might be deleted after running,
2142  // so we must fetch the next first.
2143  _Next = _Cur->_M_next;
2144  _RunContinuation(_Cur);
2145  _Cur = _Next;
2146  }
2147  }
_ContinuationList _M_Continuations
Definition: ppltasks.h:2296
void _RunContinuation(_ContinuationTaskHandleBase *_PTaskHandle)
Function executes a continuation. This function is recorded by a parent task implementation when a co...
Definition: ppltasks.h:1964
_ContinuationTaskHandleBase * _M_next
Definition: ppltasks.h:1395
_ContinuationTaskHandleBase * _ContinuationList
Definition: ppltasks.h:2293
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.
2068  {
2069  enum { _Nothing, _Schedule, _Cancel, _CancelWithException } _Do = _Nothing;
2070 
2071  // If the task has canceled, cancel the continuation. If the task has completed, execute the continuation right away.
2072  // Otherwise, add it to the list of pending continuations
2073  {
2075  if (_IsCompleted() || (_IsCanceled() && _PTaskHandle->_M_isTaskBasedContinuation))
2076  {
2077  _Do = _Schedule;
2078  }
2079  else if (_IsCanceled())
2080  {
2081  if (_HasUserException())
2082  {
2083  _Do = _CancelWithException;
2084  }
2085  else
2086  {
2087  _Do = _Cancel;
2088  }
2089  }
2090  else
2091  {
2092  // chain itself on the continuation chain.
2093  _PTaskHandle->_M_next = _M_Continuations;
2094  _M_Continuations = _PTaskHandle;
2095  }
2096  }
2097 
2098  // Cancellation and execution of continuations should be performed after releasing the lock. Continuations off of
2099  // async tasks may execute inline.
2100  switch (_Do)
2101  {
2102  case _Schedule:
2103  {
2104  _PTaskHandle->_GetTaskImplBase()->_ScheduleContinuationTask(_PTaskHandle);
2105  break;
2106  }
2107  case _Cancel:
2108  {
2109  // If the ancestor was canceled, then your own execution should be canceled.
2110  // This traverses down the tree to cancel it.
2111  _PTaskHandle->_GetTaskImplBase()->_Cancel(true);
2112 
2113  delete _PTaskHandle;
2114  break;
2115  }
2116  case _CancelWithException:
2117  {
2118  // If the ancestor encountered an exception, transfer the exception to the continuation
2119  // This traverses down the tree to propagate the exception.
2120  _PTaskHandle->_GetTaskImplBase()->_CancelWithExceptionHolder(_GetExceptionHolder(), true);
2121 
2122  delete _PTaskHandle;
2123  break;
2124  }
2125  case _Nothing:
2126  default:
2127  // In this case, we have inserted continuation to continuation chain,
2128  // nothing more need to be done, just leave.
2129  break;
2130  }
2131  }
bool _IsCompleted()
Definition: ppltasks.h:1879
bool _HasUserException()
Definition: ppltasks.h:1889
_ContinuationList _M_Continuations
Definition: ppltasks.h:2296
bool _IsCanceled()
Definition: ppltasks.h:1884
bool _Cancel(bool _SynchronousCancel)
Definition: ppltasks.h:1810
bool _CancelWithException(const std::exception_ptr &_Exception)
Definition: ppltasks.h:1831
::Concurrency::extensibility::critical_section_t _M_ContinuationsCritSec
Definition: ppltasks.h:2295
virtual _Task_ptr_base _GetTaskImplBase() const =0
const std::shared_ptr< _ExceptionHolder > & _GetExceptionHolder()
Definition: ppltasks.h:1894
An exception safe RAII wrapper for a critical_section object.
Definition: concrt.h:3661
void Concurrency::details::_Task_impl_base::_ScheduleContinuationTask ( _ContinuationTaskHandleBase _PTaskHandle)
inline
1997  {
1998 
2000  // Ensure that the continuation runs in proper context (this might be on a Concurrency Runtime thread or in a different Windows Runtime apartment)
2001  if (_PTaskHandle->_M_continuationContext._HasCapturedContext())
2002  {
2003  // For those continuations need to be scheduled inside captured context, we will try to apply automatic inlining to their inline modes,
2004  // if they haven't been specified as _ForceInline yet. This change will encourage those continuations to be executed inline so that reduce
2005  // the cost of marshaling.
2006  // For normal continuations we won't do any change here, and their inline policies are completely decided by ._ThenImpl method.
2007  if (_PTaskHandle->_M_inliningMode != details::_ForceInline)
2008  {
2009  _PTaskHandle->_M_inliningMode = details::_DefaultAutoInline;
2010  }
2011  _ScheduleFuncWithAutoInline([_PTaskHandle]() {
2012  // Note that we cannot directly capture "this" pointer, instead, we should use _TaskImplPtr, a shared_ptr to the _Task_impl_base.
2013  // Because "this" pointer will be invalid as soon as _PTaskHandle get deleted. _PTaskHandle will be deleted after being scheduled.
2014  auto _TaskImplPtr = _PTaskHandle->_GetTaskImplBase();
2015  if (details::_ContextCallback::_CaptureCurrent() == _PTaskHandle->_M_continuationContext)
2016  {
2017  _TaskImplPtr->_ScheduleTask(_PTaskHandle, details::_ForceInline);
2018  }
2019  else
2020  {
2021  //
2022  // It's entirely possible that the attempt to marshal the call into a differing context will fail. In this case, we need to handle
2023  // the exception and mark the continuation as canceled with the appropriate exception. There is one slight hitch to this:
2024  //
2025  // NOTE: COM's legacy behavior is to swallow SEH exceptions and marshal them back as HRESULTS. This will in effect turn an SEH into
2026  // a C++ exception that gets tagged on the task. One unfortunate result of this is that various pieces of the task infrastructure will
2027  // not be in a valid state after this in /EHsc (due to the lack of destructors running, etc...).
2028  //
2029  try
2030  {
2031  // Dev10 compiler needs this!
2032  auto _PTaskHandle1 = _PTaskHandle;
2033  _PTaskHandle->_M_continuationContext._CallInContext( [_PTaskHandle1, _TaskImplPtr](){
2034  _TaskImplPtr->_ScheduleTask(_PTaskHandle1, details::_ForceInline);
2035  });
2036  }
2037 #if defined (__cplusplus_winrt)
2038  catch(::Platform::Exception^ _E)
2039  {
2040  _TaskImplPtr->_CancelWithException(_E);
2041  }
2042 #endif /* defined (__cplusplus_winrt) */
2043  catch(...)
2044  {
2045  _TaskImplPtr->_CancelWithException(std::current_exception());
2046  }
2047  }
2048  }, _PTaskHandle->_M_inliningMode);
2049  }
2050  else
2051  {
2052  _ScheduleTask(_PTaskHandle, _PTaskHandle->_M_inliningMode);
2053  }
2054  }
void _LogScheduleTask(bool)
Definition: ppltasks.h:1547
exception_ptr current_exception()
Definition: exception:527
Definition: concrt.h:5277
_TaskEventLogger _M_taskEventLogger
Definition: ppltasks.h:2310
static _ContextCallback _CaptureCurrent()
Definition: ppltasks.h:734
void _ScheduleTask(_UnrealizedChore_t *_PTaskHandle, _TaskInliningMode_t _InliningMode)
Helper function to schedule the task on the Task Collection.
Definition: ppltasks.h:1929
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:533
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.
1930  {
1931  try
1932  {
1933  _M_TaskCollection._ScheduleTask(_PTaskHandle, _InliningMode);
1934  }
1935  catch(const task_canceled &)
1936  {
1937  // task_canceled is a special exception thrown by cancel_current_task. The spec states that cancel_current_task
1938  // must be called from code that is executed within the task (throwing it from parallel work created by and waited
1939  // upon by the task is acceptable). We can safely assume that the task wrapper _PPLTaskHandle::operator() has seen
1940  // the exception and canceled the task. Swallow the exception here.
1941  _ASSERTE(_IsCanceled());
1942  }
1943  catch(const _Interruption_exception &)
1944  {
1945  // The _TaskCollection will never be an interruption point since it has a none token.
1946  _ASSERTE(false);
1947  }
1948  catch(...)
1949  {
1950  // This exception could only have come from within the chore body. It should've been caught
1951  // and the task should be canceled with exception. Swallow the exception here.
1953  }
1954  }
bool _HasUserException()
Definition: ppltasks.h:1889
bool _IsCanceled()
Definition: ppltasks.h:1884
::Concurrency::details::_TaskCollection_t _M_TaskCollection
Definition: ppltasks.h:2305
#define _ASSERTE(expr)
Definition: crtdbg.h:216
void _ScheduleTask(_TaskProcHandle_t *_Parameter, _TaskInliningMode _InliningMode)
Definition: pplconcrt.h:149
void Concurrency::details::_Task_impl_base::_SetAsync ( bool  _Async = true)
inline
1906  {
1908  }
future< typename result_of< _Fty(_ArgTypes...)>::type > _Async(_Launch_type _Policy, _Fty &&_Fnarg, _ArgTypes &&..._Args)
Definition: future:1874
bool _M_fFromAsync
Definition: ppltasks.h:2284
void Concurrency::details::_Task_impl_base::_SetTaskCreationCallstack ( const _TaskCreationCallstack _Callstack)
inline
1916  {
1917  _M_pTaskCreationCallstack = _Callstack;
1918  }
_TaskCreationCallstack _M_pTaskCreationCallstack
Definition: ppltasks.h:2308
task_status Concurrency::details::_Task_impl_base::_Wait ( )
inline
1680  {
1681  bool _DoWait = true;
1682 
1683 #if defined (__cplusplus_winrt)
1684  if (_IsNonBlockingThread())
1685  {
1686  // In order to prevent Windows Runtime STA threads from blocking the UI, calling task.wait() task.get() is illegal
1687  // if task has not been completed.
1688  if (!_IsCompleted() && !_IsCanceled())
1689  {
1690  throw invalid_operation("Illegal to wait on a task in a Windows Runtime STA");
1691  }
1692  else
1693  {
1694  // Task Continuations are 'scheduled' *inside* the chore that is executing on the ancestors's task group. If a continuation
1695  // needs to be marshalled to a different apartment, instead of scheduling, we make a synchronous cross apartment COM
1696  // call to execute the continuation. If it then happens to do something which waits on the ancestor (say it calls .get(), which
1697  // task based continuations are wont to do), waiting on the task group results in on the chore that is making this
1698  // synchronous callback, which causes a deadlock. To avoid this, we test the state ancestor's event , and we will NOT wait on
1699  // if it has finished execution (which means now we are on the inline synchronous callback).
1700  _DoWait = false;
1701  }
1702  }
1703 #endif /* defined (__cplusplus_winrt) */
1704  if (_DoWait)
1705  {
1706  // If this task was created from a Windows Runtime async operation, do not attempt to inline it. The
1707  // async operation will take place on a thread in the appropriate apartment Simply wait for the completed
1708  // event to be set.
1709  if (_M_fFromAsync)
1710  {
1712  }
1713  else
1714  {
1715  // Wait on the task collection to complete. The task collection is guaranteed to still be
1716  // valid since the task must be still within scope so that the _Task_impl_base destructor
1717  // has not yet been called. This call to _Wait potentially inlines execution of work.
1718  try
1719  {
1720  // Invoking wait on a task collection resets the state of the task collection. This means that
1721  // if the task collection itself were canceled, or had encountered an exception, only the first
1722  // call to wait will receive this status. However, both cancellation and exceptions flowing through
1723  // tasks set state in the task impl itself.
1724 
1725  // When it returns cancelled, either work chore or the cancel thread should already have set task's state
1726  // properly -- cancelled state or completed state (because there was no interruption point).
1727  // For tasks with unwrapped tasks, we should not change the state of current task, since the unwrapped task are still running.
1729  }
1730  catch(details::_Interruption_exception&)
1731  {
1732  // The _TaskCollection will never be an interruption point since it has a none token.
1733  _ASSERTE(false);
1734  }
1735  catch(task_canceled&)
1736  {
1737  // task_canceled is a special exception thrown by cancel_current_task. The spec states that cancel_current_task
1738  // must be called from code that is executed within the task (throwing it from parallel work created by and waited
1739  // upon by the task is acceptable). We can safely assume that the task wrapper _PPLTaskHandle::operator() has seen
1740  // the exception and canceled the task. Swallow the exception here.
1741  _ASSERTE(_IsCanceled());
1742  }
1743 #if defined (__cplusplus_winrt)
1744  catch(::Platform::Exception^ _E)
1745  {
1746  // Its possible the task body hasn't seen the exception, if so we need to cancel with exception here.
1747  if(!_HasUserException())
1748  {
1750  }
1751  // Rethrow will mark the exception as observed.
1752  _M_exceptionHolder->_RethrowUserException();
1753  }
1754 #endif /* defined (__cplusplus_winrt) */
1755  catch(...)
1756  {
1757  // Its possible the task body hasn't seen the exception, if so we need to cancel with exception here.
1758  if(!_HasUserException())
1759  {
1761  }
1762  // Rethrow will mark the exception as observed.
1763  _M_exceptionHolder->_RethrowUserException();
1764  }
1765 
1766  // If the lambda body for this task (executed or waited upon in _RunAndWait above) happened to return a task
1767  // which is to be unwrapped and plumbed to the output of this task, we must not only wait on the lambda body, we must
1768  // wait on the **INNER** body. It is in theory possible that we could inline such if we plumb a series of things through;
1769  // however, this takes the tact of simply waiting upon the completion signal.
1770  if (_M_fUnwrappedTask)
1771  {
1773  }
1774  }
1775  }
1776 
1777  if (_HasUserException())
1778  {
1779  _M_exceptionHolder->_RethrowUserException();
1780  }
1781  else if (_IsCanceled())
1782  {
1783  return canceled;
1784  }
1786  return completed;
1787  }
std::shared_ptr< _ExceptionHolder > _M_exceptionHolder
Definition: ppltasks.h:2291
bool _IsCompleted()
Definition: ppltasks.h:1879
bool _HasUserException()
Definition: ppltasks.h:1889
exception_ptr current_exception()
Definition: exception:527
bool _IsCanceled()
Definition: ppltasks.h:1884
::Concurrency::details::_TaskCollection_t _M_TaskCollection
Definition: ppltasks.h:2305
bool _CancelWithException(const std::exception_ptr &_Exception)
Definition: ppltasks.h:1831
#define _ASSERTE(expr)
Definition: crtdbg.h:216
void _RunAndWait()
Definition: pplconcrt.h:202
The tasks queued to the task_group or structured_task_group object completed successfully.
Definition: pplinterface.h:127
The task_group or structured_task_group object was canceled. One or more tasks may not have executed...
Definition: pplinterface.h:133
bool _M_fUnwrappedTask
Definition: ppltasks.h:2286
bool _M_fFromAsync
Definition: ppltasks.h:2284
void _Wait()
Definition: pplconcrt.h:219
_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
::Concurrency::extensibility::critical_section_t 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: