+ All Categories
Home > Documents > christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition...

christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition...

Date post: 09-Jun-2018
Category:
Upload: danglien
View: 212 times
Download: 0 times
Share this document with a friend
144
/*** * ==++== * * Copyright (c) Microsoft Corporation. All rights reserved. * * ==--== * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ * * ppl_tasks.h * * Parallel Patterns Library - First Class Tasks * * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- ****/ #pragma once #ifndef _PPLTASKS_H #define _PPLTASKS_H #include <ppl.h> #include <vector> #include <utility> #if defined(__cplusplus_winrt) #include <windows.h> #if 0 // ASYNC TODO: fix this when ctxtcall.h becomes part of VS Express (and remove the entry from msvc40.if) #include <ctxtcall.h> #else #ifndef __ctxtcall_h__ #define __ctxtcall_h__ /* Forward Declarations */ #ifndef __IContextCallback_FWD_DEFINED__ #define __IContextCallback_FWD_DEFINED__ typedef interface IContextCallback IContextCallback; #endif /* __IContextCallback_FWD_DEFINED__ */ /* interface __MIDL_itf_ctxtcall_0000_0000 */ /* [local] */ //+----------------------------------------------------------------- //
Transcript
Page 1: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

/**** ==++==** Copyright (c) Microsoft Corporation.  All rights reserved.** ==--==* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+** ppl_tasks.h** Parallel Patterns Library - First Class Tasks** =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-****/ #pragma once #ifndef _PPLTASKS_H#define _PPLTASKS_H #include <ppl.h>#include <vector>#include <utility> #if defined(__cplusplus_winrt)#include <windows.h>#if 0 // ASYNC TODO: fix this when ctxtcall.h becomes part of VS Express (and remove the entry from msvc40.if)#include <ctxtcall.h>#else#ifndef __ctxtcall_h__#define __ctxtcall_h__ /* Forward Declarations */  #ifndef __IContextCallback_FWD_DEFINED__#define __IContextCallback_FWD_DEFINED__typedef interface IContextCallback IContextCallback;#endif        /* __IContextCallback_FWD_DEFINED__ */ /* interface __MIDL_itf_ctxtcall_0000_0000 *//* [local] */  //+-----------------------------------------------------------------////  Microsoft Windows//  Copyright (c) Microsoft Corporation. All rights reserved.////------------------------------------------------------------------typedef struct tagComCallData    {    DWORD dwDispid;    DWORD dwReserved;

Page 2: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

    void *pUserDefined;    } ComCallData; extern RPC_IF_HANDLE __MIDL_itf_ctxtcall_0000_0000_v0_0_c_ifspec;extern RPC_IF_HANDLE __MIDL_itf_ctxtcall_0000_0000_v0_0_s_ifspec; #ifndef __IContextCallback_INTERFACE_DEFINED__#define __IContextCallback_INTERFACE_DEFINED__ /* interface IContextCallback *//* [unique][uuid][object][local] */  typedef /* [ref] */ HRESULT ( __stdcall *PFNCONTEXTCALL )(     ComCallData *pParam); EXTERN_C const IID IID_IContextCallback; MIDL_INTERFACE("000001da-0000-0000-C000-000000000046")IContextCallback : public IUnknown{public:    virtual HRESULT STDMETHODCALLTYPE ContextCallback(         /* [in] */ PFNCONTEXTCALL pfnCallback,        /* [in] */ ComCallData *pParam,        /* [in] */ REFIID riid,        /* [in] */ int iMethod,        /* [in] */ IUnknown *pUnk) = 0;    }; #endif        /* __IContextCallback_INTERFACE_DEFINED__ */#endif // __ctxtcall_h__#endif // #if 0 (#include <ctxtcall.h>) // TODO: Remove this once we have all the right headers sitting in WCConcRT and the Rascal builds we are using to build /ZW applications//       with PPLTASKS. #ifndef E_ILLEGAL_METHOD_CALL#define E_ILLEGAL_METHOD_CALL _HRESULT_TYPEDEF_(0x8000000EL)#endif  #ifndef E_ILLEGAL_STATE_CHANGE#define E_ILLEGAL_STATE_CHANGE _HRESULT_TYPEDEF_(0x8000000DL)#endif #endif #ifdef _DEBUG    #define _DBG_ONLY(X) X#else    #define _DBG_ONLY(X)#endif #pragma pack(push,_CRT_PACKING)

Page 3: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

#pragma warning(push)#pragma warning(disable: 28197) /// <summary>///     The <c>Concurrency</c> namespace provides classes and functions that give you access to the Concurrency Runtime,///     a concurrent programming framework for C++. For more information, see <see cref="Concurrency Runtime"/>./// </summary>/**/namespace Concurrency{namespace preview{// The task_status enum simply mirrors the task_group_status enumtypedef task_group_status task_status; template <typename _Type> class task;template <> class task<void>;class task_continuation_context; /// <summary>///     This class describes an exception that is thrown by the PPL tasks layer in order to force the current task///     to cancel. It is also thrown by the <c>get()</c> method on <see cref="task Class">task</see>, if the task///     is canceled when the method is invoked./// </summary>/**/class task_canceled : public std::exception{public:    /// <summary>    ///     Constructs a <c>task_canceled</c> object.    /// </summary>    /// <param name="_Message">    ///     A descriptive message of the error.    /// </param>    /**/    explicit task_canceled(const char * _Message) throw()        : exception(_Message)    {    }     /// <summary>    ///     Constructs a <c>task_canceled</c> object.    /// </summary>    /**/    task_canceled() throw()        : exception()    {    }};

Page 4: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

namespace details{    //    // PREVIEW: Dummy definition to get the header to compile    //    class _Task_canceled : public std::exception    {    public:        explicit _CRTIMP _Task_canceled(const char * _Message) throw()            : exception(_Message)        {        }        _CRTIMP _Task_canceled() throw()            : exception()        {        }    };     typedef unsigned char _Unit_type;     struct _TypeSelectorNoAsync {};    struct _TypeSelectorAsyncOperationOrTask {};    struct _TypeSelectorAsyncOperation : public _TypeSelectorAsyncOperationOrTask { };    struct _TypeSelectorAsyncTask : public _TypeSelectorAsyncOperationOrTask { };    struct _TypeSelectorAsyncAction {};    struct _TypeSelectorAsyncActionWithProgress {};    struct _TypeSelectorAsyncOperationWithProgress {};     template<typename _Ty>    struct _NormalizeVoidToUnitType    {        typedef _Ty _Type;    };     template<>    struct _NormalizeVoidToUnitType<void>    {        typedef _Unit_type _Type;    };     template<typename _T>    struct _IsUnwrappedAsyncSelector    {        static const bool _Value = true;    };     template<>    struct _IsUnwrappedAsyncSelector<_TypeSelectorNoAsync>    {        static const bool _Value = false;    };     template <typename _Ty>

Page 5: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

    struct _UnwrapTaskType    {        typedef _Ty _Type;    };     template <typename _Ty>    struct _UnwrapTaskType<::Concurrency::preview::task<_Ty>>    {        typedef _Ty _Type;    };     template <typename _T>    _TypeSelectorAsyncTask _AsyncOperationKindSelector(::Concurrency::preview::task<_T>);     _TypeSelectorNoAsync _AsyncOperationKindSelector(...);     template <typename _Type>    struct _FixHat    {        typedef _Type _FixedType;    }; #if defined(__cplusplus_winrt)    template <typename _Type>    struct _Unhat    {        typedef _Type _Value;    };     template <typename _Type>    struct _Unhat<_Type^>    {        typedef _Type _Value;    };     template <typename _Type>    struct _FixHat<_Type^>    {        typedef _Type^ const & _FixedType;    };     value struct _NonUserType {};     template <typename _Type, bool _IsValueTypeOrRefType = __is_value_class(_Type)>    struct _ValueTypeOrRefType    {        typedef _NonUserType _Value;    };     template <typename _Type>    struct _ValueTypeOrRefType<_Type^, false>    {        typedef typename _Type^ _Value;

Page 6: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

    };     template <typename _Type>    struct _ValueTypeOrRefType<_Type, true>    {        typedef _Type _Value;    };     template <typename _T1, typename _T2>    _T2 _ProgressTypeSelector(Windows::Foundation::IAsyncOperationWithProgress<_T1,_T2>^);     template <typename _T1>    _T1 _ProgressTypeSelector(Windows::Foundation::IAsyncActionWithProgress<_T1>^);     template <typename _Type>    struct _GetProgressType    {        typedef decltype(_ProgressTypeSelector(std::declval<_Type>())) _Value;    };     template <typename _Type>    struct _IsIAsyncInfo    {        static const bool _Value = __is_base_of(Windows::Foundation::IAsyncInfo, typename _Unhat<_Type>::_Value);    };     template <typename _T>    _TypeSelectorAsyncOperation _AsyncOperationKindSelector(Windows::Foundation::IAsyncOperation<_T>^);      _TypeSelectorAsyncAction _AsyncOperationKindSelector(Windows::Foundation::IAsyncAction^);     template <typename _T1, typename _T2>    _TypeSelectorAsyncOperationWithProgress _AsyncOperationKindSelector(Windows::Foundation::IAsyncOperationWithProgress<_T1, _T2>^);     template <typename _T>    _TypeSelectorAsyncActionWithProgress _AsyncOperationKindSelector(Windows::Foundation::IAsyncActionWithProgress<_T>^);     template <typename _Type, bool _IsAsync = _IsIAsyncInfo<_Type>::_Value>    struct _TaskTypeTraits    {        typedef typename _UnwrapTaskType<_Type>::_Type _TaskRetType;        typedef decltype(_AsyncOperationKindSelector(std::declval<_Type>())) _AsyncKind;        typedef typename _NormalizeVoidToUnitType<_TaskRetType>::_Type _NormalizedTaskRetType;         static const bool _IsAsyncTask = _IsAsync;

Page 7: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

        static const bool _IsUnwrappedTaskOrAsync = _IsUnwrappedAsyncSelector<_AsyncKind>::_Value;    };     template<typename _Type>    struct _TaskTypeTraits<_Type, true >    {        typedef decltype(((_Type)nullptr)->GetResults()) _TaskRetType;        typedef _TaskRetType _NormalizedTaskRetType;        typedef decltype(_AsyncOperationKindSelector((_Type)nullptr)) _AsyncKind;         static const bool _IsAsyncTask = true;        static const bool _IsUnwrappedTaskOrAsync = _IsUnwrappedAsyncSelector<_AsyncKind>::_Value;    }; #else // defined(__cplusplus_winrt)     template <typename _Type>    struct _IsIAsyncInfo    {        static const bool _Value = false;    };     template <typename _Type, bool _IsAsync = false>    struct _TaskTypeTraits    {        typedef typename _UnwrapTaskType<_Type>::_Type _TaskRetType;        typedef decltype(_AsyncOperationKindSelector(std::declval<_Type>())) _AsyncKind;        typedef typename _NormalizeVoidToUnitType<_TaskRetType>::_Type _NormalizedTaskRetType;         static const bool _IsAsyncTask = false;        static const bool _IsUnwrappedTaskOrAsync = _IsUnwrappedAsyncSelector<_AsyncKind>::_Value;    }; #endif #pragma warning(push)#pragma warning(disable: 4100)    template <typename _Function> auto _IsCallable(_Function _Func, int) -> decltype(_Func(), std::true_type()) { return std::true_type(); }#pragma warning(pop)    template <typename _Function> std::false_type _IsCallable(_Function, ...) { return std::false_type(); }     template <typename _Type> struct _FixFunction; // ASYNC TODO: this is a work-around for compiler bug 246576. It must removed in Beta.     template <typename _Ret, typename _Arg> struct _FixFunction< std::function<_Ret (_Arg)>>    {

Page 8: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

        typedef typename _FixHat<_Arg>::_FixedType _FixedArg;        typedef std::function<_Ret (_FixedArg)> _FixedFunc;    };     template <>    struct _TaskTypeTraits<void>    {        typedef void _TaskRetType;        typedef _TypeSelectorNoAsync _AsyncKind;        typedef _Unit_type _NormalizedTaskRetType;         static const bool _IsAsyncTask = false;        static const bool _IsUnwrappedTaskOrAsync = false;    };     template<typename _Type>    task<_Type> _To_task(_Type t);     task<void> _To_task();     template <typename _Function, typename _Type> auto _ReturnTypeHelper(_Type t, _Function _Func, int, int) -> decltype(_Func(_To_task(std::declval<_Type>())));    template <typename _Function, typename _Type> auto _ReturnTypeHelper(_Type t, _Function _Func, int, ...) -> decltype(_Func(std::declval<_Type>()));     template <typename _Function, typename _Type> auto _IsTaskHelper(_Type t, _Function _Func, int, int) -> decltype(_Func(_To_task(std::declval<_Type>())), std::true_type());    template <typename _Function, typename _Type> std::false_type _IsTaskHelper(_Type t, _Function _Func, int, ...);     template <typename _Function> auto _VoidReturnTypeHelper(_Function _Func, int, int) -> decltype(_Func(_To_task()));    template <typename _Function> auto _VoidReturnTypeHelper(_Function _Func, int, ...) -> decltype(_Func());     template <typename _Function> auto _VoidIsTaskHelper(_Function _Func, int, int) -> decltype(_Func(_To_task()), std::true_type());    template <typename _Function> std::false_type _VoidIsTaskHelper(_Function _Func, int, ...);     template<typename _Function, typename _Type>    struct _FunctionTypeTraits    {        typedef decltype(_ReturnTypeHelper(std::declval<_Type>(),std::declval<_Function>(), 0, 0)) _FuncRetType;        typedef decltype(_IsTaskHelper(std::declval<_Type>(),std::declval<_Function>(), 0, 0)) _Takes_task;    };     template<typename _Function>    struct _FunctionTypeTraits<_Function, void>

Page 9: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

    {        typedef decltype(_VoidReturnTypeHelper(std::declval<_Function>(), 0, 0)) _FuncRetType;        typedef decltype(_VoidIsTaskHelper(std::declval<_Function>(), 0, 0)) _Takes_task;    };     template<typename _Function, typename _ReturnType>    struct _ContinuationTypeTraits    {        typedef typename task<typename _TaskTypeTraits<typename _FunctionTypeTraits<_Function, _ReturnType>::_FuncRetType>::_TaskRetType> _TaskOfType;    };     // _InitFunctorTypeTraits is used to decide whether a task constructed with a lambda should be unwrapped. Depending on how the variable is    // declared, the constructor may or may not perform unwrapping. For eg.    //    //  This declaration SHOULD NOT cause unwrapping    //    task<task<void>> t1([]() -> task<void> {    //        task<void> t2([]() {});    //        return t2;    //    });    //    // This declaration SHOULD cause unwrapping    //    task<void>> t1([]() -> task<void> {    //        task<void> t2([]() {});    //        return t2;    //    });    // If the type of the task is the same as the return type of the function, no unwrapping should take place. Else normal rules apply.    template <typename _TaskType, typename _FuncRetType>    struct _InitFunctorTypeTraits    {        typedef typename _TaskTypeTraits<_FuncRetType>::_AsyncKind _AsyncKind;        static const bool _IsAsyncTask = _TaskTypeTraits<_FuncRetType>::_IsAsyncTask;        static const bool _IsUnwrappedTaskOrAsync = _TaskTypeTraits<_FuncRetType>::_IsUnwrappedTaskOrAsync;    };     template<typename T>    struct _InitFunctorTypeTraits<T, T>    {        typedef _TypeSelectorNoAsync _AsyncKind;        static const bool _IsAsyncTask = false;        static const bool _IsUnwrappedTaskOrAsync = false;    };     template<typename _Function>    struct _TaskProcThunk    {        _TaskProcThunk(const _Function& _Callback) :            _Func(_Callback)

Page 10: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

        {        }         static void _Bridge(void *_PData)        {            _TaskProcThunk *_PThunk = reinterpret_cast<_TaskProcThunk *>(_PData);            _PThunk->_Func();            delete _PThunk;        }     private:         _Function _Func;         _TaskProcThunk& operator=(const _TaskProcThunk&);    };     template<typename _Function>    void _ScheduleLightweightTask(_Function _Func)    {        typedef _TaskProcThunk<_Function> _CallbackType;        _CallbackType *_PThunk = new _CallbackType(_Func);        ::Concurrency::details::_CurrentScheduler::_ScheduleTask(reinterpret_cast<TaskProc>(&_CallbackType::_Bridge), _PThunk);    }     // ASYNC TODO: This should be based on a WinRT object which is not free threaded and an agile<> reference.  With such, it should be a few lines    //       of code.  As I understand the current state of things, unfortunately neither of these exist at the moment; hence -- this is relying     //       on RAW COM.  As well, doing this requires an APPX manifest.  Can we enforce this in headers given how things are being compiled!?    //    //       Even if not all of this can be replaced, _ResultContext stuff can likely be replaced with Agile<>.     class _ContextCallback    {        typedef std::function<void(void)> _CallbackFunction; #if defined(__cplusplus_winrt)     public:         static _ContextCallback _CaptureCurrent()        {            _ContextCallback _Context;            _Context._Capture();            return _Context;        }         ~_ContextCallback()        {            _Reset();

Page 11: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

        }         _ContextCallback(bool _DeferCapture = false)        {            if (_DeferCapture)            {                _Context._CaptureMethod = _CaptureDeferred;            }            else            {                _Context._M_pContextCallback = nullptr;            }        }         // Resolves a context that was created as _CaptureDeferred based on the environment (ancestor, current context).        void _Resolve(bool _CaptureCurrent)        {            if(_Context._CaptureMethod == _CaptureDeferred)            {                if (_CaptureCurrent && _IsCurrentOriginSTA())                {                    _Capture();                }                else                {                    _Context._M_pContextCallback = nullptr;                }            }        }         void _Capture()        {            HRESULT _Hr = CoGetObjectContext(IID_IContextCallback, reinterpret_cast<void **>(&_Context._M_pContextCallback));            if (!SUCCEEDED(_Hr))            {                _Context._M_pContextCallback = nullptr;            }        }         _ContextCallback(const _ContextCallback& _Src)        {            _Assign(_Src._Context._M_pContextCallback);        }         _ContextCallback(_ContextCallback&& _Src)        {            _Context._M_pContextCallback = _Src._Context._M_pContextCallback;            _Src._Context._M_pContextCallback = nullptr;        }         _ContextCallback& operator=(const _ContextCallback& _Src)        {            if (this != &_Src)

Page 12: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

            {                _Reset();                _Assign(_Src._Context._M_pContextCallback);            }            return *this;        }         _ContextCallback& operator=(_ContextCallback&& _Src)        {            if (this != &_Src)            {                _Context._M_pContextCallback = _Src._Context._M_pContextCallback;                _Src._Context._M_pContextCallback = nullptr;            }            return *this;        }         bool _HasCapturedContext() const        {            _ASSERT(_Context._CaptureMethod != _CaptureDeferred);            return (_Context._M_pContextCallback != nullptr);        }         void _CallInContext(_CallbackFunction _Func) const        {            if (!_HasCapturedContext())            {                _Func();            }            else            {                ComCallData callData;                memset(&callData, 0, sizeof(callData));                callData.pUserDefined = reinterpret_cast<void *>(&_Func);                 HRESULT _Hr = _Context._M_pContextCallback->ContextCallback(&_Bridge, &callData, IID_IContextCallback, 5, nullptr);                if (!SUCCEEDED(_Hr))                {#pragma warning(push)#pragma warning(disable: 4673 4672) // ASYNC TODO: remove the pragma when the fix for TFS#209378 comes to our branch                    throw ref new Platform::COMException(_Hr);#pragma warning(pop)                }            }        }         bool operator==(const _ContextCallback& _Rhs) const        {            return (_Context._M_pContextCallback == _Rhs._Context._M_pContextCallback);        }

Page 13: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

        bool operator!=(const _ContextCallback& _Rhs) const        {            return !(operator==(_Rhs));        }     private:        void _Reset()        {            if (_Context._CaptureMethod != _CaptureDeferred && _Context._M_pContextCallback != nullptr)            {                _Context._M_pContextCallback->Release();            }        }         void _Assign(IContextCallback *_PContextCallback)        {            _Context._M_pContextCallback = _PContextCallback;            if (_Context._CaptureMethod != _CaptureDeferred && _Context._M_pContextCallback != nullptr)            {                _Context._M_pContextCallback->AddRef();            }        }         static HRESULT __stdcall _Bridge(ComCallData *_PParam)        {            _CallbackFunction *pFunc = reinterpret_cast<_CallbackFunction *>(_PParam->pUserDefined);            (*pFunc)();            return S_OK;        }         // Returns the origin information for the caller (runtime / WinRT apartment as far as task continuations need know)        bool _IsCurrentOriginSTA()        {            APTTYPE _AptType;            APTTYPEQUALIFIER _AptTypeQualifier;             HRESULT hr = CoGetApartmentType(&_AptType, &_AptTypeQualifier);            if (SUCCEEDED(hr))            {                // We determine the origin of a task continuation by looking at where .then is called, so we can tell whether                // to need to marshal the continuation back to the originating apartment. If an STA thread is in executing in                // a neutral aparment when it schedules a continuation, we will not marshal continuations back to the STA,                // since variables used within a neutral apartment are expected to be apartment neutral                switch(_AptType)                {                    case APTTYPE_MAINSTA:

Page 14: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

                    case APTTYPE_STA:                        return true;                    default:                        break;                }            }            return false;        }         union        {            IContextCallback *_M_pContextCallback;            size_t _CaptureMethod;        } _Context;         static const size_t _CaptureDeferred = 1;#else    public:         static _ContextCallback _CaptureCurrent()        {            return _ContextCallback();        }         _ContextCallback(bool = false)        {        }         _ContextCallback(const _ContextCallback&)        {        }         _ContextCallback(_ContextCallback&&)        {        }         _ContextCallback& operator=(const _ContextCallback&)        {            return *this;        }         _ContextCallback& operator=(_ContextCallback&&)        {            return *this;        }         bool _HasCapturedContext() const        {            return false;        }         void _Resolve(bool) const        {        }

Page 15: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

        void _CallInContext(_CallbackFunction _Func) const        {            _Func();        }         bool operator==(const _ContextCallback&) const        {            return true;        }         bool operator!=(const _ContextCallback&) const        {            return false;        } #endif // defined(__cplusplus_winrt)    };     template<typename _Type>    struct _ResultContext    {        static _ContextCallback _GetContext(bool /* _RuntimeAggregate */)        {            return _ContextCallback();        }         static _Type _GetValue(_Type _ObjInCtx, const _ContextCallback & /* _Ctx */, bool /* _RuntimeAggregate */)        {            return _ObjInCtx;        }    }; #if defined(__cplusplus_winrt)    template<typename _Type>    struct _MarshalHelper    {        static _Type^ _Perform(_Type^ _ObjInCtx, const _ContextCallback& _Ctx)        {            HRESULT _Hr;            LPSTREAM _PStream;            _Ctx._CallInContext([&](){                // It isn't safe to simply reinterpret_cast a hat type to IUnknown* because some hat type do not have a real vtable ptr                // Instead, we need to first upcast it to Object^ to make it "grow" the vtable ptr                Platform::Object^ _PObj = safe_cast<Platform::Object^>(_ObjInCtx);                IUnknown* _PUnk = reinterpret_cast<IUnknown*>(_PObj);                _Hr = CoMarshalInterThreadInterfaceInStream(__uuidof(_Type^), _PUnk, &_PStream);            });            //            // ASYNC TODO: Is this right?  Right now without an APPX manifest

Page 16: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

, classes you define in your C++ WinRT code are not registered meaning this            //             *WILL* fail!            //            if (!SUCCEEDED(_Hr))            {                return _ObjInCtx;            }             _Type^ _Proxy;            _Hr = CoGetInterfaceAndReleaseStream(_PStream, __uuidof(_Type^), reinterpret_cast<void**>(&_Proxy));            if (!SUCCEEDED(_Hr))            {                throw ref new Platform::COMException(_Hr);            }            return _Proxy;        }    };     // Specializations to avoid marshaling for strings and arrays. ASYNC TODO: rewrite using a special compiler type trait    template<typename _Type>    struct _MarshalHelper<lang::array<_Type^>>    {        static lang::array<_Type^>^ _Perform(lang::array<_Type^>^ _ObjInCtx, const _ContextCallback& _Ctx)        {            return _ObjInCtx;        }    };     template<>    struct _MarshalHelper<Platform::String>    {        static Platform::String^ _Perform(Platform::String^ _ObjInCtx, const _ContextCallback& _Ctx)        {            return _ObjInCtx;        }    };     template<typename _Type>    _Type^ _Marshal(_Type^ _ObjInCtx, const _ContextCallback& _Ctx)    {        return _MarshalHelper<_Type>::_Perform(_ObjInCtx, _Ctx);    }     template<typename _Type>    struct _InContext    {        static _Type _Get(_Type _ObjInCtx, const _ContextCallback& _Ctx)        {            return _ObjInCtx;        }    };

Page 17: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

    template<typename _Type>    struct _InContext<_Type^>    {        static _Type^ _Get(_Type^ _ObjInCtx, const _ContextCallback& _Ctx)        {            _ContextCallback _CurrentContext = _ContextCallback::_CaptureCurrent();            if (!_Ctx._HasCapturedContext() || _Ctx == _CurrentContext)            {                return _ObjInCtx;            }             //             // The object is from another apartment.  If it's marshalable, do so.            //            return _Marshal<_Type>(_ObjInCtx, _Ctx);        }    };     template<typename _Type>    struct _ResultContext<_Type^>    {        static _Type^ _GetValue(_Type^ _ObjInCtx, const _ContextCallback& _Ctx, bool /* _RuntimeAggregate */)        {            return _InContext<_Type^>::_Get(_ObjInCtx, _Ctx);        }         static _ContextCallback _GetContext(bool /* _RuntimeAggregate */)        {            return _ContextCallback::_CaptureCurrent();        }    };     //     // The below are for composability with tasks auto-created from when_any / when_all / && / || constructs.    //     template<typename _Type>    struct _ResultContext<std::vector<_Type^>>    {        static std::vector<_Type^> _GetValue(std::vector<_Type^> _ObjInCtx, const _ContextCallback& _Ctx, bool _RuntimeAggregate)        {            if (!_RuntimeAggregate)            {                return _ObjInCtx;            }             _ContextCallback _CurrentContext = _ContextCallback::_CaptureCurrent();            if (!_Ctx._HasCapturedContext() || _Ctx == _CurrentContext)

Page 18: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

            {                return _ObjInCtx;            }             for (auto _It = _ObjInCtx.begin(); _It != _ObjInCtx.end(); ++_It)            {                *_It = _Marshal<_Type>(*_It, _Ctx);            }             return _ObjInCtx;        }         static _ContextCallback _GetContext(bool _RuntimeAggregate)        {            if (!_RuntimeAggregate)            {                return _ContextCallback();            }            else            {                return _ContextCallback::_CaptureCurrent();            }        }    };     template<typename _Type>    struct _ResultContext<std::pair<_Type^, size_t>>    {        static std::pair<_Type^, size_t> _GetValue(std::pair<_Type^, size_t> _ObjInCtx, const _ContextCallback& _Ctx, bool _RuntimeAggregate)        {            if (!_RuntimeAggregate)            {                return _ObjInCtx;            }             _ContextCallback _CurrentContext = _ContextCallback::_CaptureCurrent();            if (!_Ctx._HasCapturedContext() || _Ctx == _CurrentContext)            {                return _ObjInCtx;            }             return std::pair<_Type^, size_t>(_Marshal<_Type>(_ObjInCtx.first, _Ctx), _ObjInCtx.second);        }         static _ContextCallback _GetContext(bool _RuntimeAggregate)        {            if (!_RuntimeAggregate)            {                return _ContextCallback();            }            else            {

Page 19: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

                return _ContextCallback::_CaptureCurrent();            }        }    }; #endif // defined(__cplusplus_winrt)     // An exception thrown by the task body is captured in an exception holder and it is shared with all value based continuations rooted at the task.    // The exception is 'observed' if the user invokes get()/wait() or schedules a task-based continuation on any of the tasks that are sharing this    // exception holder. If the exception is not observed by the time the internal object owned by the shared pointer destructs,    // an unobserved_task_exception is thrown by the runtime.    struct _ExceptionHolder    {        explicit _ExceptionHolder(const std::exception_ptr& _E) : _M_exceptionObserved(0), _M_storedException(_E)        {        }         ~_ExceptionHolder()        {            if (_M_exceptionObserved == 0)            {                // Throwing an exception from a destructor will terminate the process if the destructor is executing as part of stack                // unwinding due to an existing exception. In general, this should be fine here, since we're throwing this exception in                // order to terminate the process.// PREVIEW_DISABLED//                throw unobserved_task_exception(_M_storedException);            }        }         void _SetExceptionObserved()        {            if (_M_exceptionObserved == 0)            {                _InterlockedExchange(&_M_exceptionObserved, 1);            }        }         long volatile _M_exceptionObserved;        std::exception_ptr _M_storedException;    };     struct _Task_impl_base;     template<typename _ReturnType> struct _Task_impl;     template<typename _ReturnType>    struct _Task_ptr    {        typedef std::shared_ptr<_Task_impl<_ReturnType>> _Type;

Page 20: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

        static _Type make() { return std::make_shared<_Task_impl<_ReturnType>>(); }    };     /// <summary>    ///     The _PPLTaskHandle is the individual work item that the PPL Task is expected to execute. The user function    ///     executed by the PPL task must be wrapped in one of these handles in order to execute properly on the underlying    ///     task collection. The lifetime of the task collection is owned by the task impl.    /// </summary>    /// <typeparam name="_Function">    ///     The type of the function object that will be invoked to execute the body of the PPL task handle.    /// </typeparam>    /**/    template<typename _Function>    class _PPLTaskHandle : public ::Concurrency::details::_PPLTaskChore    {    public:        _PPLTaskHandle(const _Function& _Func, _Task_impl_base * _Task_impl) : _M_function(_Func), _M_pTask(_Task_impl)        {            m_pFunction = reinterpret_cast <TaskProc> (&::Concurrency::details::_UnrealizedChore::_InvokeBridge<_PPLTaskHandle>);        }         ~_PPLTaskHandle()        {        }         void operator()() const        {            // All exceptions should be rethrown to finish cleanup of the task collection. They will be caught and handled            // by the runtime.            _ASSERT(_M_pTask != NULL);            try            {                _M_function();             }            catch (const task_canceled &)            {                _M_pTask->_Cancel(true, 0);                throw;            }            catch (const _Task_canceled &)            {                _M_pTask->_Cancel(true, 0);                throw;            }            catch (...)            {

Page 21: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

                _M_pTask->_CancelWithException(std::current_exception(), 0);                throw;            }        }     private:        // The task that is executing this function.        _Task_impl_base * _M_pTask;         // The function object invoked to perform the body of the task.        _Function _M_function;         _PPLTaskHandle const & operator=(_PPLTaskHandle const&);    // no assignment operator    };     struct _TaskContinuationParameterBase;     typedef void (__cdecl * _TaskContinuationProc)(_TaskContinuationParameterBase *, size_t);     struct _TaskProcWithParam    {        _TaskContinuationProc _M_proc;        _TaskContinuationParameterBase* _M_param;        _TaskProcWithParam(_TaskContinuationProc _P_proc, _TaskContinuationParameterBase* _P_param) : _M_proc(_P_proc), _M_param(_P_param) {}    };     /// <summary>    ///     The base implementation of a first-class task. This class contains all the non-type specific    ///     implementation details of the task.    /// </summary>    /**/    struct _Task_impl_base    {private:        // Must not be copied by value:        _Task_impl_base(const _Task_impl_base&);        _Task_impl_base const & operator=(_Task_impl_base const&);public:        enum _TaskInternalState        {            // Tracks the state of the task, rather than the task collection on which the task is scheduled            _Created,            _Started,            _PendingCancel,            _Completed,            _Canceled        };        _Task_impl_base() : _M_TaskState(_Created), _M_pTaskCollection(NULL), _M_fObservesExceptions(false), _M_pExecutingChore(NULL),                            _M_fFromAsync(false), _M_fRuntimeAggregate

Page 22: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

(false), _M_fUnwrappedTask(false)        {        }         virtual ~_Task_impl_base()         {            // This destructor is called when the last reference to the _Task_impl_base goes away.            // References are held by the task<T> class as well as the _PPLTaskHandle executing on the            // TaskCollection.            delete _M_pTaskCollection;        }         task_status _Wait(bool _FromWait)        {#if defined(__cplusplus_winrt)            // In order to prevent WinRT STA threads from blocking the UI, calling task.wait() is illegal for STA            // threads, and task.get() is illegal if it has to wait.            if (_IsSTA() && (_FromWait || _M_Completed.wait(0) == COOPERATIVE_WAIT_TIMEOUT))            {                throw invalid_operation("Illegal to wait on a task in a WinRT STA");            }#endif // defined(__cplusplus_winrt)             // Wait for the task to be actually scheduled, otherwise the underlying task collection            // might not be created yet. If we don't wait, we will miss the chance to inline this task.            _M_Scheduled.wait();             // A PPL task created by a task_completion_event does not have an underlying TaskCollection.  For            // These tasks, a call to wait should wait for the event to be set. The TaskCollection must either            // be NULL or allocated (the setting of _M_Scheduled) ensures that.            // If this task was created from a WinRT async operation, do not attempt to inline it. The            // async operation will take place on a thread in the appropriate apartment Simply wait for the completed            // event to be set.            if (_M_pTaskCollection == NULL || _M_fFromAsync)            {                _M_Completed.wait();                 if (_HasUserException())                {                    _RethrowUserException();                }                else if (_IsCanceled())                {

Page 23: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

                    return canceled;                }                _ASSERT(_IsCompleted());                return completed;            }             // Wait on the task collection to complete. The task collection is guaranteed to still be            // valid since the task must be still within scope so that the _Task_impl_base destructor            // has not yet been called. This call to _Wait potentially inlines execution of work.            try            {                // Invoking wait on a task collection resets the state of the task collection. This means that                // if the task collection itself were canceled, or had encountered an exception, only the first                // call to wait will receive this status. However, both cancellation and exceptions flowing through                // tasks set state in the task impl itself.                if(_M_pTaskCollection->_RunAndWaitPPLTask() == canceled)                {                    _Cancel(true, 0);                }            }            catch(details::_Task_canceled&)            {                // This could be a _Task_canceled exception flowing through the wait due to a cancellation at a higher level.                //                // Note that this exception may or may not have already been observed by the task body depending on when the                 // higher level cancellation happened.  _RunAndWait may have thrown the cancellation and aborted the task                // before it was picked up -- or it may have happened due to an interruption point in the body.  This exception                // handler must be consistent with the _PPLTaskHandle's set of handlers.                _Cancel(true, 0);               throw;            }            catch(task_canceled&)            {                // task_canceled is a special exception thrown by cancel_current_task. The spec states that cancel_current_task                // must be called from code that is executed within the task (throwing it from parallel work created by and waited                // upon by the task is acceptable). We can safely assume that the task wrapper _PPLTaskHandle::operator() has seen                // the exception and canceled the task. Swallow the exception here.                _ASSERT(_IsCanceled());            }            catch(...)

Page 24: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

            {                // Its possible the task body hasn't seen the exception, if so we need to cancel with exception here.                if(!_HasUserException())                {                    _CancelWithException(std::current_exception(), 0);                }                _ObserveUserException();                throw;            }             // If the lambda body for this task (executed or waited upon in _RunAndWait above) happened to return a task            // which is to be unwrapped and plumbed to the output of this task, we must not only wait on the lambda body, we must            // wait on the **INNER** body.  It is in theory possible that we could inline such if we plumb a series of things through;            // however, this takes the tact of simply waiting upon the completion signal.            if (_M_fUnwrappedTask)            {                _M_Completed.wait();            }             if (_HasUserException())            {                _RethrowUserException();            }            else if (_IsCanceled())            {                return canceled;            }            _ASSERT(_IsCompleted());            return completed;        }         /// <summary>        ///     Requests cancellation on the task and schedules continuations if the task can be transitioned to a terminal state.        /// </summary>        /// <param name="_SynchronousCancel">        ///     Set 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.        /// </param>        /// <param name="_UserException">        ///     Whether an exception other than the internal runtime cancella

Page 25: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

tion exceptions caused this cancellation.        /// </param>        /// <param name="_PropagatedFromAncestor">        ///     Whether 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.        /// </param>        /// <param name="_ExHolder">        ///     The exception holder that represents the exception. Only valid when _UserException is set to true.        /// </param>        virtual bool _CancelAndRunContinuations(bool _SynchronousCancel, bool _UserException, bool _PropagatedFromAncestor, const std::shared_ptr<_ExceptionHolder>& _ExHolder, size_t _ContCount) = 0;         bool _Cancel(bool _SynchronousCancel, size_t _ContCount)        {            // Send in a dummy value for exception. It is not used when the first parameter is false.            return _CancelAndRunContinuations(_SynchronousCancel, false, false, _M_exceptionHolder, _ContCount);        }         bool _CancelWithExceptionHolder(const std::shared_ptr<_ExceptionHolder>& _ExHolder, bool _PropagatedFromAncestor, size_t _ContCount)        {            // This task was canceled because an ancestor task encountered an exception.            return _CancelAndRunContinuations(true, true, _PropagatedFromAncestor, _ExHolder, _ContCount);        }         bool _CancelWithException(const std::exception_ptr& _Exception, size_t _ContCount)        {            // This task was canceled because the task body encountered an exception.            _ASSERT(!_HasUserException());            return _CancelAndRunContinuations(true, true, false, std::make_shared<_ExceptionHolder>(_Exception), _ContCount);        }         bool _IsCreated()        {            return (_M_TaskState == _Created);        }         bool _IsStarted()        {            return (_M_TaskState == _Started);        }         bool _IsPendingCancel()        {

Page 26: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

            return (_M_TaskState == _PendingCancel);        }         bool _IsCompleted()        {            return (_M_TaskState == _Completed);        }         bool _IsCanceled()        {            return (_M_TaskState == _Canceled);        }         bool _HasUserException()        {            return _M_exceptionHolder;        }         bool _ObservesExceptions()        {            return _M_fObservesExceptions;        }         void _ObserveUserException()        {            if (_HasUserException())            {                _M_exceptionHolder->_SetExceptionObserved();            }        }         void _RethrowUserException()        {            _ASSERT(_HasUserException());            _M_exceptionHolder->_SetExceptionObserved();            std::rethrow_exception(_M_exceptionHolder->_M_storedException);        }         void _SetScheduledEvent()        {            _M_Scheduled.set();        }         const std::shared_ptr<_ExceptionHolder>& _GetExceptionHolder()        {            _ASSERT(_HasUserException());            return _M_exceptionHolder;        }         bool _IsAsync()        {            return _M_fFromAsync;        }         void _SetAsync(bool _Async = true)

Page 27: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

        {            _M_fFromAsync = _Async;        }         static void _RunTaskContinuations(std::vector<_TaskProcWithParam>& _Continuations, size_t _Depth)        {            for (auto it = _Continuations.begin(); it != _Continuations.end(); ++it)            {                // When this continuation function runs, it will check to see if its ancestor                // has canceled or not before scheduling itself for execution                it->_M_proc(it->_M_param, _Depth);            }            _Continuations.clear();        } #if defined(__cplusplus_winrt)         static bool  _IsSTA()        {            APTTYPE _AptType;            APTTYPEQUALIFIER _AptTypeQualifier;             HRESULT hr = CoGetApartmentType(&_AptType, &_AptTypeQualifier);            //            // If it failed, it's not a WinRT/COM initialized thread. This is not a failure.            //            if (SUCCEEDED(hr))            {                switch(_AptType)                {                case APTTYPE_STA:                case APTTYPE_MAINSTA:                    return true;                    break;                case APTTYPE_NA:                    switch(_AptTypeQualifier)                    {                    // A thread executing in a neutral apartment is either STA or MTA. To find out if this thread is allowed                    // to wait, we check the app qualifier. If it is an STA thread executing in a neutral apartment, waiting                    // is illegal, because the thread is responsible for pumping messages and waiting on a task could take the                    // thread out of circulation for a while.                    case APTTYPEQUALIFIER_NA_ON_STA:                    case APTTYPEQUALIFIER_NA_ON_MAINSTA:                        return true;                        break;                    }                    break;                }

Page 28: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

            }            return false;        }         template<typename _ReturnType, typename>        static void _AsyncInit(typename _Task_ptr<_ReturnType>::_Type _OuterTask,                               Windows::Foundation::IAsyncOperation<typename details::_ValueTypeOrRefType<_ReturnType>::_Value>^ _AsyncOp)        {            // This method is invoked either when a task is created from an existing async operation or            // when a lambda that creates an async operation executes.             // If the outer task is pending cancel, don't bother with starting the async operation. The COM reference on            // the IAsyncInfo object will be released when all ^references to the operation go out of scope.            _ASSERT((_OuterTask->_M_fUnwrappedTask || _OuterTask->_M_pTaskCollection == NULL) && !_OuterTask->_IsCanceled());            if (!_OuterTask->_IsPendingCancel())            {                // Note: This is an optimistic check outside the lock. it's possible the task could become canceled while we're in this function.                // Pass the shared_ptr by value into the lambda instead of using 'this'.                _AsyncOp->Completed = ref new Windows::Foundation::AsyncOperationCompletedHandler<_ReturnType>(                    [_OuterTask](Windows::Foundation::IAsyncOperation<typename details::_ValueTypeOrRefType<_ReturnType>::_Value>^ _Operation)                    {                        if (_Operation->Status == Windows::Foundation::AsyncStatus::Canceled)                        {                            // ASYNC TODO: _Cancel may call Cancel on the async op if it is set. Find out whether it is ok to call                             // IAsyncInfo::Cancel multiple times.                            _OuterTask->_Cancel(true, 0);                        }                        else                        {                            try                            {                                _OuterTask->_FinalizeAndRunContinuations(_Operation->GetResults());                                _ASSERT(_Operation->Status == Windows::Foundation::AsyncStatus::Completed);                            }                            catch (Platform::COMException^ _E)                            {                                _ASSERT(_Operation->Status == Windows::Foundation::AsyncStatus::Error);                                _OuterTask->_CancelWithException(make_exception_ptr(async_operation_exception(_E)), 0);

Page 29: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

                            }                        }                        _Operation->Close();                    });                _AsyncOp->Start();                _OuterTask->_SetUnwrappedAsyncOp(_AsyncOp);            }            else            {                _ASSERT(!_OuterTask->_HasUserException());                // If we were canceled while executing we must respond to it here by completing the cancellation.                _OuterTask->_Cancel(true, 0);            }        }#endif         template<typename _ReturnType, typename _InternalReturnType>        static void _AsyncInit(typename _Task_ptr<_ReturnType>::_Type _OuterTask, task<_InternalReturnType> _UnwrappedTask)        {            _ASSERT(_OuterTask->_M_fUnwrappedTask && !_OuterTask->_IsCanceled());            //            // We must ensure that continuations off _OuterTask (especially exception handling ones) continue to function in the             // presence of an exception flowing out of the inner task _UnwrappedTask. This requires an exception handling continuation            // off the inner task which does the appropriate funnelling to the outer one. We use _Then instead of then to prevent            // the exception from being marked as observed by our internal continuation. This continuation must be scheduled regardless            // of whether or not the _OuterTask task is canceled.            //            _UnwrappedTask._Then([_OuterTask] (task<_InternalReturnType> _AncestorTask) {                 if (_AncestorTask._GetImpl()->_IsCompleted())                {                    _OuterTask->_FinalizeAndRunContinuations(_AncestorTask._GetImpl()->_GetResult());                }                else                {                    _ASSERT(_AncestorTask._GetImpl()->_IsCanceled());                    if (_AncestorTask._GetImpl()->_HasUserException())                    {                        // Set _PropagatedFromAncestor to false, since _AncestorTask is not an ancestor of _UnwrappedTask.                        // Instead, it is the enclosing task.                        _OuterTask->_CancelWithExceptionHolder(_AncestorTask._GetImpl()->_GetExceptionHolder(), false, 0);                    }                    else

Page 30: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

                    {                        _OuterTask->_Cancel(true, 0);                    }                }            }, false, false);             _OuterTask->_SetUnwrappedTask(_UnwrappedTask._GetImpl());        }         event _M_Completed;        event _M_Scheduled;         // Tracks the internal state of the task        _TaskInternalState _M_TaskState;        // Set to true either if the ancestor task had the flag set to true, or if the lambda that does the work of this task returns an        // async operation or async action that is unwrapped by the runtime.        bool _M_fFromAsync;        // Set to true if we need to marshal the inner parts of an aggregate type like std::vector<T^> or std::pair<T^, size_t>. We only marshal        // the contained T^s if we create the vector or pair, such as on a when_any or a when_all operation.        bool _M_fRuntimeAggregate;        // Set to true when a continuation unwraps a task or async operation.        bool _M_fUnwrappedTask;        // Set to true for a task-based continuation that is scheduled by the user. All internal (runtime scheduled) task based continuations        // should have this set to false.        bool _M_fObservesExceptions;        // An exception thrown by the task body is captured in an exception holder and it is shared with all its value based continuations.        // The exception is 'observed' if the user invokes get()/wait() or schedules a task-based continuation on any of the tasks that are sharing this        // exception holder. If the exception is not observed by the time the internal object owned by the shared pointer destructs,        // an unobserved_task_exception is thrown by the runtime.        std::shared_ptr<_ExceptionHolder> _M_exceptionHolder;         typedef std::vector<_TaskProcWithParam> _ContinuationList;         critical_section _M_ContinuationsCritSec;        _ContinuationList _M_Continuations;         ::Concurrency::details::_PPLTaskChore * _M_pExecutingChore;         // The underlying group of tasks as known to the runtime.        ::Concurrency::details::_TaskCollection * _M_pTaskCollection;    };     /// <summary>    ///     The implementation of a first-class task. This structure contains the task group used to execute    ///     the task function and handles the scheduling.  The _Task_impl is created as a shared_ptr

Page 31: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

    ///     member of the the public task class, so its destruction is handled automatically.    /// </summary>    /// <typeparam name="_ReturnType">    ///     The result type of this task.    /// </typeparam>    /**/    template<typename _ReturnType>    struct _Task_impl : public _Task_impl_base    {#if defined(__cplusplus_winrt)        typedef Windows::Foundation::IAsyncOperation<typename details::_ValueTypeOrRefType<_ReturnType>::_Value> _AsyncOperationType;#endif        _Task_impl()        {#if defined(__cplusplus_winrt)            _M_unwrapped_async_op = nullptr;#endif        }         virtual ~_Task_impl()         {        }         virtual bool _CancelAndRunContinuations(bool _SynchronousCancel, bool _UserException, bool _DBG_ONLY(_PropagatedFromAncestor), const std::shared_ptr<_ExceptionHolder>& _ExceptionHolder, size_t _ContCount)        {            _ContinuationList _Continuations;            bool _CancelUnwrapped = false;            bool _RunContinuations = false;            {                critical_section::scoped_lock _LockHolder(_M_ContinuationsCritSec);                if (_UserException)                {                    _ASSERT(_SynchronousCancel && !_IsCompleted());                    // If the state is _Created or _Canceled, the exception has to be coming from an ancestor.                    _ASSERT((!_IsCreated() && !_IsCanceled()) || _PropagatedFromAncestor);                    // If the state is _Started or _PendingCancel, the exception cannot be coming from an ancestor.                    _ASSERT((!_IsStarted() && !_IsPendingCancel()) || !_PropagatedFromAncestor);                     // We should not be canceled with an exception more than once.                    _ASSERT(!_HasUserException());                     switch (_M_TaskState)                    {                    case _Created:                        // Intentional fall through

Page 32: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

                    case _Started:                        {                            // If the task is canceled with exception there is no need to cancel the task collection (if it exists, it should already                            // have been canceled).                            _M_exceptionHolder = _ExceptionHolder;                        }                        break;                    case _PendingCancel:                        {                            _M_exceptionHolder = _ExceptionHolder;                            // If cancellation was previously requested, mark the exception as observed.                            _M_exceptionHolder->_SetExceptionObserved();                        }                        break;                    case _Canceled:                        {                            // If the task has finished cancelling there should not be any continuation records in the array.                            _ASSERT(_M_Continuations.empty());                            return false;                        }                        break;                    case _Completed:                        // Intentional fall through                    default:                        _ASSERT(false);                        break;                    }                }                else                {                    // If the task has a stored exception, cancellation of the task observes the exception.                    _ObserveUserException();                     // Completed is a non-cancellable state, and if this is an asynchronous cancel, we're unable to do better than the last async cancel                    // which is to say, cancellation is already initiated, so return early.                    if (_IsCompleted() || _IsCanceled() || (_IsPendingCancel() && !_SynchronousCancel))                    {                        _ASSERT(!_IsCompleted() || !_HasUserException());                        return false;                    }                    _ASSERT(!_SynchronousCancel || !_HasUserException());                     if (_IsStarted() && !_SynchronousCancel)                    {                        // The _M_TaskState variable transitions to _Canceled when cancellation is completed (the task is not executing user code anymore).                        // In the case of a synchronous cancel, this can happen immediately, whereas with an asynchronous cancel, the task has to move fro

Page 33: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

m                        // _Started to _PendingCancel before it can move to _Canceled when it is finished executing.                        _M_TaskState = _PendingCancel;                         if (_M_pTaskCollection != NULL)                        {                            _M_pTaskCollection->_Cancel();                        }                         _CancelUnwrapped = _M_unwrapped_task;#if defined(__cplusplus_winrt)                        if (_M_unwrapped_async_op != nullptr)                        {                            _ASSERT(!_CancelUnwrapped);                            _CancelUnwrapped = true;                        }#endif                    }                }                 // It is important to check if this task has an unwrapped task and *not* complete cancellation unless it is also canceled. If an                 // unwrapped task was linked up, the burden for finalizing cancellation/completion state is on that tasks continuations (we scheduled                // a task based continuation off the unwrapped task for this purpose in _AsyncInit).                //                // Consider the following example:                //      Outer task OT creates and returns inner task IT. After IT has started executing (_Started), but before OT has returned IT,                // the user cancels OT. If OT has no interruption points, the pending cancellation will first be detected in _AsyncInit when OT's                // lambda returns. If the user meanwhile does a wait() on OT, _RunAndWait will return a status of 'canceled' causing wait to                // invoke a synchronous cancellation on OT. However, we want OT's cancellation to be completed when IT is done executing/cancelling,                // since it's already hooked up via _M_unwrapped_task. Ignoring this cancel allows IT to complete the cancellation on OT.                if ((_SynchronousCancel || _IsCreated()) && (!_M_unwrapped_task || _M_unwrapped_task->_IsCanceled()))                {                    // The state could be _Created if we're cancelled as the result of an ancestor being canceled or a task completion event                    // cancellation                    if (_IsCreated())                    {                        _M_Scheduled.set();                    }                    _M_TaskState = _Canceled;                    // Cancellation completes the task, so all dependent tasks must be run to cancel them                    // They are canceled when they begin running (see _RunContinuation) and see that their                     // ancestor has been canceled.

Page 34: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

                    _Continuations.swap(_M_Continuations);                    _RunContinuations = true;                }            }             // Only execute continuations and mark the task as completed if we were able to move the task to the _Canceled state.            if (_RunContinuations)            {                _M_Completed.set();                 // If nesting is not too deep, continue traversing the task tree on the stack. Otherwise, ship the work off to an LWT                if( _ContCount < 64 )                {                    _RunTaskContinuations(_Continuations, _ContCount + 1);                }                else                {                    auto _Func = [_Continuations]() mutable {                        _RunTaskContinuations(_Continuations, 0);                    };                    _ScheduleLightweightTask(_Func);                }            }             if (_CancelUnwrapped)            {                if (_M_unwrapped_task)                {                    // The unwrapped task should be canceled after releasing the lock in case it has any task based continuations that could                    // run inline.                    _M_unwrapped_task->_Cancel(false, 0);                }#if defined(__cplusplus_winrt)                else                {                    _ASSERT(_M_unwrapped_async_op != nullptr);                    // The async op should also be canceled after releasing the lock. Some objects may not be able to process Cancel requests while                    // the completed handler is executing.                    _M_unwrapped_async_op->Cancel();                }#endif            }            return true;        }         void _FinalizeAndRunContinuations(_ReturnType _Result)        {            _ContinuationList _Continuations;             _M_Result = _Result;

Page 35: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

#if defined(__cplusplus_winrt)            _M_ResultContext = ::Concurrency::preview::details::_ResultContext<_ReturnType>::_GetContext(_M_fRuntimeAggregate);#endif            {                //                // Hold this lock to ensure continuations being concurrently either get added                // to the _M_Continuations vector or wait for the result                //                critical_section::scoped_lock _LockHolder(_M_ContinuationsCritSec);                 // A task could still be in the _Created state if it was created with a task_completion_event.                // It could also be in the _Canceled state for the same reason.                _ASSERT(!_HasUserException() && !_IsCompleted());                if (_IsCanceled())                {                    _ASSERT(_M_Continuations.empty());                    return;                }                 // If a cancel request slipped through after this task was scheduled, set the state to _Canceled                // before scheduling continuations.                if (_IsPendingCancel())                {                    _M_TaskState = _Canceled;                }                else                {                    _M_TaskState = _Completed;                }                 _M_Completed.set();                _Continuations.swap(_M_Continuations);            }             _RunTaskContinuations(_Continuations, 0);        }         //        // This method is invoked when the starts executing. The task returns early if this method returns true.        //        bool _TransitionedToScheduled()        {            critical_section::scoped_lock _LockHolder(_M_ContinuationsCritSec);            if (_IsCanceled())            {                return false;            }

Page 36: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

            _ASSERT(_IsCreated());            _M_TaskState = _Started;            return true;        }         /// <summary>        ///     Helper function to schedule the task on the Task Collection.        /// </summary>        /// <param name="_Func">        ///     The function object to execute.        /// </param>        /// <param name="_InlineInApartment">        ///     Tells the method to inline the function object on the task collection instead of scheduling it for potential        ///     stealing. This should only be set to true when the continuation context does not allow for the continuation        ///     to be scheduled on a runtime thread.        /// </param>        template<typename _Function>        void _ScheduleTaskHelper(const _Function& _Func, bool _RunInline = false)        {            if (_RunInline)            {                // For chores that execute inline, the scheduled event should be set when the chore starts running - this takes place                // in _TaskContinuationParameter::_Continue(). This is to prevent a different thread performing a wait on the task from waiting                // on the task collection before the chore is actually added to it via run and wait, and thereby returning from the wait() before                // the chore has executed.                try                {                    _Func();                }                catch (const task_canceled &)                {                    _Cancel(true, 0);                }                catch (const _Task_canceled &)                {                    // PREVIEW: doesn't really do anything since _Task_canceled is not thrown by the runtime                    // We should not see _Task_canceled here since this is a top level chore being inlined.                    _ASSERT(false);                }                catch(...)                {                    _CancelWithException(std::current_exception(), 0);                }            }            else            {                {

Page 37: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

                    // Grab the lock so we can check on the cancellation status of this task. If it has already been                    // canceled, the cancellation has taken care of propagating the cancellation down, we should not                    // allocate a task collection or chore for this task. A wait on this task will then not have a task                    // to wait on and can simply return canceled.                    // If a cancellation happens AFTER this lock releases, then that means a task has been scheduled,                    // so a wait on the task will enter _RunAndWaitPPLTask, which will ensure the cancellation has completed.                    critical_section::scoped_lock _LockHolder(_M_ContinuationsCritSec);                    if (_IsCanceled())                    {                        return;                    }                     // TODO: perf optimization -- investigate using suballocator                    _M_pTaskCollection = new ::Concurrency::details::_TaskCollection();                     // Create a PPLTaskHandle for the user function. This is a _PPLTaskChore which is simply an                     // _Unrealized chore with an extra ref counter for the allocated task collection, above.                    _M_pExecutingChore = new _PPLTaskHandle<_Function>(_Func, this);                }                 // This special TaskCollection API causes the runtime to delete the task collection completing the                // execution of the chore.                _M_pTaskCollection->_ScheduleCollectionDeletingTask(_M_pExecutingChore);                 // Set the event in case anyone is waiting to notify that this task has been scheduled. In the case where we                // execute the chore inline, the event should be set after the chore has started (and therefore, finished)                // executing. This is fine, since a waiting thread could not have inlined this chore anyway.                _SetScheduledEvent();                 // If this task going out of scope and the task has already finished scheduling and executing,                 // destruct the task collection and chore to clean up memory.                if (_InterlockedDecrement(&_M_pExecutingChore->_M_collectionRefCount) == 0)                {                    // This deletion removes one of the references on the _Task_impl_base and could initiate                     // destruction of the task.                    delete _M_pExecutingChore;

Page 38: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

                }            }        }         void _ScheduleTask(void * _PData)        {            auto _PParam = (_TaskExecutionParameter<_ReturnType>*) _PData;            //            // The parameter is passed to the execution thunk in order to do the right thing.  It cannot be deleted inside the body            // of the lambda because it holds refs to the task_impl.  Deletion of the task_impl will delete the underlying task            // collection.  The lambda itself must hold reference to the task impl.  A capture by value of a shared pointer to the            // parameter accomplishes the necessary lifetime semantics.            //            std::shared_ptr<_TaskExecutionParameter<_ReturnType>> _PShParam(_PParam);             _ScheduleTaskHelper([_PShParam]() {                _PShParam->_Execute();            });        }         // Schedule a continuation to run        template <typename _InputType>        void _ScheduleContinuationTask(details::_TaskContinuationParameterBase* _PData)        {            auto _PParam = static_cast<_TaskContinuationParameter<_InputType,_ReturnType>*>(_PData);            //            // The parameter is passed to the continuation thunk in order to do the right thing.  As with _ScheduleTask, it cannot            // be deleted inside the body of the lambda because it holds refs to the task_impl.  Deletion of the task_impl will delete            // the underlying task collection.  The lambda itself must hold reference to the task impl.  A capture by value of a shared            // pointer to the parameter accomplishes the necessary lifetime semantics.            //            std::shared_ptr<_TaskContinuationParameter<_InputType,_ReturnType>> _PShParam(_PParam);             // Ensure that the continuation runs in proper context (this might be on a Concurrency Runtime thread or in a different WinRT apartment)            if (_PParam->_ContinuationContext._HasCapturedContext())            {                _PParam->_ContinuationContext._CallInContext( [_PShParam](){                    _PShParam->_Continuation->_ScheduleTaskHelper([_PShParam]() {                        // This code executes inside _PPLTaskHandle::operator(), inline on the thread that calls _ScheduleTaskHelper                        _PShParam->_Continue();                    }, true);

Page 39: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

                });            }            else            {                _ScheduleTaskHelper([_PShParam]() {                    // This code executes inside _PPLTaskHandle::operator()                    _PShParam->_Continue();                });            }        } #if defined (__cplusplus_winrt)        void _SetUnwrappedAsyncOp(_AsyncOperationType^ _AsyncOp)        {            critical_section::scoped_lock _LockHolder(_M_ContinuationsCritSec);            // Cancel the async operation if the task itself is canceled, since the thread that canceled the task missed it.            if (_IsPendingCancel())            {                _ASSERT(!_IsCanceled());                _AsyncOp->Cancel();            }            else            {                _M_unwrapped_async_op = _AsyncOp;            }        }#endif         void _SetUnwrappedTask(typename _Task_ptr<_ReturnType>::_Type _UnwrappedTask)        {            bool _Cancel = false;            {                critical_section::scoped_lock _LockHolder(_M_ContinuationsCritSec);                // Store the unwrapped task even if the continuation is pending cancel. See comments around this in _CancelAndRunContinuations.                // If an unwrapped task happens to be linked at the time a task is synchronously canceled the task should NOT schedule continuations or                 // take itself into a terminal state, since a continuation on the unwrapped task will do that.                _M_unwrapped_task = _UnwrappedTask;                if (_IsPendingCancel())                {                    _Cancel = true;                    _ASSERT(!_HasUserException() && !_IsCanceled());                }                else                {                    _M_unwrapped_task = _UnwrappedTask;                }            }            if (_Cancel)

Page 40: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

            {                // It is sufficient to cancel the unwrapped task - the exception handling continuation on the unwrapped task will                // cancel _Continuation when it is executed. Cancel outside the lock in case we catch the task before it has been scheduled                // and execute continuations inline.                _UnwrappedTask->_Cancel(false, 0);            }        }         _ReturnType _GetResult()        {#if defined(__cplusplus_winrt)            return ::Concurrency::preview::details::_ResultContext<_ReturnType>::_GetValue(_M_Result, _M_ResultContext, _M_fRuntimeAggregate);#else // defined(__cplusplus_winrt)            return _M_Result;#endif // defined(__cplusplus_winrt)        }         _ReturnType _M_Result;        // this means that the result type must have a public default ctor.        typename _Task_ptr<_ReturnType>::_Type _M_unwrapped_task;#if defined(__cplusplus_winrt)        _AsyncOperationType^ _M_unwrapped_async_op;        _ContextCallback _M_ResultContext;#endif    };     //    // ASYNC TODO: Usage of std::function for the functions returned in task::_ContinuationStub causes the input and output type names to be replicated in    //       the template decorated name a total of 14 times.  This causes the mangled names for many ConcRT FVT tests to be longer than 4096    //       characters.  The compiler is presently *CRASHING* when processing such symbols in c2.  This is a temporary workaround designed to reduce    //       the template name length and allow tests to continue to compile with the present factoring.  Once the compiler bug is fixed, this should    //       be restored to utilize a function object.    //    template<typename _In, typename _Out>     class _Workaround_Invoker    {    public:         virtual _Out _Invoke(_In _Inval) =0;         // A virtual destructor needs to be defined so that the derived class destructor is invoked when a derived class object is deleted        // using a _Workaround_Invoker*.        virtual ~_Workaround_Invoker()        {        }    };

Page 41: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

    template<typename _In, typename _Out, typename _Function>    class _Workaround_Function : public _Workaround_Invoker<_In, _Out>    {    public:         _Workaround_Function(const _Function& _Func) : _UserFunc(_Func)        {        }         virtual _Out _Invoke(_In _Inval)        {            return _UserFunc(_Inval);        }     private:         _Workaround_Function& operator=(const _Workaround_Function&);        _Function _UserFunc;    };     template<typename _ReturnType>    struct _TaskExecutionParameter    {        typedef typename _NormalizeVoidToUnitType<_ReturnType>::_Type _NormalizedReturnType;        typedef _Workaround_Invoker<_TaskExecutionParameter<_ReturnType> *, void> *_InvocationThunk;        typedef typename std::function<_NormalizedReturnType()> _NominalFunc;         _TaskExecutionParameter(typename _Task_ptr<_NormalizedReturnType>::_Type _T,                                _InvocationThunk _Func)            : _Task(_T),              _ExecutionFunction(_Func)        {        }         ~_TaskExecutionParameter()        {            delete _ExecutionFunction;        }         void _Execute()        {            if (_Task->_TransitionedToScheduled())            {                _ExecutionFunction->_Invoke(this);            }        }         typename _Task_ptr<_NormalizedReturnType>::_Type _Task;        _InvocationThunk _ExecutionFunction;    };     struct _TaskContinuationParameterBase {};

Page 42: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

    template<typename _ReturnType, typename _NewReturnType>    struct _TaskContinuationParameter : public _TaskContinuationParameterBase    {        typedef typename _NormalizeVoidToUnitType<_ReturnType>::_Type _NormalizedReturnType;        typedef typename _NormalizeVoidToUnitType<_NewReturnType>::_Type _NewNormalizedReturnType;         // typedef std::function<void(_TaskContinuationParameter<_ReturnType, _NewReturnType> *)> _InvocationThunk;        typedef _Workaround_Invoker<_TaskContinuationParameter<_ReturnType, _NewReturnType> *, void> *_InvocationThunk;         typedef typename _FixFunction<std::function<_NewNormalizedReturnType(_NormalizedReturnType)>>::_FixedFunc _NominalFunc;         _TaskContinuationParameter(typename _Task_ptr<_NormalizedReturnType>::_Type _Anc,                                   typename _Task_ptr<_NewNormalizedReturnType>::_Type _Cont,                                   _InvocationThunk _Func,                                   const task_continuation_context& _Context,                                   bool _PassExceptionsToFunc)            : _TaskContinuationParameterBase(),              _Ancestor(_Anc),              _Continuation(_Cont),              _ContinuationContext(_Context),              _ContinuationFunction(_Func),              _ProcessExceptions(_PassExceptionsToFunc)        {            // If the context has requested deferred capture, resolve it here            _ContinuationContext._Resolve(_Ancestor->_IsAsync());        }         ~_TaskContinuationParameter()        {            delete _ContinuationFunction;        }         void _Continue()        {            if (_Continuation->_TransitionedToScheduled())            {                if (_ContinuationContext._HasCapturedContext())                {                    // This continuation is executing in a captured context, and was not allowed to be scheduled by one of the runtime's threads.                    // This means the scheduled event for it has not been set yet. We set the event here.                    _Continuation->_SetScheduledEvent();                }                // _ObservesExceptions returns true if this is a 'user scheduled' task-based continuation. The runtime schedules internal task based                // continuations, but they should *never* observe exceptions.

Page 43: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

                if (_Continuation->_ObservesExceptions())                {                    _ASSERT(_ProcessExceptions);                    _Ancestor->_ObserveUserException();                }                 //_ContinuationFunction(this);                _ContinuationFunction->_Invoke(this);            }        }         typename _Task_ptr<_NormalizedReturnType>::_Type _Ancestor;        typename _Task_ptr<_NewNormalizedReturnType>::_Type _Continuation;        task_continuation_context _ContinuationContext;        _InvocationThunk _ContinuationFunction;        bool _ProcessExceptions;    };     template<typename _ResultType>    struct _Task_completion_event_impl    {        typedef std::vector<typename _Task_ptr<_ResultType>::_Type> _TaskList;         _Task_completion_event_impl() : _HasValue(false), _IsCanceled(false)        {        }         bool _HasUserException()        {            return _ExceptionHolder;        }         ~_Task_completion_event_impl()        {            for( auto _TaskIt = _Tasks.begin(); _TaskIt != _Tasks.end(); ++_TaskIt )            {                _ASSERT(!_HasValue && !_IsCanceled);                // Cancel the tasks since the event was never signaled or canceled.                (*_TaskIt)->_Cancel(true, 0);            }        }         // We need to protect the loop over the array, so concurrent_vector would not have helped        _TaskList _Tasks;        critical_section _TaskListCritSec;        _ResultType _Value;        std::shared_ptr<_ExceptionHolder> _ExceptionHolder;        bool _HasValue;        bool _IsCanceled;    };} // details

Page 44: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

#if defined(__cplusplus_winrt)// ASYNC TODO: temporary - replace with Platform::COMException when it is convertible to std::exception_ptr.// This is tracked by Dev11 Bug: 237467class async_operation_exception : public std::exception{public:    async_operation_exception(Platform::COMException^ _E):        _M_platformException(_E)    {    }     Platform::COMException^ get_platform_exception()    {        return _M_platformException;    } private:    Platform::COMException^ _M_platformException;};#endif class task_continuation_context : public details::_ContextCallback{public:     // The continuation will be executed in a context that is determined by the ancestor task and the current context.    // The default behavior of task continuations is as follows:    //   Some definitions:    //      An async task is a task that unwraps a WinRT async operation.    //      An apartment bound task is a task in the continuation tree of an async task. The apartment bound property    //          is infectious. That is, if one of the tasks in a when_all or a when_any is an async or apartment bound    //          task, then when_all task and it's continuations become apartment bound.    //   Default continuation behavior:    // - A continuation off an apartment bound task executes in the apartment where .then was called to schedule that continuation.    // - A continuation off a non-apartment bound task is scheduled on a Concurrency Runtime worker thread, in the MTA.    static task_continuation_context use_default()    {#if defined(__cplusplus_winrt)        // The callback context is created with the context set to CaptureDeferred and resolved when it is used in .then()        return task_continuation_context(true); // sets it to deferred, is resolved in the constructor of _TaskContinuationParameter#else        return task_continuation_context();#endif    }

Page 45: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

#if defined(__cplusplus_winrt)    // Creates a task continuation context which completely ignores any marshaling requirements. The continuation will run where    // the runtime deems appropriate.    static task_continuation_context use_arbitrary()    {        task_continuation_context _Arbitrary(true);         _Arbitrary._Resolve(false);        return _Arbitrary;    }     // Captures the caller's context for WinRT so that callback are made in the right apartment. By default, a callback on a task    // wrapping a WinRT async object (or the continuation chain of a WinRT async object) is made in the apartment .then is called in.    // However, this default behavior can be changed for async continuations by specifying the continuation context to be 'arbitrary',    // and for non-async continuations by specifying the continuation context to be 'current'.    static task_continuation_context use_current()    {        task_continuation_context _Current(true);        _Current._Resolve(true);        return _Current;    }#endif private:     task_continuation_context(bool _DeferCapture = false) : details::_ContextCallback(_DeferCapture)    {    }}; /// <summary>///     The task completion event class, allows users to delay the execution of a task until a condition is///     satisfied, or start a task in response to an external event./// </summary>/// <typeparam name="_ResultType">///     The result type of this task_completion_event./// </typeparam>/**/template<typename _ResultType>class task_completion_event {    typedef typename details::_Task_completion_event_impl<_ResultType>::_TaskList _TaskList;    std::shared_ptr<::Concurrency::preview::details::_Task_completion_event_impl<_ResultType>> _M_Impl;public:    template <typename T> friend class task; // task can register itself with the event by calling the private _RegisterTask    template <typename T> friend class task_completion_event;

Page 46: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

    /// <summary>    ///     The task completion event constructor.    /// </summary>    /**/    task_completion_event() : _M_Impl(std::make_shared<::Concurrency::preview::details::_Task_completion_event_impl<_ResultType>>())     {    }     /// <summary>    ///     The set the task completion event.     /// </summary>    /// <param>    ///     The result to set this event with.    /// </param>    /// <returns>    ///     If this call to set actually does set the event, <c>true</c> is returned. If the event has already been set,     ///     <c>false</c> is returned    /// </returns>    /**/    bool set(_ResultType _Result) const // 'const' (even though it's not deep) allows to safely pass events by value into lambdas    {        // subsequent sets are ignored. This makes races to set benign: the first setter wins and all others are ignored.        if (_M_Impl->_HasValue == true || _M_Impl->_IsCanceled == true)        {            return false;        }         _TaskList _Tasks;        bool _RunContinuations = false;        {            critical_section::scoped_lock _LockHolder(_M_Impl->_TaskListCritSec);             if (_M_Impl->_HasValue == false && _M_Impl->_IsCanceled == false)            {                _M_Impl->_Value = _Result;                _M_Impl->_HasValue = true;                 _Tasks.swap(_M_Impl->_Tasks);                _RunContinuations = true;            }        }         if (_RunContinuations)        {            for( auto _TaskIt = _Tasks.begin(); _TaskIt != _Tasks.end(); ++_TaskIt )            {                // Tasks created with task_completion_events can be marked as async, (we do this in when_any and when_all

Page 47: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

                // if one of the tasks involved is an async task). Since continuations of async tasks can execute inline, we                // need to run continuations after the lock is released.                (*_TaskIt)->_FinalizeAndRunContinuations(_M_Impl->_Value);            }            if (_M_Impl->_HasUserException())            {                _M_Impl->_ExceptionHolder.reset();            }            return true;        }         return false;    }     /// <summary>    ///     Internal method that cancel the task_completion_event.    /// </summary>    /**/    bool _CancelInternal(bool _UserException, const std::shared_ptr<details::_ExceptionHolder>& _ExHolder) const    {        // Cancellation of task completion events is an internal only utility. Our usage is such that _CancelInternal        // will never be invoked if the task completion event has been set.        _ASSERT(!_M_Impl->_HasValue);        if (_M_Impl->_IsCanceled == true)        {            return false;        }         _TaskList _Tasks;        bool _Cancel = false;        {            critical_section::scoped_lock _LockHolder(_M_Impl->_TaskListCritSec);            _ASSERT(!_M_Impl->_HasValue);            if (_M_Impl->_IsCanceled == false)            {                _M_Impl->_IsCanceled = true;                _Tasks.swap(_M_Impl->_Tasks);                _Cancel = true;            }        }         if (_Cancel)        {            for( auto _TaskIt = _Tasks.begin(); _TaskIt != _Tasks.end(); ++_TaskIt )            {                // Need to call this after the lock is released. See comments in set().                if (_UserException)                {                    (*_TaskIt)->_CancelWithExceptionHolder(_ExHolder, true, 0

Page 48: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

);                }                else                {                    (*_TaskIt)->_Cancel(true, 0);                }            }             if (_M_Impl->_HasUserException())            {                _M_Impl->_ExceptionHolder.reset();            }        }        return _Cancel;    }     /// <summary>    ///     Cancel the task_completion_event. Any task created using this event will be marked as canceled if it has    ///     not already been set.    /// </summary>    /**/    bool _Cancel() const    {        // Cancel with the stored exception if one exists.        return _CancelInternal(_M_Impl->_HasUserException(), _M_Impl->_ExceptionHolder);    }     /// <summary>    ///     Cancel the task_completion_event with the exception provided. Any task created using this event will be canceled    ///     with the same exception.    /// </summary>    /**/    bool _Cancel(const std::shared_ptr<details::_ExceptionHolder>& _ExHolder) const    {        // We want to make sure that an exception doesn't override a stored exception via this method. If the usage changes such        // that this assert starts to fire, an exception from a the tasks in a when_any or when_all may be unobserved.        _ASSERT(!_M_Impl->_HasUserException());        return _CancelInternal(true, _ExHolder);    }     /// <summary>    ///     Method that stores an exception in the task completion event. This is used internally by when_any.    ///     Note, this does not cancel the task completion event. A task completion event with a stored exception    ///     can bet set() successfully. If it is canceled, it will cancel with the stored exception, if one is present.    /// </summary>    /**/

Page 49: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

    bool _StoreException(const std::shared_ptr<details::_ExceptionHolder>& _ExHolder) const    {        // Storing exceptions on task completion events is an internal only mechanism.        if (_M_Impl->_HasValue == true || _M_Impl->_IsCanceled == true || _M_Impl->_HasUserException())        {            return false;        }        critical_section::scoped_lock _LockHolder(_M_Impl->_TaskListCritSec);        if (_M_Impl->_HasValue == false && _M_Impl->_IsCanceled == false && !_M_Impl->_HasUserException())        {            _M_Impl->_ExceptionHolder = _ExHolder;            return true;        }        return false;    } private:     /// <summary>    ///     Register a task with this event. This function is called when a task is constructed using    ///     a task_completion_event.    /// </summary>    /**/    void _RegisterTask(typename ::Concurrency::preview::details::_Task_ptr<_ResultType>::_Type _TaskParam)    {        _TaskParam->_SetScheduledEvent();        critical_section::scoped_lock _LockHolder(_M_Impl->_TaskListCritSec);        //        // Cancellation of and setting exceptions on task completion events is not exposed, and the internal implementation        // does not register tasks with events after they are canceled or have an exception stored.        //        _ASSERT(!_M_Impl->_IsCanceled);        _ASSERT(!_M_Impl->_ExceptionHolder);        if (_M_Impl->_HasValue)        {            _TaskParam->_FinalizeAndRunContinuations(_M_Impl->_Value);        }        else        {            _M_Impl->_Tasks.push_back(_TaskParam);        }    }}; /// <summary>///     The task completion event class, allows users to delay the execution of a task until a condition is

Page 50: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

///     satisfied, or start a task in response to an external event.///     Template specialization for void./// </summary>/**/template<>class task_completion_event<void>{    task_completion_event<::Concurrency::preview::details::_Unit_type> _UnitEvent; public:    template <typename T> friend class task; // task can register itself with the event by calling the private _RegisterTask     /// <summary>    ///     The set the task completion event.     /// </summary>    /// <returns>    ///     If this call to set actually does set the event, <c>true</c> is returned. If the event has already been set,     ///     <c>false</c> is returned    /// </returns>    /**/    bool set() const // 'const' (even though it's not deep) allows to safely pass events by value into lambdas    {        return _UnitEvent.set(::Concurrency::preview::details::_Unit_type());    }     /// <summary>    ///     Cancel the task_completion_event. Any task created using this event will be marked as canceled if it has    ///     not already been set.    /// </summary>    /**/    void _Cancel() const // 'const' (even though it's not deep) allows to safely pass events by value into lambdas    {        _UnitEvent._Cancel();    }     /// <summary>    ///     Cancel the task_completion_event with the exception holder provided. Any task created using this event will be canceled    ///     with the same exception.    /// </summary>    /**/    void _Cancel(const std::shared_ptr<details::_ExceptionHolder>& _ExHolder) const    {        _UnitEvent._Cancel(_ExHolder);    }     /// <summary>    ///     Method that stores an exception in the task completion event. Thi

Page 51: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

s is used internally by when_any.    ///     Note, this does not cancel the task completion event. A task completion event with a stored exception    ///     can bet set() successfully. If it is canceled, it will cancel with the stored exception, if one is present.    /// </summary>    /**/    bool _StoreException(const std::shared_ptr<details::_ExceptionHolder>& _ExHolder) const    {        return _UnitEvent._StoreException(_ExHolder);    } private:     /// <summary>    ///     Register a task with this event. This function is called when a task is constructed using    ///     a task_completion_event.    /// </summary>    /**/    void _RegisterTask(::Concurrency::preview::details::_Task_ptr<::Concurrency::preview::details::_Unit_type>::_Type _TaskParam)    {        _UnitEvent._RegisterTask(_TaskParam);    }}; /// <summary>///     The PPL task class./// </summary>/// <typeparam name="_ReturnType">///     The result type of this task./// </typeparam>/**/template<typename _ReturnType>class task{public:    typedef _ReturnType _TaskType;     /// <summary>    ///     Constructor for a PPL task.    /// </summary>    /// <param name="_Func">    ///     The function for this PPL task to execute.    /// </param>    /// <param name="_Event">    ///     A task_completion_event with which to create this task. The task will be set as completed    ///     when the task_completion_event is set.    /// </param>    /// <remarks>    ///     The default constructor for a task is only present in order to allow tasks to be used within containers.

Page 52: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

    ///     Users should never create a default constructed task because it is not usable: you cannot run anything,    ///     continue any work, or wait on it.    /// </remarks>    /**/    task() : _M_Impl(NULL)     {        // The default constructor should create a task with a NULL impl. This is a signal that the        // task is not usable and should throw if any wait(), get() or then() APIs are used.    }     /// <summary>    ///     Create an underlying task implementation.    /// </summary>    /// <remarks>    ///     In one instance (the then() API) we need to default construct a task with an Impl, since    ///     that is the continuation task being returned.    /// </remarks>    /**/    void _CreateImpl()    {        _M_Impl = ::Concurrency::preview::details::_Task_ptr<_ReturnType>::make();    }     /// <summary>    ///     Set the implementation of the task to be the supplied implementaion.    /// </summary>    /// <remarks>    ///     When a continuation that takes a task<T> is scheduled on a task<T>, this method is    ///     used to generate a task with the same implementataion as the ancestor task, effectively    ///     incrementing the reference on the shared_ptr in the ancestor task.    /// </remarks>    /**/    void _SetImpl(typename ::Concurrency::preview::details::_Task_ptr<_ReturnType>::_Type _Impl)    {        _ASSERT(_M_Impl == NULL);        _M_Impl = _Impl;    }     /// <summary>    ///     Determine whether the task is a task that wraps an async object or is descended from the continuation chain of such a task.    /// </summary>    bool _IsAsync() const    {        return _GetImpl()->_IsAsync();

Page 53: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

    }     /// <summary>    ///     Sets a property determining whether the task is a task that wraps an async object or is descended from the continuation chain of such a task.    /// </summary>    void _SetAsync(bool _Async = true)    {        _GetImpl()->_SetAsync(_Async);    }     /// <summary>    ///     Return the underlying implementation for this task.    /// </summary>    /// <returns>    ///     The underlying implementation for the task.    /// </returns>    /**/    typename ::Concurrency::preview::details::_Task_ptr<_ReturnType>::_Type _GetImpl() const    {         return _M_Impl;     }     template <typename T> friend class task; private:     // The underlying implementation for this task    typename ::Concurrency::preview::details::_Task_ptr<_ReturnType>::_Type _M_Impl;     /// <summary>    ///     Static function that executes a continuation function. This function is recorded by a parent task implementation    ///     when a continuation is created in order to execute later.    /// </summary>    /// <typeparam name="_NewReturnType">    ///     The return type of the continuation.    /// </typeparam>    /// <param name="_PData">    ///     A void* pointing to a _TaskContinationParameter, which contains pointers to this (parent) task implementation    ///     as well as the the continuation task implementation.    /// </param>    /**/    template <typename _NewReturnType>    static void __cdecl _RunContinuation(details::_TaskContinuationParameterBase* _PData, size_t _InvocationNestingLevel)    {        auto _PParam = static_cast<::Concurrency::preview::details::_TaskContinuationParameter<_ReturnType,_NewReturnType>*>(_PData);        if (_PParam->_Ancestor->_IsCanceled() && !_PParam->_ProcessExceptions)

Page 54: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

        {            if (_PParam->_Ancestor->_HasUserException())            {                // If the ancestor encountered an exception, transfer the exception to the continuation                // This traverses down the tree to propagate the exception.                _PParam->_Continuation->_CancelWithExceptionHolder(_PParam->_Ancestor->_GetExceptionHolder(), true, _InvocationNestingLevel);            }            else            {                // If the ancestor was canceled, then your own execution should be canceled.                // This traverses down the tree to cancel it.                _PParam->_Continuation->_Cancel(true, _InvocationNestingLevel);            }            // Delete the parameter to free up the reference for this task and the ancestor.            delete _PParam;        }        else        {            // This can only run when the ancestor has completed or it's a task based continuation that fires when a task is canceled            // (with or without a user exception).            _ASSERT(_PParam->_Ancestor->_IsCompleted() || _PParam->_ProcessExceptions);             if (!_PParam->_Continuation->_IsCanceled())            {                _PParam->_Continuation->_ScheduleContinuationTask<_ReturnType>(_PParam);            }            else            {                delete _PParam;            }        }    } #if defined(__cplusplus_winrt)    /// <summary>    ///     Initializer invoked by the constructor for a PPL task.    /// </summary>    /// <remarks>    ///     Create a task from an asynchronous operation IAsyncOperation<T>    /// </remarks>    /**/    void _TaskInitAsyncOp(Windows::Foundation::IAsyncOperation<typename details::_ValueTypeOrRefType<_ReturnType>::_Value>^ _AsyncOp)    {        //typedef typename details::_ValueTypeOrRefType<_ReturnType>::_Value _Ty;        _M_Impl->_M_fFromAsync = true;

Page 55: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

        _M_Impl->_SetScheduledEvent();        // Mark this task as started here since we can set the state in the constructor without acquiring a lock. Once _AsyncInit        // returns a completion could execute concurrently and the task must be fully initialized before that happens.        _M_Impl->_M_TaskState = details::_Task_impl_base::_Started;        // Pass the shared pointer into _AsyncInit for storage in the Async Callback.        details::_Task_impl_base::_AsyncInit<_ReturnType, _ReturnType>(_M_Impl, _AsyncOp);    }#endif     template<typename _InternalReturnType, typename _Function>    void _TaskInitWithFunctor(const _Function& _Func)    {        typedef ::Concurrency::preview::details::_InitFunctorTypeTraits<_InternalReturnType, decltype(_Func())> _Async_type_traits;         _M_Impl->_M_fFromAsync = _Async_type_traits::_IsAsyncTask;        _M_Impl->_M_fUnwrappedTask = _Async_type_traits::_IsUnwrappedTaskOrAsync;         auto _PParam = new ::Concurrency::preview::details::_TaskExecutionParameter<_InternalReturnType>(            _GetImpl(),            _InitStub<_InternalReturnType, _Function>(_Func, _Async_type_traits::_AsyncKind())            );        _M_Impl->_ScheduleTask(_PParam);    }     template<typename _InternalReturnType, typename _Function>    //static std::function<void(::Concurrency::preview::details::_TaskExecutionParameter<_InternalReturnType> *)>     static ::Concurrency::preview::details::_Workaround_Invoker<::Concurrency::preview::details::_TaskExecutionParameter<_InternalReturnType> *, void> *    _InitStub(const _Function& _Func, /* returns IAsync */ details::_TypeSelectorNoAsync)    {        //        // Overload 0: returns _InternalReturnType        //        // This is the most basic task with no unwrapping        //        auto _StubFunc = [=](::Concurrency::preview::details::_TaskExecutionParameter<_InternalReturnType> *_PParam){            _PParam->_Task->_FinalizeAndRunContinuations(_Init_func_transformer<_InternalReturnType>::_Perform(_Func)());        };         // return _StubFunc;        return new ::Concurrency::preview::details::_Workaround_Function<::Co

Page 56: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

ncurrency::preview::details::_TaskExecutionParameter<_InternalReturnType> *, void, decltype(_StubFunc)>(_StubFunc);    }     template<typename _InternalReturnType, typename _Function>    //static std::function<void(::Concurrency::preview::details::_TaskExecutionParameter<_InternalReturnType> *)>     static ::Concurrency::preview::details::_Workaround_Invoker<::Concurrency::preview::details::_TaskExecutionParameter<_InternalReturnType> *, void> *    _InitStub(const _Function& _Func, /* returns IAsync */ details::_TypeSelectorAsyncOperationOrTask)    {        //        // Overload 1: returns IAsyncOperation<_InternalReturnType>^ (only uder /ZW)        //                   or        //             returns task<_InternalReturnType>        //        // This is task whose functor returns an async operation or a task which will be unwrapped for continuation        // Depending on the output type, the right _AsyncInit gets invoked        //        auto _StubFunc = [=](::Concurrency::preview::details::_TaskExecutionParameter<_InternalReturnType> *_PParam){            details::_Task_impl_base::_AsyncInit<_ReturnType, _InternalReturnType>(_PParam->_Task, _Func());        };         // return _StubFunc;        return new ::Concurrency::preview::details::_Workaround_Function<::Concurrency::preview::details::_TaskExecutionParameter<_InternalReturnType> *, void, decltype(_StubFunc)>(_StubFunc);    }     template<typename _InternalReturnType, typename _Function>    //static std::function<void(::Concurrency::preview::details::_TaskExecutionParameter<_InternalReturnType> *)>     static ::Concurrency::preview::details::_Workaround_Invoker<::Concurrency::preview::details::_TaskExecutionParameter<_InternalReturnType> *, void> *    _InitStub(const _Function& _Func, /* returns IAsync */ details::_TypeSelectorAsyncAction)    {        //        // Overload 2: returns IAsyncAction^        //        // This is task whose functor returns an async action which will be unwrapped for continuation        //        auto _StubFunc = [=](::Concurrency::preview::details::_TaskExecutionParameter<_InternalReturnType> *_PParam){            details::_Task_impl_base::_AsyncInit<_ReturnType, _InternalReturnType>(_PParam->_Task, ref new details::_IAsyncActionToAsyncOperationConverter(_Func()));

Page 57: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

        };         // return _StubFunc;        return new ::Concurrency::preview::details::_Workaround_Function<::Concurrency::preview::details::_TaskExecutionParameter<_InternalReturnType> *, void, decltype(_StubFunc)>(_StubFunc);    }     template<typename _InternalReturnType, typename _Function>    //static std::function<void(::Concurrency::preview::details::_TaskExecutionParameter<_InternalReturnType> *)>     static ::Concurrency::preview::details::_Workaround_Invoker<::Concurrency::preview::details::_TaskExecutionParameter<_InternalReturnType> *, void> *    _InitStub(const _Function& _Func, /* returns IAsync */ details::_TypeSelectorAsyncOperationWithProgress)    {        //        // Overload 3: returns IAsyncOperationWithProgress<_InternalReturnType, _ProgressType>^        //        // This is task whose functor returns an async operation with progress which will be unwrapped for continuation        //        auto _StubFunc = [=](::Concurrency::preview::details::_TaskExecutionParameter<_InternalReturnType> *_PParam){            auto _OpWithProgress = _Func();            typedef details::_GetProgressType<decltype(_OpWithProgress)>::_Value _ProgressType;             details::_Task_impl_base::_AsyncInit<_ReturnType, _InternalReturnType>(_PParam->_Task,                    ref new details::_IAsyncOperationWithProgressToAsyncOperationConverter<_InternalReturnType,_ProgressType>(_OpWithProgress));        };         // return _StubFunc;        return new ::Concurrency::preview::details::_Workaround_Function<::Concurrency::preview::details::_TaskExecutionParameter<_InternalReturnType> *, void, decltype(_StubFunc)>(_StubFunc);    }     template<typename _InternalReturnType, typename _Function>    //static std::function<void(::Concurrency::preview::details::_TaskExecutionParameter<_InternalReturnType> *)>     static ::Concurrency::preview::details::_Workaround_Invoker<::Concurrency::preview::details::_TaskExecutionParameter<_InternalReturnType> *, void> *    _InitStub(const _Function& _Func, /* returns IAsync */ details::_TypeSelectorAsyncActionWithProgress)    {        //        // Overload 4: returns IAsyncActionWithProgress<_ProgressType>^        //        // This is task whose functor returns an async action with progress which will be unwrapped for continuation

Page 58: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

        //        auto _StubFunc = [=](::Concurrency::preview::details::_TaskExecutionParameter<_InternalReturnType> *_PParam){            auto _OpWithProgress = _Func();            typedef details::_GetProgressType<decltype(_OpWithProgress)>::_Value _ProgressType;             details::_Task_impl_base::_AsyncInit<_ReturnType, _InternalReturnType>(_PParam->_Task, ref new details::_IAsyncActionWithProgressToAsyncOperationConverter<_ProgressType>(_OpWithProgress));        };         // return _StubFunc;        return new ::Concurrency::preview::details::_Workaround_Function<::Concurrency::preview::details::_TaskExecutionParameter<_InternalReturnType> *, void, decltype(_StubFunc)>(_StubFunc);    }     /// <summary>    ///     Initializer invoked by the constructor for a PPL task.    /// </summary>    /// <param name="_Event">    ///     A task_completion_event with which to create this task. The task will be set as completed    ///     when the task_completion_event is set.    /// </param>    /**/    void _TaskInitNoFunctor(task_completion_event<_ReturnType>& _Event)    {        _Event._RegisterTask(_M_Impl);    } #if defined(__cplusplus_winrt)    void _TaskInitNoFunctor(Windows::Foundation::IAsyncOperation<typename details::_ValueTypeOrRefType<_ReturnType>::_Value>^ _AsyncOp)    {        _TaskInitAsyncOp(_AsyncOp);    }     /// <summary>    ///     Constructor for a PPL task.    /// </summary>    /// <remarks>    ///     Create a task from an asynchronous operation with progress IAsyncOperationWithProgress<T>    /// </remarks>    /**/    template<typename _Progress>    void _TaskInitNoFunctor(Windows::Foundation::IAsyncOperationWithProgress<typename details::_ValueTypeOrRefType<_ReturnType>::_Value, _Progress>^ _AsyncOp)    {        _TaskInitAsyncOp(ref new details::_IAsyncOperationWithProgressToAsyncOperationConverter<typename details::_ValueTypeOrRefType<_ReturnType>::_Value

Page 59: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

, _Progress>(_AsyncOp));    } #endif     // _TaskInitMaybeFunctor overload for non-callable objects.    template<typename _Function>    void _TaskInitMaybeFunctor(_Function& _Func, std::true_type)    {        _TaskInitWithFunctor<_ReturnType, _Function>(_Func);    }     // _TaskInitMaybeFunctor overload for non-callable objects.    template<typename _Ty>    void _TaskInitMaybeFunctor(_Ty& _Param, std::false_type)    {        _TaskInitNoFunctor(_Param);    } public:    /// <summary>    ///     The non-default constructor of the task class. See _TaskInitNoFunctor overloads for the    ///     various parameter types the constructor can accept.    /// </summary>    template<typename _Ty>    explicit task(_Ty _Param) : _M_Impl(::Concurrency::preview::details::_Task_ptr<_ReturnType>::make())    {        _TaskInitMaybeFunctor(_Param, details::_IsCallable(_Param,0));    }     /// <summary>    ///     Destructor for a PPL task.    /// </summary>    /**/    ~task()    {    }     /// <summary>    ///     A utility function for executing task functions which helps to manage different types. Since void tasks can accept continuations that    ///     take task<void>, the input type is templatized.    /// </summary>    /// <typeparam name="_InpType">    ///     The output type of the function.    /// </typeparam>    /// <typeparam name="_OutType">    ///     The output type of the function.    /// </typeparam>    /**/    template<typename _InpType, typename _OutType>    class _Continuation_func_transformer    {

Page 60: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

    public:        static typename ::Concurrency::preview::details::_TaskContinuationParameter<_InpType,_OutType>::_NominalFunc _Perform(typename details::_FixFunction<std::function<_OutType(_InpType)>>::_FixedFunc _Func)        {            return _Func;        }    };     /// <summary>    ///     A utility function for executing task functions which helps to manage different types. Since void tasks can accept continuations that    ///     take task<void>, the input type is templatized.    /// </summary>    /// <typeparam name="_OutType">    ///     The output type of the function.    /// </typeparam>    /**/    template<typename _OutType>    class _Continuation_func_transformer<void, _OutType>    {    public:        static typename ::Concurrency::preview::details::_TaskContinuationParameter<void,_OutType>::_NominalFunc _Perform(std::function<_OutType(void)> _Func)        {            return ::Concurrency::preview::details::_MakeUnitToTFunc<_OutType>(_Func);        }    };     /// <summary>    ///     A utility function for executing task functions which helps to manage different types. Since void tasks can accept continuations that    ///     take task<void>, the input type is templatized.    /// </summary>    /// <typeparam name="_OutType">    ///     The output type of the function.    /// </typeparam>    /**/    template<typename _InType>    class _Continuation_func_transformer<_InType, void>    {    public:        static typename ::Concurrency::preview::details::_TaskContinuationParameter<_InType,void>::_NominalFunc _Perform(typename details::_FixFunction<std::function<void(_InType)>>::_FixedFunc _Func)        {            return ::Concurrency::preview::details::_MakeTToUnitFunc<_InType>(_Func);        }    };     /// <summary>    ///     A utility function for executing task functions which helps to ma

Page 61: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

nage different types. Since void tasks can accept continuations that    ///     take task<void>, the input type is templatized.    /// </summary>    /**/    template<>    class _Continuation_func_transformer<void, void>    {    public:        static ::Concurrency::preview::details::_TaskContinuationParameter<void,void>::_NominalFunc _Perform(std::function<void(void)> _Func)        {            return ::Concurrency::preview::details::_MakeUnitToUnitFunc(_Func);        }    };     template<typename _RetType>    class _Init_func_transformer    {    public:        static typename ::Concurrency::preview::details::_TaskExecutionParameter<_RetType>::_NominalFunc _Perform(std::function<_RetType(void)> _Func)        {            return _Func;        }    };     template<>    class _Init_func_transformer<void>    {    public:        static ::Concurrency::preview::details::_TaskExecutionParameter<void>::_NominalFunc _Perform(std::function<void(void)> _Func)        {            return ::Concurrency::preview::details::_MakeVoidToUnitFunc(_Func);        }    };     /// <summary>    ///     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.    /// </summary>    /// <typeparam name="_FuncInputType">    ///     The input type of the task.    /// </typeparam>    /// <typeparam name="_FuncOutputType">    ///     The output type of the task.    /// </typeparam>    /**/    template<typename _FuncInputType, typename _FuncOutputType>    static void _ScheduleContinuation(::Concurrency::preview::details::_TaskContinuationParameter<_FuncInputType,_FuncOutputType> *_PParam)

Page 62: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

    {        enum { _Nothing, _Schedule, _Cancel, _CancelWithException } _Do = _Nothing;         auto _Ancestor = _PParam->_Ancestor;        _ASSERT (_Ancestor != nullptr);        // If the task has canceled, cancel the continuation. If the task has completed, execute the continuation right away.        // Otherwise, add it to the list of pending continuations        {            critical_section::scoped_lock _LockHolder(_Ancestor->_M_ContinuationsCritSec);            if (_Ancestor->_IsCompleted() || (_Ancestor->_IsCanceled() && _PParam->_ProcessExceptions))            {                _Do = _Schedule;            }            else if (_Ancestor->_IsCanceled())            {                if (_Ancestor->_HasUserException())                {                    _Do = _CancelWithException;                }                else                {                    _Do = _Cancel;                }            }            else            {                _Ancestor->_M_Continuations.push_back(details::_TaskProcWithParam(_RunContinuation<_FuncOutputType>,_PParam));            }        }         // Cancellation and execution of continuations should be performed after releasing the lock. Continuations off of        // async tasks may execute inline.        switch (_Do)        {            case _Schedule:            {                _PParam->_Continuation->_ScheduleContinuationTask<_FuncInputType>(_PParam);                break;            }            case _Cancel:            {                // If the ancestor was canceled, then your own execution should be canceled.                // This traverses down the tree to cancel it.                _PParam->_Continuation->_Cancel(true, 0);                // Delete the parameter to free up the reference for this task and the ancestor

Page 63: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

                delete _PParam;                break;            }            case _CancelWithException:            {                // If the ancestor encountered an exception, transfer the exception to the continuation                // This traverses down the tree to propagate the exception.                _PParam->_Continuation->_CancelWithExceptionHolder(_Ancestor->_GetExceptionHolder(), true, 0);                // Delete the parameter to free up the reference for this task and the ancestor                delete _PParam;            }            case _Nothing:            default:                break;        }    }     /// <summary>    ///     Add a continuation task to this task. The continuation will execute when this task completes, and its function    ///     will be presented the output of this task's function.    /// </summary>    /// <typeparam name="_Function">    ///     The type of the function object that will be invoked by this task.    /// </typeparam>    /// <param name="_Func">    ///     The continuation function to execute when this task completes. This continuation function must take as input the     ///     output of this parent task that it is continuing from.    /// </param>    /// <returns>    ///     A new task which will be scheduled for execution when this current task completes. The new task's type will    ///     be the output of the function <c>_Func</c>    /// </returns>    /**/    template<typename _Function>    auto then(const _Function& _Func) const -> typename ::Concurrency::preview::details::_ContinuationTypeTraits<_Function, _ReturnType>::_TaskOfType     {        return _ThenImpl<_ReturnType, _Function>(_Func, task_continuation_context::use_default());    } #if defined(__cplusplus_winrt)    /// <summary>    ///     Add a continuation task to this task. The continuation will execute when this task completes, and its function    ///     will be presented the output of this task's function.    /// </summary>    /// <typeparam name="_Function">

Page 64: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

    ///     The type of the function object that will be invoked by this task.    /// </typeparam>    /// <param name="_Func">    ///     The continuation function to execute when this task completes. This continuation function must take as input the     ///     output of this parent task that it is continuing from.    /// </param>    /// <param name="_ContinuationContext">    ///     A variable that specifies where the continuation should execute.    /// </param>    /// <returns>    ///     A new task which will be scheduled for execution when this current task completes. The new task's type will    ///     be the output of the function <c>_Func</c>    /// </returns>    /**/    template<typename _Function>    auto then(const _Function& _Func, task_continuation_context _ContinuationContext) const -> typename ::Concurrency::preview::details::_ContinuationTypeTraits<_Function, _ReturnType>::_TaskOfType    {        return _ThenImpl<_ReturnType, _Function>(_Func, _ContinuationContext);    }#endif     /// <summary>    ///     An internal version of then that takes additional flags.    /// </summary>    /**/    template<typename _Function>    auto _Then(const _Function& _Func, bool _ObservesExceptions, bool _Aggregating) const -> typename ::Concurrency::preview::details::_ContinuationTypeTraits<_Function, _ReturnType>::_TaskOfType    {        return _ThenImpl<_ReturnType, _Function>(_Func, task_continuation_context::use_default(), _ObservesExceptions, _Aggregating);    }     /// <summary>    ///     The one and only implementation of then for void and non-void tasks    /// </summary>    /**/    template<typename _InternalReturnType, typename _Function>    auto _ThenImpl(const _Function& _Func, const task_continuation_context& _ContinuationContext,        bool _ObservesExceptions = true, bool _Aggregating = false) const -> typename ::Concurrency::preview::details::_ContinuationTypeTraits<_Function, _InternalReturnType>::_TaskOfType    {        if (_M_Impl == NULL)        {            throw invalid_operation("then() cannot be called on a default con

Page 65: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

structed task.");        }         typedef ::Concurrency::preview::details::_FunctionTypeTraits<_Function, _InternalReturnType> _Function_type_traits;        typedef ::Concurrency::preview::details::_TaskTypeTraits<_Function_type_traits::_FuncRetType> _Async_type_traits;        typedef _Async_type_traits::_TaskRetType _TaskType;         task<_TaskType> _ContinuationTask;        _ContinuationTask._CreateImpl();         _ContinuationTask._GetImpl()->_M_fFromAsync = (_GetImpl()->_M_fFromAsync || _Async_type_traits::_IsAsyncTask);        _ContinuationTask._GetImpl()->_M_fRuntimeAggregate = _Aggregating;        _ContinuationTask._GetImpl()->_M_fUnwrappedTask = _Async_type_traits::_IsUnwrappedTaskOrAsync;        _ContinuationTask._GetImpl()->_M_fObservesExceptions = _Function_type_traits::_Takes_task() && _ObservesExceptions;         auto _PParam = new ::Concurrency::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType>(            _GetImpl(),            _ContinuationTask._GetImpl(),            _ContinuationStub<_InternalReturnType, _TaskType, _Function>(_Func, _Function_type_traits::_Takes_task(), _Async_type_traits::_AsyncKind()),            _ContinuationContext,            _Function_type_traits::_Takes_task()            );         _ScheduleContinuation(_PParam);        return _ContinuationTask;    }     template<typename _InternalReturnType, typename _TaskType, typename _Function>    // std::function<void(::Concurrency::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType> *)>     static ::Concurrency::preview::details::_Workaround_Invoker<::Concurrency::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType> *, void> *    _ContinuationStub(const _Function& _Func, /* takes task */ std::false_type, /* returns IAsync */ details::_TypeSelectorNoAsync)    {        //        // Overload 0-0: _InternalReturnType -> _TaskType        //        // This is a straight task continuation which simply invokes its target with the ancestor's completion argument        //        auto _StubFunc = [=](::Concurrency::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType> *_PParam){            _PParam->_Continuation->_FinalizeAndRunContinuations(_Continuation_func_transformer<_InternalReturnT

Page 66: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

ype, _TaskType>::_Perform(_Func)(_PParam->_Ancestor->_GetResult()));        };         // return _StubFunc;        return new ::Concurrency::preview::details::_Workaround_Function<::Concurrency::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType> *, void, decltype(_StubFunc)>(_StubFunc);    }     template<typename _InternalReturnType, typename _TaskType, typename _Function>    // std::function<void(::Concurrency::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType> *)>     static ::Concurrency::preview::details::_Workaround_Invoker<::Concurrency::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType> *, void> *    _ContinuationStub(const _Function& _Func, /* takes task */ std::false_type, /* returns IAsync */ details::_TypeSelectorAsyncOperationOrTask)    {        //        // Overload 0-1: _InternalReturnType -> IAsyncOperation<_TaskType>^ (only uder /ZW)        //               or        //               _InternalReturnType -> task<_TaskType>        //        // This is a straight task continuation which returns an async operation or a task which will be unwrapped for continuation        // Depending on the output type, the right _AsyncInit gets invoked        //         auto _StubFunc = [=](::Concurrency::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType> *_PParam){            typedef ::Concurrency::preview::details::_FunctionTypeTraits<_Function, _InternalReturnType>::_FuncRetType _FuncOutputType;            typedef details::_NormalizeVoidToUnitType<_TaskType>::_Type _NormalizedTaskType;             details::_Task_impl_base::_AsyncInit<_NormalizedTaskType,_TaskType>(                _PParam->_Continuation,                 _Continuation_func_transformer<_InternalReturnType, _FuncOutputType>::_Perform(_Func)(_PParam->_Ancestor->_GetResult())                );        };         // return _StubFunc;        return new ::Concurrency::preview::details::_Workaround_Function<::Concurrency::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType> *, void, decltype(_StubFunc)>(_StubFunc);    } #if defined(__cplusplus_winrt)     template<typename _InternalReturnType, typename _TaskType, typename _Func

Page 67: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

tion>    // std::function<void(::Concurrency::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType> *)>     static ::Concurrency::preview::details::_Workaround_Invoker<::Concurrency::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType> *, void> *    _ContinuationStub(const _Function& _Func, /* taskes task */ std::false_type, /* returns IAsync */ details::_TypeSelectorAsyncAction)    {        //        // Overload 0-2: _InternalReturnType -> IAsyncAction^        //        // This is a straight task continuation which returns an async action which will be unwrapped for continuation        //        auto _StubFunc = [=](::Concurrency::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType> *_PParam){            typedef ::Concurrency::preview::details::_FunctionTypeTraits<_Function, _InternalReturnType>::_FuncRetType _FuncOutputType;            typedef details::_NormalizeVoidToUnitType<_TaskType>::_Type _NormalizedTaskType;             details::_Task_impl_base::_AsyncInit<_NormalizedTaskType,_TaskType>(                _PParam->_Continuation,                 ref new details::_IAsyncActionToAsyncOperationConverter(                    _Continuation_func_transformer<_InternalReturnType, _FuncOutputType>::_Perform(_Func)(_PParam->_Ancestor->_GetResult())));        };         // return _StubFunc;        return new ::Concurrency::preview::details::_Workaround_Function<::Concurrency::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType> *, void, decltype(_StubFunc)>(_StubFunc);    }     template<typename _InternalReturnType, typename _TaskType, typename _Function>    // std::function<void(::Concurrency::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType> *)>     static ::Concurrency::preview::details::_Workaround_Invoker<::Concurrency::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType> *, void> *    _ContinuationStub(const _Function& _Func, /* taskes task */ std::false_type, /* returns IAsync */ details::_TypeSelectorAsyncOperationWithProgress)    {        //        // Overload 0-3: _InternalReturnType -> IAsyncOperationWithProgress<_TaskType, _ProgressType>^        //        // This is a straight task continuation which returns an async operation with progress which will be unwrapped for continuation        //        auto _StubFunc = [=]

Page 68: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

(::Concurrency::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType> *_PParam){            typedef ::Concurrency::preview::details::_FunctionTypeTraits<_Function, _InternalReturnType>::_FuncRetType _FuncOutputType;            typedef details::_NormalizeVoidToUnitType<_TaskType>::_Type _NormalizedTaskType;             auto _OpWithProgress = _Continuation_func_transformer<_InternalReturnType, _FuncOutputType>::_Perform(_Func)(_PParam->_Ancestor->_GetResult());            typedef details::_GetProgressType<decltype(_OpWithProgress)>::_Value _ProgressType;             details::_Task_impl_base::_AsyncInit<_NormalizedTaskType,_TaskType>(                _PParam->_Continuation,                 ref new details::_IAsyncOperationWithProgressToAsyncOperationConverter<_TaskType,_ProgressType>(_OpWithProgress));        };         // return _StubFunc;        return new ::Concurrency::preview::details::_Workaround_Function<::Concurrency::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType> *, void, decltype(_StubFunc)>(_StubFunc);    }     template<typename _InternalReturnType, typename _TaskType, typename _Function>    // std::function<void(::Concurrency::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType> *)>     static ::Concurrency::preview::details::_Workaround_Invoker<::Concurrency::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType> *, void> *    _ContinuationStub(const _Function& _Func, /* taskes task */ std::false_type, /* returns IAsync */ details::_TypeSelectorAsyncActionWithProgress)    {        //        // Overload 0-4: _InternalReturnType -> IAsyncActionWithProgress<_ProgressType>^         //        // This is a straight task continuation which returns an async action with progress which will be unwrapped for continuation        //        auto _StubFunc = [=](::Concurrency::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType> *_PParam){            typedef ::Concurrency::preview::details::_FunctionTypeTraits<_Function, _InternalReturnType>::_FuncRetType _FuncOutputType;            typedef details::_NormalizeVoidToUnitType<_TaskType>::_Type _NormalizedTaskType;             auto _OpWithProgress = _Continuation_func_transformer<_InternalReturnType, _FuncOutputType>::_Perform(_Func)(_PParam->_Ancestor->_GetResult());            typedef details::_GetProgressType

Page 69: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

<decltype(_OpWithProgress)>::_Value _ProgressType;             details::_Task_impl_base::_AsyncInit<_NormalizedTaskType,_TaskType>(                _PParam->_Continuation,                 ref new details::_IAsyncActionWithProgressToAsyncOperationConverter<_ProgressType>(_OpWithProgress));        };         // return _StubFunc;        return new ::Concurrency::preview::details::_Workaround_Function<::Concurrency::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType> *, void, decltype(_StubFunc)>(_StubFunc);    } #endif     template<typename _InternalReturnType, typename _TaskType, typename _Function>    // std::function<void(::Concurrency::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType> *)>     static ::Concurrency::preview::details::_Workaround_Invoker<::Concurrency::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType> *, void> *    _ContinuationStub(const _Function& _Func, /* takes task */ std::true_type, /* returns IAsync */ details::_TypeSelectorNoAsync)    {        //        // Overload 1-0: task<_InternalReturnType> -> _TaskType         //        // This is an exception handling type of continuation which takes the task rather than the task's result.        //        auto _StubFunc = [=](::Concurrency::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType> *_PParam){            typedef task<_InternalReturnType> _FuncInputType;            task<_InternalReturnType> _ResultTask;            _ResultTask._SetImpl(_PParam->_Ancestor);            _PParam->_Continuation->_FinalizeAndRunContinuations(_Continuation_func_transformer<_FuncInputType, _TaskType>::_Perform(_Func)(_ResultTask));        };         // return _StubFunc;        return new ::Concurrency::preview::details::_Workaround_Function<::Concurrency::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType> *, void, decltype(_StubFunc)>(_StubFunc);    }     template<typename _InternalReturnType, typename _TaskType, typename _Function>    // std::function<void(::Concurrency::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType> *)>     static ::Concurrency::preview::details::_Workaround_Invoker<::Concurrency

Page 70: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType> *, void> *    _ContinuationStub(const _Function& _Func, /* takes task */ std::true_type, /* returns IAsync */ details::_TypeSelectorAsyncOperationOrTask)    {        //        // Overload 1-1: task<_InternalReturnType> -> IAsyncOperation<_TaskType>^         //                                            or        //                                            task<_TaskType>        //        // This is an exception handling type of continuation which takes the task rather than        // the task's result.  It also returns an async operation or a task which will be unwrapped        // for continuation        //        auto _StubFunc = [=](::Concurrency::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType> *_PParam){            typedef details::_NormalizeVoidToUnitType<_TaskType>::_Type _NormalizedTaskType;             // The continuation takes a parameter of type task<_Input>, which is the same as the ancestor task.            task<_InternalReturnType> _ResultTask;            _ResultTask._SetImpl(_PParam->_Ancestor);            details::_Task_impl_base::_AsyncInit<_NormalizedTaskType,_TaskType>(_PParam->_Continuation, _Func(_ResultTask));        };         // return _StubFunc;        return new ::Concurrency::preview::details::_Workaround_Function<::Concurrency::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType> *, void, decltype(_StubFunc)>(_StubFunc);    } #if defined(__cplusplus_winrt)     template<typename _InternalReturnType, typename _TaskType, typename _Function>    // std::function<void(::Concurrency::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType> *)>     static ::Concurrency::preview::details::_Workaround_Invoker<::Concurrency::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType> *, void> *    _ContinuationStub(const _Function& _Func, /* takes task */ std::true_type, /* returns IAsync */ details::_TypeSelectorAsyncAction)    {        //        // Overload 1-2: task<_InternalReturnType> -> IAsyncAction^        //        // This is an exception handling type of continuation which takes the task rather than        // the task's result.  It also returns an async action which will be 

Page 71: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

unwrapped for continuation        //        auto _StubFunc = [=](::Concurrency::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType> *_PParam){            typedef details::_NormalizeVoidToUnitType<_TaskType>::_Type _NormalizedTaskType;             // The continuation takes a parameter of type task<_Input>, which is the same as the ancestor task.            task<_InternalReturnType> _ResultTask;            _ResultTask._SetImpl(_PParam->_Ancestor);            details::_Task_impl_base::_AsyncInit<_NormalizedTaskType,_TaskType>(_PParam->_Continuation, ref new details::_IAsyncActionToAsyncOperationConverter(_Func(_ResultTask)));        };         // return _StubFunc;        return new ::Concurrency::preview::details::_Workaround_Function<::Concurrency::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType> *, void, decltype(_StubFunc)>(_StubFunc);    }     template<typename _InternalReturnType, typename _TaskType, typename _Function>    // std::function<void(::Concurrency::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType> *)>     static ::Concurrency::preview::details::_Workaround_Invoker<::Concurrency::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType> *, void> *    _ContinuationStub(const _Function& _Func, /* takes task */ std::true_type, /* returns IAsync */ details::_TypeSelectorAsyncOperationWithProgress)     {        //        // Overload 1-3: task<_InternalReturnType> -> IAsyncOperationWithProgress<_TaskType, _ProgressType>^         //        // This is an exception handling type of continuation which takes the task rather than        // the task's result.  It also returns an async operation with progress which will be unwrapped        // for continuation        //        auto _StubFunc = [=](::Concurrency::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType> *_PParam){            // The continuation takes a parameter of type task<_Input>, which is the same as the ancestor task.            task<_InternalReturnType> _ResultTask;            _ResultTask._SetImpl(_PParam->_Ancestor);             auto _OpWithProgress = _Func(_ResultTask);            typedef details::_GetProgressType<decltype(_OpWithProgress)>::_Value _ProgressType;            typedef details::_NormalizeVoidToUnitType<_TaskType>::_Type _Norm

Page 72: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

alizedTaskType;             details::_Task_impl_base::_AsyncInit<_NormalizedTaskType,_TaskType>(_PParam->_Continuation,                    ref new details::_IAsyncOperationWithProgressToAsyncOperationConverter<_TaskType,_ProgressType>(_OpWithProgress));        };         // return _StubFunc;        return new ::Concurrency::preview::details::_Workaround_Function<::Concurrency::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType> *, void, decltype(_StubFunc)>(_StubFunc);    }     template<typename _InternalReturnType, typename _TaskType, typename _Function>    // std::function<void(::Concurrency::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType> *)>     static ::Concurrency::preview::details::_Workaround_Invoker<::Concurrency::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType> *, void> *    _ContinuationStub(const _Function& _Func, /* takes task */ std::true_type, /* returns IAsync */ details::_TypeSelectorAsyncActionWithProgress)     {        //        // Overload 1-4: task<_InternalReturnType> -> IAsyncActionWithProgress<_ProgressType>^         //        // This is an exception handling type of continuation which takes the task rather than        // the task's result.  It also returns an async operation with progress which will be unwrapped        // for continuation        //        auto _StubFunc = [=](::Concurrency::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType> *_PParam){            // The continuation takes a parameter of type task<_Input>, which is the same as the ancestor task.            task<_InternalReturnType> _ResultTask;            _ResultTask._SetImpl(_PParam->_Ancestor);             auto _OpWithProgress = _Func(_ResultTask);             typedef details::_GetProgressType<decltype(_OpWithProgress)>::_Value _ProgressType;            typedef details::_NormalizeVoidToUnitType<_TaskType>::_Type _NormalizedTaskType;             details::_Task_impl_base::_AsyncInit<_NormalizedTaskType,_TaskType>(_PParam->_Continuation,                    ref new details::_IAsyncActionWithProgressToAsyncOperationConverter<_ProgressType>(_OpWithProgress));        };

Page 73: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

        // return _StubFunc;        return new ::Concurrency::preview::details::_Workaround_Function<::Concurrency::preview::details::_TaskContinuationParameter<_InternalReturnType, _TaskType> *, void, decltype(_StubFunc)>(_StubFunc);    } #endif     /// <summary>    ///     Wait on the task to complete. If the task is still in the process of executing, a    ///     call to wait can potentially inline work.    /// </summary>    /// <returns>    ///     A <c>task_status</c> which can be either <c>completed</c> or <c>canceled</c>.    /// </returns>    /**/    task_status wait() const    {        if (_M_Impl == NULL)        {            throw invalid_operation("wait() cannot be called on a default constructed task.");        }         return _M_Impl->_Wait(true);    }     /// <summary>    ///     Return the result of this task. If the task has not yet completed, this will wait on the     ///     task to complete. If the task is still in the process of executing, a call to wait can    ///     potentially inline work.    /// </summary>    /// <returns>    ///     The output of the task.    /// </returns>    /// <remarks>    ///     If the task is canceled, a call to get will throw an <c>task_canceled</c> exception.    /// </remarks>    /**/    _ReturnType get() const    {        if (_M_Impl == NULL)        {            throw invalid_operation("get() cannot be called on a default constructed task.");        }         if (_M_Impl->_Wait(false) == canceled)        {            throw task_canceled();

Page 74: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

        }         return _M_Impl->_GetResult();    }     /// <summary>    ///     Checks whether the task has been canceled    /// </summary>    /// <returns>    ///     If the task is canceled, <c>true</c> is returned, otherwise, <c>false</c>.    /// </returns>    /**/    bool is_canceled() const    {        if (_M_Impl == NULL)        {            throw invalid_operation("is_canceled() cannot be called on a default constructed task.");        }         return _M_Impl->_IsPendingCancel() || _M_Impl->_IsCanceled();    }     /// <summary>    ///     Compare two tasks.    /// </summary>    /// <returns>    ///     If the tasks point to the same underlying implementation, <c>true</c> is returned, otherwise, <c>false</c>.    /// </returns>    /**/    bool operator==(const task<_ReturnType>& _Rhs) const    {        return (_M_Impl == _Rhs._M_Impl);    }     /// <summary>    ///     Compare two tasks    /// </summary>    /// <returns>    ///     If the tasks point to the same underlying implementation, <c>false</c> is returned, otherwise, <c>true</c>.    /// </returns>    /**/    bool operator!=(const task<_ReturnType>& _Rhs) const    {        return !operator==(_Rhs);    } }; namespace details{    // Utility method for dealing with void functions

Page 75: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

    inline std::function<_Unit_type(void)> _MakeVoidToUnitFunc(const std::function<void(void)>& _Func)    {        return [=]() -> _Unit_type { _Func(); return _Unit_type(); };    }     template <typename _Type>    std::function<_Type(_Unit_type)> _MakeUnitToTFunc(const std::function<_Type(void)>& _Func)    {        return [=](_Unit_type) -> _Type { return _Func(); };    }     template <typename _Type>    typename _FixFunction<std::function<_Unit_type(_Type)>>::_FixedFunc _MakeTToUnitFunc(const typename _FixFunction<std::function<void(_Type)>>::_FixedFunc& _Func)    {        return [=](_Type t) -> _Unit_type { _Func(t); return _Unit_type(); };    }     inline std::function<_Unit_type(_Unit_type)> _MakeUnitToUnitFunc(const std::function<void(void)>& _Func)    {        return [=](_Unit_type) -> _Unit_type { _Func(); return _Unit_type(); };    } #if defined(__cplusplus_winrt)    /// <summary>    ///     Base converter class for converting asynchronous interfaces to IAsyncOperation    /// </summary>    /**/    template<typename _AsyncOperationType, typename _CompletionHandlerType, typename _Result>    ref struct _AsyncInfoImpl abstract : Windows::Foundation::IAsyncOperation<_Result>    {        _AsyncOperationType _M_asyncInfo;        Windows::Foundation::AsyncOperationCompletedHandler<_Result>^ _M_CompletedHandler;         _AsyncInfoImpl( _AsyncOperationType _asyncInfo ) : _M_asyncInfo(_asyncInfo) {}         virtual void Cancel() { _M_asyncInfo->Cancel(); }        virtual void Close() { _M_asyncInfo->Close(); }        virtual void Start() { _M_asyncInfo->Start(); }         property Windows::Foundation::HResult ErrorCode        {            Windows::Foundation::HResult get()            {                return _M_asyncInfo->ErrorCode;

Page 76: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

            }        }         property UINT Id        {            UINT get()            {                return _M_asyncInfo->Id;            }        }         property Windows::Foundation::AsyncStatus Status        {            Windows::Foundation::AsyncStatus get()            {                return _M_asyncInfo->Status;            }        }         virtual _Result GetResults() { throw std::runtime_error("derived class must implement"); }         property Windows::Foundation::AsyncOperationCompletedHandler<_Result>^ Completed        {            Windows::Foundation::AsyncOperationCompletedHandler<_Result>^ get()            {                return _M_CompletedHandler;            }             void set(Windows::Foundation::AsyncOperationCompletedHandler<_Result>^ value)            {                _M_CompletedHandler = value;                _M_asyncInfo->Completed = ref new _CompletionHandlerType([&](_AsyncOperationType) {                    _M_CompletedHandler->Invoke(this);                });            }        }    };     /// <summary>    ///     Class _IAsyncOperationWithProgressToAsyncOperationConverter is used to convert an instance of IAsyncOperationWithProgress<T> into IAsyncOperation<T>    /// </summary>    /**/    template<typename _Result, typename _Progress>    ref struct _IAsyncOperationWithProgressToAsyncOperationConverter :         _AsyncInfoImpl<Windows::Foundation::IAsyncOperationWithProgress<_Result,_Progress>^,                      Windows::Foundation::AsyncOperationWithProgressCompletedHandler<_Result,_Progress>,

Page 77: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

                      _Result>    {        _IAsyncOperationWithProgressToAsyncOperationConverter(Windows::Foundation::IAsyncOperationWithProgress<_Result,_Progress>^ _Operation) :             _AsyncInfoImpl<Windows::Foundation::IAsyncOperationWithProgress<_Result,_Progress>^,                          Windows::Foundation::AsyncOperationWithProgressCompletedHandler<_Result,_Progress>,                          _Result>(_Operation) {}         virtual _Result GetResults() { return _M_asyncInfo->GetResults(); }    };     /// <summary>    ///     Class _IAsyncActionToAsyncOperationConverter is used to convert an instance of IAsyncAction into IAsyncOperation<_Unit_type>    /// </summary>    /**/    ref struct _IAsyncActionToAsyncOperationConverter :         _AsyncInfoImpl<Windows::Foundation::IAsyncAction^,                      Windows::Foundation::AsyncActionCompletedHandler,                      details::_Unit_type>    {        _IAsyncActionToAsyncOperationConverter(Windows::Foundation::IAsyncAction^ _Operation) :            _AsyncInfoImpl<Windows::Foundation::IAsyncAction^,                          Windows::Foundation::AsyncActionCompletedHandler,                          details::_Unit_type>(_Operation) {}         virtual details::_Unit_type GetResults()        {            // Invoke GetResults on the IAsyncAction to allow exceptions to be thrown to higher layers before returning a dummy value.            _M_asyncInfo->GetResults();            return details::_Unit_type();        }    };     /// <summary>    ///     Class _IAsyncActionWithProgressToAsyncOperationConverter is used to convert an instance of IAsyncActionWithProgress into IAsyncOperation<_Unit_type>    /// </summary>    /**/    template<typename _Progress>    ref struct _IAsyncActionWithProgressToAsyncOperationConverter :         _AsyncInfoImpl<Windows::Foundation::IAsyncActionWithProgress<_Progress>^,                      Windows::Foundation::AsyncActionWithProgressCompletedHandler<_Progress>,                      details::_Unit_type>    {        _IAsyncActionWithProgressToAsyncOperationConverter(Windows::Foundation::IAsyncActionWithProgress<_Progress>^ _Action) :             _AsyncInfoImpl<Windows::Foundation::IAsyncActionWithProgress<_Pro

Page 78: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

gress>^,                          Windows::Foundation::AsyncActionWithProgressCompletedHandler<_Progress>,                          details::_Unit_type>(_Action) {}         virtual details::_Unit_type GetResults()        {            // Invoke GetResults on the IAsyncActionWithProgress to allow exceptions to be thrown before returning a dummy value.            _M_asyncInfo->GetResults();            return details::_Unit_type();        }    }; #endif} /// <summary>///     The PPL task class. Explicit specialization for void./// </summary>/**/template<>class task<void>{    // This is the task that will execute the void function    task<::Concurrency::preview::details::_Unit_type> _UnitTask; public:    typedef void _TaskType;     friend class task<void>;    template <typename T> friend class task;    template <typename T> friend class task_completion_event; private:    void _TaskInitNoFunctor(task_completion_event<void>& _Event)    {        _UnitTask._TaskInitNoFunctor(_Event._UnitEvent);    } #if defined(__cplusplus_winrt)    void _TaskInitNoFunctor(Windows::Foundation::IAsyncAction^ _AsyncAction)    {         _UnitTask._TaskInitAsyncOp(ref new details::_IAsyncActionToAsyncOperationConverter(_AsyncAction));    }     template<typename _P>    void _TaskInitNoFunctor(Windows::Foundation::IAsyncActionWithProgress<_P>^ _AsyncActionWithProgress)    {        _UnitTask._TaskInitAsyncOp(ref new details::_IAsyncActionWithProgressToAsyncOperationConverter<_P>(_AsyncActionWithProgress));    }#endif

Page 79: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

    // _TaskInitMaybeFunctor overload for callable objects.    template<typename _Function>    void _TaskInitMaybeFunctor(_Function& _Func, std::true_type)    {        _UnitTask._TaskInitWithFunctor<void, _Function>(_Func);    }     // _TaskInitMaybeFunctor overload for non-callable objects.    template<typename _T>    void _TaskInitMaybeFunctor(_T& _Param, std::false_type)    {        _TaskInitNoFunctor(_Param);    } public:    /// <summary>    ///     The one and only non-default constructor of the task class. See _TaskInitNoFunctor overloads for the    ///     various parameter types the constructor can accept    /// </summary>    /**/    template<typename _Ty>    explicit task(_Ty _Param) : _UnitTask()    {        _UnitTask._CreateImpl();        _TaskInitMaybeFunctor(_Param, details::_IsCallable(_Param,0));    }     /// <summary>    ///     Constructor for a PPL task.    /// </summary>    /// <param name="_Func">    ///     The function for this PPL task to execute.    /// </param>    /// <param name="_Event">    ///     A task_completion_event with which to create this task. The task will be set as completed    ///     when the task_completion_event is set.    /// </param>    /// <remarks>    ///     The default constructor for a task is only present in order to allow tasks to be used within containers.    ///     Users should never create a default constructed task because it is not usable: you cannot run anything,    ///     continue any work, or wait on it.    /// </remarks>    /**/    task() : _UnitTask() {}     /// <summary>    ///     Create an underlying task implementation.    /// </summary>    /// <remarks>    ///     In one instance (the then() API) we need to default construct a t

Page 80: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

ask with an Impl, since    ///     that is the continuation task being returned.    /// </remarks>    /**/    void _CreateImpl()    {        _UnitTask._CreateImpl();    }     /// <summary>    ///     Return the underlying implementation for this task.    /// </summary>    /// <returns>    ///     The underlying implementation for the task.    /// </returns>    /**/    ::Concurrency::preview::details::_Task_ptr<::Concurrency::preview::details::_Unit_type>::_Type _GetImpl() const    {         return _UnitTask._M_Impl;     }     /// <summary>    ///     Set the implementation of the task to be the supplied implementaion.    /// </summary>    /// <remarks>    ///     When a continuation that takes a task<T> is scheduled on a task<T>, this method is    ///     used to generate a task with the same implementataion as the ancestor task, effectively    ///     incrementing the reference on the shared_ptr in the ancestor task.    /// </remarks>    /**/    void _SetImpl(::Concurrency::preview::details::_Task_ptr<::Concurrency::preview::details::_Unit_type>::_Type _Impl)    {        _UnitTask._SetImpl(_Impl);    }     /// <summary>    ///     Determine whether the task is a task that wraps an async object or is descended from the continuation chain of such a task.    /// </summary>    bool _IsAsync() const    {        return _UnitTask._IsAsync();    }     /// <summary>    ///     Sets a property determining whether the task is a task that wraps an async object or is descended from the continuation chain of such a task.    /// </summary>    void _SetAsync(bool _Async = true)

Page 81: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

    {        _UnitTask._SetAsync(_Async);    }     /// <summary>    ///     Add a continuation task to this task. The continuation will execute when this task completes, and its function    ///     will be presented the output of this task's function.    /// </summary>    /// <typeparam name="_Function">    ///     The type of the function object that will be invoked by this task.    /// </typeparam>    /// <param name="_Func">    ///     The continuation function to execute when this task completes. This continuation function must take as input the     ///     output of this parent task that it is continuing from.    /// </param>    /// <returns>    ///     A new task which will be scheduled for execution when this current task completes. The new task's type will    ///     be the output of the function <c>_Func</c>    /// </returns>    /**/    template<typename _Function>    auto then(const _Function& _Func) const -> typename ::Concurrency::preview::details::_ContinuationTypeTraits<_Function, void>::_TaskOfType    {        return _UnitTask._ThenImpl<void, _Function>(_Func, task_continuation_context::use_default());    } #if defined(__cplusplus_winrt)    /// <summary>    ///     Add a continuation task to this task. The continuation will execute when this task completes, and its function    ///     will be presented the output of this task's function.    /// </summary>    /// <typeparam name="_Function">    ///     The type of the function object that will be invoked by this task.    /// </typeparam>    /// <param name="_Func">    ///     The continuation function to execute when this task completes. This continuation function must take as input the     ///     output of this parent task that it is continuing from.    /// </param>    /// <param name="_ContinuationContext">    ///     A variable that specifies where the continuation should execute.    /// </param>    /// <returns>    ///     A new task which will be scheduled for execution when this current task completes. The new task's type will    ///     be the output of the function <c>_Func</c>    /// </returns>

Page 82: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

    /**/    template<typename _Function>    auto then(const _Function& _Func, task_continuation_context _ContinuationContext) const -> typename ::Concurrency::preview::details::_ContinuationTypeTraits<_Function, void>::_TaskOfType    {        return _UnitTask._ThenImpl<void, _Function>(_Func, _ContinuationContext);    }#endif     /// <summary>    ///     An internal version of then that takes additional flags.    /// </summary>    /**/    template<typename _Function>    auto _Then(const _Function& _Func,        bool _ObservesExceptions, bool _Aggregating) const -> typename ::Concurrency::preview::details::_ContinuationTypeTraits<_Function, void>::_TaskOfType    {        return _UnitTask._ThenImpl<void, _Function>(_Func, task_continuation_context::use_default(), _ObservesExceptions, _Aggregating);    }     /// <summary>    ///     Wait on the task to complete. If the task is still in the process of executing, a    ///     call to wait can potentially inline work.    /// </summary>    /// <returns>    ///     A <c>task_status</c> which can be either <c>completed</c> or <c>canceled</c>.    /// </returns>    /**/    task_status wait() const    {        return _UnitTask.wait();    }     /// <summary>    ///     Checks whether the task has been canceled.    /// </summary>    /// <returns>    ///     If the task is canceled, <c>true</c> is returned, otherwise, <c>false</c>.    /// </returns>    /**/    bool is_canceled() const    {        return _UnitTask.is_canceled();    }     /// <summary>    ///     Return the result of this task. If the task has not yet completed

Page 83: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

, this will wait on the     ///     task to complete. If the task is still in the process of executing, a call to wait can    ///     potentially inline work.    /// </summary>    /// <remarks>    ///     If the task is canceled, a call to get will throw an <c>invalid_operation</c> exception.    /// </remarks>    /**/    void get() const    {        _UnitTask.get();    }     /// <summary>    ///     Compare two tasks.    /// </summary>    /// <returns>    ///     If the tasks point to the same underlying implementation, <c>true</c> is returned, otherwise, <c>false</c>.    /// </returns>    /**/    bool operator==(const task<void>& _Rhs) const    {        return (_UnitTask == _Rhs._UnitTask);    }     /// <summary>    ///     Compare two tasks.    /// </summary>    /// <returns>    ///     If the tasks point to the same underlying implementation, <c>false</c> is returned, otherwise, <c>true</c>.    /// </returns>    /**/    bool operator!=(const task<void>& _Rhs) const    {        return !operator==(_Rhs);    }}; #if defined(__cplusplus_winrt) namespace details{    template<typename _ProgressType>    class _ProgressDispatcherBase    {    public:         virtual ~_ProgressDispatcherBase()        {        }

Page 84: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

        virtual void _Report(const _ProgressType& _Val) = 0;    };     template<typename _ProgressType, typename _ClassPtrType>    class _ProgressDispatcher : public _ProgressDispatcherBase<_ProgressType>    {        task_continuation_context _M_Ct;        task<void> _Task;    public:         virtual ~_ProgressDispatcher()        {        }         _ProgressDispatcher(_ClassPtrType _Ptr) : _M_ptr(_Ptr), _M_Ct(task_continuation_context::use_current()), _Task([](){})        {        }                virtual void _Report(const _ProgressType& _Val)        {/*            _Task.then([=]() {                _M_ptr->_FireProgress(_Val);            }, _M_Ct);*/            _M_Ct._CallInContext( [=](){                _M_ptr->_FireProgress(_Val);            });        }        private:         _ClassPtrType _M_ptr;    };} /// <summary>///     The progress reporter class represents a sink for reporting progress notifications of a specific type.  Each progress_reporter object is bound///     to a particular asynchronous action or operation./// </summary>/// <typeparam name="_ProgressType">///     The payload type of each progress notification reported through the progress reporter./// </typeparam>/**/template<typename _ProgressType>class progress_reporter{    typedef std::shared_ptr<details::_ProgressDispatcherBase<_ProgressType>> _PtrType; public:

Page 85: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

    template<typename _ClassPtrType>    static progress_reporter _CreateReporter(_ClassPtrType _Ptr)    {        progress_reporter _Reporter;        details::_ProgressDispatcherBase<_ProgressType> *_PDispatcher = new details::_ProgressDispatcher<_ProgressType, _ClassPtrType>(_Ptr);        _Reporter._M_dispatcher = _PtrType(_PDispatcher);        return _Reporter;    }     /// <summary>    ///     Sends a progress report to the asynchronous action or operation to which this progress reporter is bound.    /// </summary>    /// <param name="_Val")    ///     The ppayload to report through a progress notification.    /// </param>    /**/    void report(const _ProgressType& _Val) const    {        _M_dispatcher->_Report(_Val);    } private:     _PtrType _M_dispatcher;}; namespace details{    //    // maps internal definitions for AsyncStatus and defines states that are not client visible    //    enum _AsyncStatusInternal     {        // client visible states (must match AsyncStatus exactly)        _AsyncCreated = 0, // ::Windows::Foundation::AsyncStatus::Created,        _AsyncStarted = 1, // ::Windows::Foundation::AsyncStatus::Started,        _AsyncCompleted = 2, // ::Windows::Foundation::AsyncStatus::Completed,        _AsyncCancelled = 3, // ::Windows::Foundation::AsyncStatus::Canceled,        _AsyncError = 4, // ::Windows::Foundation::AsyncStatus::Error,         // non-client visible internal states        _AsyncCancelPending,        _AsyncClosed,        _AsyncUndefined    };     //    // designates whether the "GetResults" method returns a single result (after complete fires) or multiple results    // (which are progressively consumable between Start state and before Close is called)

Page 86: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

    //    enum _AsyncResultType    {        SingleResult    = 0x0001,        MultipleResults = 0x0002    };     // ***************************************************************************    // Template type traits and helpers for async production APIs:    //     // non-void arg:    template<typename _Class, typename _ReturnType, typename _Arg1>    _Arg1 _Arg1ClassHelperThunk(_ReturnType (_Class::*)(_Arg1) const);     // Needed to work around TFS#287753    template<typename _Class, typename _ReturnType, typename _Arg1>    _Arg1 _Arg1ClassHelperThunk(_ReturnType (__cdecl _Class::*)(_Arg1) const);     template<typename _Class, typename _ReturnType, typename _Arg1>    _ReturnType _ReturnTypeClassHelperThunk(_ReturnType (_Class::*)(_Arg1) const);     // Needed to work around TFS#287753    template<typename _Class, typename _ReturnType, typename _Arg1>    _ReturnType _ReturnTypeClassHelperThunk(_ReturnType (__cdecl _Class::*)(_Arg1) const);     // void arg:    template<typename _Class, typename _ReturnType>    _ReturnType _ReturnTypeClassHelperThunk(_ReturnType (_Class::*)() const);     // Needed to work around TFS#287753    template<typename _Class, typename _ReturnType>    _ReturnType _ReturnTypeClassHelperThunk(_ReturnType (__cdecl _Class::*)() const);     template<typename _Class, typename _ReturnType>    void _Arg1ClassHelperThunk(_ReturnType (_Class::*)() const);     // Needed to work around TFS#287753    template<typename _Class, typename _ReturnType>    void _Arg1ClassHelperThunk(_ReturnType (__cdecl _Class::*)() const);     // --- Function pointer ---    template<typename _ReturnType, typename _Arg1>    _Arg1 _Arg1PFNHelperThunk(_ReturnType(__cdecl *)(_Arg1));     template<typename _ReturnType, typename _Arg1>    _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__cdecl *)(_Arg1));     template<typename _ReturnType>

Page 87: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

    void _Arg1PFNHelperThunk(_ReturnType(__cdecl *)());     template<typename _ReturnType>    _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__cdecl *)());     template<typename _ReturnType, typename _Arg1>    _Arg1 _Arg1PFNHelperThunk(_ReturnType(__stdcall *)(_Arg1));     template<typename _ReturnType, typename _Arg1>    _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__stdcall *)(_Arg1));     template<typename _ReturnType>    void _Arg1PFNHelperThunk(_ReturnType(__stdcall *)());     template<typename _ReturnType>    _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__stdcall *)());     template<typename _ReturnType, typename _Arg1>    _Arg1 _Arg1PFNHelperThunk(_ReturnType(__fastcall *)(_Arg1));     template<typename _ReturnType, typename _Arg1>    _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__fastcall *)(_Arg1));     template<typename _ReturnType>    void _Arg1PFNHelperThunk(_ReturnType(__fastcall *)());     template<typename _ReturnType>    _ReturnType _ReturnTypePFNHelperThunk(_ReturnType(__fastcall *)());     //    // ASYNC TODO: See if this can be merged with _FunctionTypeTraits.    //     template<typename _T>    struct _FunctorTypeTraits    {        typedef decltype(_ReturnTypeClassHelperThunk(&(_T::operator()))) _ReturnType;        typedef decltype(_Arg1ClassHelperThunk(&(_T::operator()))) _Argument1Type;    };     template<typename _T>    struct _FunctorTypeTraits<_T *>    {        typedef decltype(_ReturnTypePFNHelperThunk(std::declval<_T*>())) _ReturnType;        typedef decltype(_Arg1PFNHelperThunk(std::declval<_T*>())) _Argument1Type;    };     template<typename _T>    struct _ProgressTypeTraits    {        static const bool _TakesProgress = false;

Page 88: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

        typedef void _ProgressType;    };     template<typename _T>    struct _ProgressTypeTraits<progress_reporter<_T>>    {        static const bool _TakesProgress = true;        typedef typename _T _ProgressType;    };     ref class _Zip    {    };     // ***************************************************************************    // Async Operation Task Generators    //     //    // Functor result needs to be wrapped in a task:    //    template<typename _AsyncSelector, typename _ReturnType>    struct _TaskGenerator    {        template<typename _Function>        static ::Concurrency::preview::task<_ReturnType> _GenerateTask(const _Function& _Func)        {            return task<_ReturnType>(_Func());        }         template<typename _Function, typename _ProgressObject>        static ::Concurrency::preview::task<_ReturnType> _GenerateProgressAdaptedTask(const _Function& _Func, const _ProgressObject& _Progress)        {            return task<_ReturnType>(_Func(_Progress));        }    };#if 0    template<typename _AsyncSelector>    struct _TaskGenerator<_AsyncSelector, void>    {        template<typename _Function>        static ::Concurrency::preview::task<void> _GenerateTask(const _Function& _Func)        {            return task<void>(_Func());        }         template<typename _Function, typename _ProgressObject>        static ::Concurrency::preview::task<void> _GenerateProgressAdaptedTask(const _Function& _Func, const _ProgressObject& _Progress)        {            return task<void>(_Func(_Progress));

Page 89: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

        }    };#endif    //    // Functor needs to be wrapped in a task:    //    template<typename _ReturnType>    struct _TaskGenerator<_TypeSelectorNoAsync, _ReturnType>    {        template<typename _Function>        static ::Concurrency::preview::task<_ReturnType> _GenerateTask(const _Function& _Func)        {            return task<_ReturnType>(_Func);        }         template<typename _Function, typename _ProgressObject>        static ::Concurrency::preview::task<_ReturnType> _GenerateProgressAdaptedTask(const _Function& _Func, _ProgressObject _Progress)        {            return task<_ReturnType>( [=]() -> _ReturnType {                return _Func(_Progress);            });        }    };     template<>    struct _TaskGenerator<_TypeSelectorNoAsync, void>    {        template<typename _Function>        static ::Concurrency::preview::task<void> _GenerateTask(const _Function& _Func)        {            return task<void>(_Func);        }         template<typename _Function, typename _ProgressObject>        static ::Concurrency::preview::task<void> _GenerateProgressAdaptedTask(const _Function& _Func, _ProgressObject _Progress)        {            return task<void>( [=]() {                _Func(_Progress);            });        }    };     //    // Functor returns a task:    //    template<typename _ReturnType>    struct _TaskGenerator<_TypeSelectorAsyncTask, _ReturnType>    {        template<typename _Function>        static ::Concurrency::preview::task<_ReturnType> _GenerateTask(const _Function& _Func)

Page 90: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

        {            return _Func();        }         template<typename _Function, typename _ProgressObject>        static ::Concurrency::preview::task<_ReturnType> _GenerateProgressAdaptedTask(const _Function& _Func, const _ProgressObject& _Progress)        {            return _Func(_Progress);        }    };     // ***************************************************************************    // Async Operation Attributes Classes    //    // These classes are passed through the hierarchy of async base classes in order to hold multiple attributes of a given async construct in    // a single container.  An attribute class must define:    //    // Mandatory:    // -------------------------    //    // _AsyncBaseType           : The WinRT interface which is being implemented.    // _CompletionDelegateType  : The WinRT completion delegate type for the interface.    // _ProgressDelegateType    : If _TakesProgress is true, the WinRT progress delegate type for the interface.  If it is false, an empty WinRT type.    // _ReturnType              : The return type of the async construct (void for actions / non-void for operations)    //    // _TakesProgress           : An indication as to whether or not     //    // _Task_Generator_Function : A function adapting the user's function into what's necessary to produce the appropriate task    //     // Optional:    // -------------------------    //      template<typename _Function, typename _ProgressType, typename _ReturnType, typename _TaskTraits, bool _TakesProgress>    struct _AsyncAttributes    {    };     template<typename _Function, typename _ProgressType, typename _ReturnType, typename _TaskTraits>    struct _AsyncAttributes<_Function, _ProgressType, _ReturnType, _TaskTraits, true>    {        typedef typename ::Windows::Foundation::IAsyncOperationWithProgress<_ReturnType, _ProgressType> _AsyncBaseType;        typedef typename ::Windows::Foundation::AsyncOperationProgressHandler

Page 91: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

<_ReturnType, _ProgressType> _ProgressDelegateType;        typedef typename ::Windows::Foundation::AsyncOperationWithProgressCompletedHandler<_ReturnType, _ProgressType> _CompletionDelegateType;        typedef typename _ReturnType _ReturnType;        typedef typename _ProgressType _ProgressType;        typedef typename _TaskGenerator<typename _TaskTraits::_AsyncKind, _ReturnType> _TaskGenerator;         static const bool _TakesProgress = true;         template<typename _Function, typename _ClassPtr>        static ::Concurrency::preview::task<_ReturnType> _Generate_Task(const _Function& _Func, _ClassPtr _Ptr)        {            return _TaskGenerator::_GenerateProgressAdaptedTask(_Func, progress_reporter<_ProgressType>::_CreateReporter(_Ptr));        }    };     template<typename _Function, typename _ProgressType, typename _ReturnType, typename _TaskTraits>    struct _AsyncAttributes<_Function, _ProgressType, _ReturnType, _TaskTraits, false>    {        typedef typename ::Windows::Foundation::IAsyncOperation<_ReturnType> _AsyncBaseType;        typedef _Zip _ProgressDelegateType;        typedef typename ::Windows::Foundation::AsyncOperationCompletedHandler<_ReturnType> _CompletionDelegateType;        typedef typename _ReturnType _ReturnType;        typedef typename _TaskGenerator<typename _TaskTraits::_AsyncKind, _ReturnType> _TaskGenerator;         static const bool _TakesProgress = false;         template<typename _Function, typename _ClassPtr>        static ::Concurrency::preview::task<_ReturnType> _Generate_Task(const _Function& _Func, _ClassPtr _Ptr)        {            return _TaskGenerator::_GenerateTask(_Func);        }    };     template<typename _Function, typename _ProgressType, typename _TaskTraits>    struct _AsyncAttributes<_Function, _ProgressType, void, _TaskTraits, true>    {        typedef typename ::Windows::Foundation::IAsyncActionWithProgress<_ProgressType> _AsyncBaseType;        typedef typename ::Windows::Foundation::AsyncActionProgressHandler<_ProgressType> _ProgressDelegateType;        typedef typename ::Windows::Foundation::AsyncActionWithProgressCompletedHandler<_ProgressType> _CompletionDelegateType;        typedef void _ReturnType;

Page 92: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

        typedef typename _ProgressType _ProgressType;        typedef typename _TaskGenerator<typename _TaskTraits::_AsyncKind, _ReturnType> _TaskGenerator;         static const bool _TakesProgress = true;         template<typename _Function, typename _ClassPtr>        static ::Concurrency::preview::task<_ReturnType> _Generate_Task(const _Function& _Func, _ClassPtr _Ptr)        {            return _TaskGenerator::_GenerateProgressAdaptedTask(_Func, progress_reporter<_ProgressType>::_CreateReporter(_Ptr));        }    };     template<typename _Function, typename _ProgressType, typename _TaskTraits>    struct _AsyncAttributes<_Function, _ProgressType, void, _TaskTraits, false>    {        typedef typename ::Windows::Foundation::IAsyncAction _AsyncBaseType;        typedef _Zip _ProgressDelegateType;        typedef typename ::Windows::Foundation::AsyncActionCompletedHandler _CompletionDelegateType;        typedef void _ReturnType;        typedef typename _TaskGenerator<typename _TaskTraits::_AsyncKind, _ReturnType> _TaskGenerator;         static const bool _TakesProgress = false;         template<typename _Function, typename _ClassPtr>        static ::Concurrency::preview::task<_ReturnType> _Generate_Task(const _Function& _Func, _ClassPtr _Ptr)        {            return _TaskGenerator::_GenerateTask(_Func);        }    };     template<typename _Function>    struct _AsyncLambdaTypeTraits    {        typedef typename _FunctorTypeTraits<_Function>::_ReturnType _ReturnType;        typedef typename _FunctorTypeTraits<_Function>::_Argument1Type _Argument1Type;        typedef typename _ProgressTypeTraits<_Argument1Type>::_ProgressType _ProgressType;        static const bool _TakesProgress = _ProgressTypeTraits<_Argument1Type>::_TakesProgress;        typedef typename _TaskTypeTraits<_ReturnType> _TaskTraits;        typedef typename _AsyncAttributes<_Function, _ProgressType, typename _TaskTraits::_TaskRetType, _TaskTraits, _TakesProgress> _AsyncAttributes;    };     // **********************************************************************

Page 93: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

*****    // AsyncInfo (and completion) Layer:    //     //    // Internal base class implementation for async operations (based on internal Windows representation for ABI level async operations)    //    template < typename _Attributes, _AsyncResultType resultType = SingleResult >    ref class _AsyncInfoBase abstract : _Attributes::_AsyncBaseType    {    public:         _AsyncInfoBase() :             _M_currentStatus(_AsyncStatusInternal::_AsyncCreated),             _M_id(1),             _M_errorCode(S_OK),            _M_completeDelegate(ref new _Attributes::_CompletionDelegateType([](_Attributes::_AsyncBaseType^){}))        {             }         property unsigned int Id        {            unsigned int get()            {                _CheckValidStateForAsyncInfoCall();                 return _M_id;            }             void set(unsigned int id)            {                _CheckValidStateForAsyncInfoCall();                 if (id == 0)                {                    throw ref new Platform::COMException(E_INVALIDARG);                }                 _M_id = id;            }        }         property ::Windows::Foundation::AsyncStatus Status        {            ::Windows::Foundation::AsyncStatus get()            {                _CheckValidStateForAsyncInfoCall();                 _AsyncStatusInternal _Current = _AsyncUndefined;                _CurrentStatus(&_Current);                 //

Page 94: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

                // Map our internal cancel pending to started.  It's not successfully been canceled yet nor has it finished yet.  It's                // waiting on resolution one way or another.                //                switch(_Current)                {                    case _AsyncCancelPending:                        _Current = _AsyncStarted;                        break;                    default:                        break;                }                 return static_cast<::Windows::Foundation::AsyncStatus>(_Current);            }        }         property ::Windows::Foundation::HResult ErrorCode        {            ::Windows::Foundation::HResult get()            {                _CheckValidStateForAsyncInfoCall();                 ::Windows::Foundation::HResult _Hr;                _Hr.Value = _M_errorCode;                return _Hr;            }        }         property typename _Attributes::_CompletionDelegateType^ Completed        {            typename _Attributes::_CompletionDelegateType^ get()            {                _CheckValidStateForDelegateCall();                return _M_completeDelegate;            }             void set(typename _Attributes::_CompletionDelegateType^ _CompleteHandler)            {                _CheckValidStateForDelegateCall();                _M_completeDelegate = _CompleteHandler;                _M_completeDelegateContext = ::Concurrency::preview::details::_ContextCallback::_CaptureCurrent();            }        }         // ASYNC TODO: When the compiler can deal with virtual/overriden properties, this should just become a virtual        // property Progress with overrides in the derived classes.        //        // ASYNC TODO: The below two should be abstract / pure virtual         property typename _Attributes::_ProgressDelegateType^ Progress

Page 95: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

        {            typename typename _Attributes::_ProgressDelegateType^ get()            {                return _GetOnProgress();            }             void set(typename _Attributes::_ProgressDelegateType^ _ProgressHandler)            {                _PutOnProgress(_ProgressHandler);            }        }         virtual typename _Attributes::_ProgressDelegateType^ _GetOnProgress()        {            throw ref new Platform::COMException(E_UNEXPECTED);        }         virtual void _PutOnProgress(typename _Attributes::_ProgressDelegateType^ _ProgressHandler)        {            throw ref new Platform::COMException(E_UNEXPECTED);        }         virtual typename _Attributes::_ReturnType GetResults()        {            throw ref new Platform::COMException(E_UNEXPECTED);        }         void Start()        {            if (_TransitionToState(_AsyncStarted))            {                _OnStart();            }            else            {                throw ref new Platform::COMException(E_ILLEGAL_STATE_CHANGE);            }        }         void Cancel()        {            if (_TransitionToState(_AsyncCancelPending))            {                _OnCancel();            }        }         void Close()        {            if (_TransitionToState(_AsyncClosed))            {                _OnClose();            }

Page 96: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

            else            {                _AsyncStatusInternal current = _AsyncUndefined;                _CurrentStatus(&current);                if (current != _AsyncClosed) // Closed => Closed transition is just ignored                {                    throw ref new Platform::COMException(E_ILLEGAL_STATE_CHANGE);                }            }        }         void _FireCompletion()        {            _TryTransitionToCompleted();            if (_M_completeDelegate != nullptr)            {                //                // TODO: Sort out why I cannot safely marshal a delegate with a proxy across apartments.  The delegate has fields which are used in () and                //       are not part of the marshaled object.  Using the delegate after marshaling crashes.  This is TFS #265326.                //                typename _Attributes::_CompletionDelegateType^ _Completion = _M_completeDelegate; //                ::Concurrency::preview::details::_InContext<typename _Attributes::_CompletionDelegateType^>::_Get(_M_completeDelegate, _M_completeDelegateContext);                _Completion((_Attributes::_AsyncBaseType^)this);                 _M_completeDelegate = nullptr;            }        }     protected:         inline void _CurrentStatus(_AsyncStatusInternal *status)         {            InterlockedCompareExchange(reinterpret_cast<LONG*>(status), _M_currentStatus, static_cast<LONG>(*status));        }         inline void _InternalErrorCode(HRESULT *error)         {            InterlockedCompareExchange(reinterpret_cast<LONG*>(error), _M_errorCode, static_cast<LONG>(*error));        }         bool _TryTransitionToCompleted(void)        {            return _TransitionToState(_AsyncStatusInternal::_AsyncCompleted);        }

Page 97: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

        bool _TryTransitionToCancelled(void)        {            return _TransitionToState(_AsyncStatusInternal::_AsyncCancelled);        }         bool _TryTransitionToError(const HRESULT error)        {            _InterlockedCompareExchange(reinterpret_cast<volatile LONG*>(&_M_errorCode), error, S_OK);            return _TransitionToState(_AsyncStatusInternal::_AsyncError);        }         // This method checks to see if the delegate properties can be         // modified in the current state and generates the appropriate         // errro hr in the case of violation.        inline void _CheckValidStateForDelegateCall()        {            _AsyncStatusInternal _Current = _AsyncUndefined;            _CurrentStatus(&_Current);            if (_Current != _AsyncCreated)            {                throw ref new Platform::COMException(E_ILLEGAL_METHOD_CALL);            }        }         // This method checks to see if results can be collected in the         // current state and generates the appropriate error hr in         // the case of a violation.        inline void _CheckValidStateForResultsCall()        {            _AsyncStatusInternal _Current = _AsyncUndefined;            _CurrentStatus(&_Current);             if (_Current == _AsyncError)            {                throw ref new Platform::COMException(_M_errorCode);            }#pragma warning(push)#pragma warning(disable: 4127) // Conditional expression is constant            // single result illegal before transition to Completed or Cancelled state            if (resultType == SingleResult)#pragma warning(pop)            {                if (_Current != _AsyncCancelled &&                     _Current != _AsyncCompleted)                {                    throw ref new Platform::COMException(E_ILLEGAL_METHOD_CALL);                }            }            // multiple results can be called after Start has been called and before/after Completed            else if (_Current != _AsyncStarted &&                      _Current != _AsyncCancelPending &&

Page 98: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

                     _Current != _AsyncCancelled &&                      _Current != _AsyncCompleted)            {                throw ref new Platform::COMException(E_ILLEGAL_METHOD_CALL);            }        }                // This method can be called by derived classes periodically to determine         // whether the asynchronous operation should continue processing or should         // be halted.        inline bool _ContinueAsyncOperation()        {            _AsyncStatusInternal _Current = _AsyncUndefined;            _CurrentStatus(&_Current);            return (_Current == _AsyncStarted);        }         // These two methods are used to allow the async worker implementation do work on        // state transitions. No real "work" should be done in these methods. In other words        // they should not block for a long time on UI timescales.        virtual void _OnStart(void) = 0;        virtual void _OnClose(void) = 0;        virtual void _OnCancel(void) = 0;     private:         // This method is used to check if calls to the AsyncInfo properties        // (id, status, errorcode) are legal in the current state. It also         // generates the appropriate error hr to return in the case of an         // illegal call.        inline void _CheckValidStateForAsyncInfoCall()        {            _AsyncStatusInternal _Current = _AsyncUndefined;            _CurrentStatus(&_Current);            if (_Current == _AsyncClosed)            {                throw ref new Platform::COMException(E_ILLEGAL_METHOD_CALL);            }        }         inline bool _TransitionToState(const _AsyncStatusInternal _NewState)        {            _AsyncStatusInternal _Current = _AsyncUndefined;            _CurrentStatus(&_Current);             // This enforces the valid state transitions of the asynchronous worker object             // state machine.            switch(_NewState)            {            case _AsyncStatusInternal::_AsyncStarted:

Page 99: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

                if (_Current != _AsyncCreated)                 {                    return false;                }                break;            case _AsyncStatusInternal::_AsyncCompleted:                if (_Current != _AsyncStarted && _Current != _AsyncCancelPending)                {                    return false;                }                break;            case _AsyncStatusInternal::_AsyncCancelPending:                if (_Current != _AsyncStarted)                {                    return false;                }                break;            case _AsyncStatusInternal::_AsyncCancelled:                if (_Current != _AsyncStarted && _Current != _AsyncCancelPending)                {                    return false;                }                break;            case _AsyncStatusInternal::_AsyncError:                if (_Current != _AsyncStarted && _Current != _AsyncCancelPending)                {                    return false;                }                break;            case _AsyncStatusInternal::_AsyncClosed:                if (!_IsTerminalState(_Current))                 {                    return false;                }                break;            default:                return false;                break;            }             // attempt the transition to the new state            // Note: if currentStatus_ == _Current, then there was no intervening write             // by the async work object and the swap succeeded.             _AsyncStatusInternal _RetState = static_cast<_AsyncStatusInternal>(                    _InterlockedCompareExchange(reinterpret_cast<volatile LONG*>(&_M_currentStatus),                                                 _NewState,                                                 static_cast<LONG>(_Current)));

Page 100: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

            // ICE returns the former state, if the returned state and the             // state we captured at the beginning of this method are the same,             // the swap succeeded.            return (_RetState == _Current);        }         inline bool _IsTerminalState()        {            _AsyncStatusInternal _Current = _AsyncUndefined;            _CurrentStatus(&_Current);            return _IsTerminalState(_Current);        }         inline bool _IsTerminalState(_AsyncStatusInternal status)        {            return (status == _AsyncError ||                     status == _AsyncCancelled ||                     status == _AsyncCompleted ||                     status == _AsyncClosed);        }     private:         ::Concurrency::preview::details::_ContextCallback _M_completeDelegateContext;        typename _Attributes::_CompletionDelegateType^ _M_completeDelegate;         _AsyncStatusInternal volatile _M_currentStatus;        HRESULT volatile _M_errorCode;        unsigned int _M_id;    };     // ***************************************************************************    // Progress Layer (optional):    //     template< typename _Attributes, bool _HasProgress, _AsyncResultType _ResultType = SingleResult >    ref class _AsyncProgressBase abstract : _AsyncInfoBase<_Attributes, _ResultType>    {    };     template< typename _Attributes, _AsyncResultType _ResultType>    ref class _AsyncProgressBase<_Attributes, true, _ResultType> abstract : _AsyncInfoBase<_Attributes, _ResultType>    {    public:         // ASYNC TODO: When the compiler can deal with virtual/overriden properties, this should just become an override        // of the base class Progress property!

Page 101: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

        virtual typename _Attributes::_ProgressDelegateType^ _GetOnProgress() override        {            _CheckValidStateForDelegateCall();            return _M_progressDelegate;        }         virtual void _PutOnProgress(typename _Attributes::_ProgressDelegateType^ _ProgressHandler) override        {            _CheckValidStateForDelegateCall();            _M_progressDelegate = _ProgressHandler;            _M_progressDelegateContext = ::Concurrency::preview::details::_ContextCallback::_CaptureCurrent();        }     public:         void _FireProgress(const typename _Attributes::_ProgressType& _ProgressValue)        {            if (_M_progressDelegate != nullptr)            {                //                // TODO: Sort out why I cannot safely marshal a delegate with a proxy across apartments.  The delegate has fields which are used in () and                //       are not part of the marshaled object.  Using the delegate after marshaling crashes.  This is TFS #265326.                //                typename _Attributes::_ProgressDelegateType^ _Progress = _M_progressDelegate; //              ::Concurrency::preview::details::_InContext<typename _Attributes::_ProgressDelegateType^>::_Get(_M_progressDelegate, _M_progressDelegateContext);                _Progress((typename _Attributes::_AsyncBaseType^)this, _ProgressValue);            }        }     private:         ::Concurrency::preview::details::_ContextCallback _M_progressDelegateContext;        typename _Attributes::_ProgressDelegateType^ _M_progressDelegate;    };     template<typename _Attributes, _AsyncResultType _ResultType = SingleResult>    ref class _AsyncBaseProgressLayer abstract : _AsyncProgressBase<_Attributes, _Attributes::_TakesProgress, _ResultType>    {    };     // **********************************************************************

Page 102: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

*****    // Task Adaptation Layer:    //     //    // _AsyncTaskThunkBase provides a *HOT* bridge between IAsync<Action/Operation> and task.  The resultant async operation hides the hot nature    // of the task (results won't be available until after Start is called, etc...).  The underlying task is, however, *HOT*.    //    template<typename _Attributes, typename _ReturnType>    ref class _AsyncTaskThunkBase abstract : _AsyncBaseProgressLayer<_Attributes>    {    public:         typedef task<_ReturnType> _TaskType;         _ReturnType GetResults()        {            _CheckValidStateForResultsCall();            return _M_task.get();        }     protected:         _AsyncTaskThunkBase(const _TaskType& _Task)            : _M_task(_Task)        {        }         _AsyncTaskThunkBase()        {        }         virtual void _OnStart()        {            task_continuation_context _Ct = task_continuation_context::use_current();            _M_task.then( [=](_TaskType _Antecedent) {                try                {                    _ReturnType _Val = _Antecedent.get();                }                catch(task_canceled&)                {                    _TryTransitionToCancelled();                }                catch(Platform::Exception^ ex)                {                    _TryTransitionToError(ex->HResult);                }                catch(...)                {                    _TryTransitionToError(E_FAIL);

Page 103: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

                }            }).then([=] (task<void>) {                //                // Completed happens regardless of what terminal state we transition into.                //                _FireCompletion();            }, _Ct);        }         _TaskType _M_task;    };     template<typename _Attributes>    ref class _AsyncTaskThunkBase<_Attributes, void> abstract : _AsyncBaseProgressLayer<_Attributes>    {    public:         typedef task<void> _TaskType;         void GetResults()        {            _CheckValidStateForResultsCall();        }     protected:         _AsyncTaskThunkBase(const _TaskType& _Task)            : _M_task(_Task)        {        }         _AsyncTaskThunkBase()        {        }         virtual void _OnStart()        {            task_continuation_context _Ct = task_continuation_context::use_current();            _M_task.then( [=](_TaskType _Antecedent)            {                try                {                    _Antecedent.get();                }                catch(task_canceled&)                {                    _TryTransitionToCancelled();                }                catch(Platform::Exception^ ex)                {                    _TryTransitionToError(ex->HResult);                }

Page 104: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

                catch(...)                {                    _TryTransitionToError(E_FAIL);                }            }).then([=] (task<void>) {                //                // Completed happens regardless of what terminal state we transition into.                //                _FireCompletion();            }, _Ct);        }         _TaskType _M_task;    };     template<typename _Attributes>    ref class _AsyncTaskThunk : _AsyncTaskThunkBase<_Attributes, typename _Attributes::_ReturnType>    {    public:         _AsyncTaskThunk(const _TaskType& _Task) :            _AsyncTaskThunkBase(_Task)        {        }     protected:         _AsyncTaskThunk()        {        }         virtual void _OnClose()        {        }         virtual void _OnCancel()        {            // Cancellation is not supported in PREVIEW//            _M_task.cancel();        }    };     // ***************************************************************************    // Async Creation Layer:    //     //    // _AsyncTaskGeneratorBase provides a truly *COLD* bridge between IAsync<Action/Operation>[WithProgress] and task.  The generator does not actually    // schedule a task *UNTIL* the IAsync*->Start method is called.    //    template<typename _Function>

Page 105: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

    ref class _AsyncTaskGeneratorThunk : _AsyncTaskThunk<typename _AsyncLambdaTypeTraits<_Function>::_AsyncAttributes>    {    public:         typedef typename _AsyncLambdaTypeTraits<_Function>::_AsyncAttributes _Attributes;        typedef typename _AsyncTaskThunk<_Attributes> _Base;        typedef typename _Attributes::_AsyncBaseType _AsyncBaseType;                 _AsyncTaskGeneratorThunk(const _Function& _Func) : _M_func(_Func)        {        }     protected:         //        // The only thing we must do different from the base class is we must spin the hot task on transition from Created->Started.  Otherwise,        // let the base thunk handle everything.        //         virtual void _OnStart()        {            //            // Call the appropriate task generator to actually produce a task of the expected type.  This might adapt the user lambda for progress reports,            // wrap the return result in a task, or allow for direct return of a task depending on the form of the lambda.            //             _M_task = _Attributes::_Generate_Task(_M_func, this);            _Base::_OnStart();        }         virtual void _OnCancel()        {            _AsyncStatusInternal _Current = _AsyncUndefined;            _CurrentStatus(&_Current);             // TODO: What's the semantic on Cancel before Start.  The spec and AsyncBase implementation contradict each other.            _Base::_OnCancel();        }     private:         _Function _M_func;    };}; /// <summary>///     Creates a WinRT asynchronous construct based on a user supplied lambda (or functor).  The return type of create_async is one of either///     IAsyncAction, IAsyncActionWithProgress<TProgress>, IAsyncOperatio

Page 106: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

n<TResult>, or IAsyncOperationWithProgress<TResult, TProgress> based on the///     signature of the lambda passed to the method. /// </summary>/// <param name="_Func">///     The user supplied lambda from which to create a WinRT asynchronous construct.  The body of the lambda is the asynchronous action or operation ///     which will be executed within the MTA.  The return type of the lambda determines whether the construct is an action or an operation.  //////     Void returning lambdas cause the creation of actions.  Non-void returning lambdas cause the creation of///     operations of TResult where TResult is the return type of the lambda.//////     The lambda may take either zero or one argument.  A zero argument lambda creates an asynchronous construct without the capability for progress///     reporting.  A one argument lambda must take an argument of the form progress_reporter<TProgress>.  Lambdas that take an argument of this form///     construct an asynchronous construct which reports progress of type TProgress each time the report method of the progress_reporter object is///     called./// </param>/// <returns>///     An asynchronous construct represented by an IAsyncAction, IAsyncActionWithProgress<TProgress>, IAsyncOperation<TResult>, or an ///     IAsyncOperationWithProgress<TResult, TProgress>.  The interface returned depends on the signature of the lambda passed into the function./// </returns>template<typename _Function>typename details::_AsyncTaskGeneratorThunk<_Function>::_AsyncBaseType^ create_async(const _Function& _Func){    return ref new details::_AsyncTaskGeneratorThunk<_Function>(_Func);} #endif /// <summary>///     Returns an indication of whether the task which is currently executing inline on the current context///     is in the midst of an active cancellation (or will be shortly).  /// </summary>/// <returns>///     <c>true</c> if the task  which is currently executing is canceling, <c>false</c> otherwise./// </returns>/**/inline bool is_current_task_canceling(){    return is_current_task_group_canceling();} /// <summary>///     Cancel the currently running task. This function can be called from within a task's body of///     execution to begin a cancellation.

Page 107: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

/// </summary>/**/__declspec(noreturn)inline void __cdecl cancel_current_task(){    throw task_canceled();} namespace details {    // Helper struct for when_all operators to know when tasks have completed    template<typename _Type>    struct _RunAllParam    {        _RunAllParam() : _M_lCompleteCount(0), _M_lCancelCount(0), _M_numTasks(0)        {        }         void _Resize(size_t _Len, bool _SkipVector = false)        {            _M_numTasks = _Len;            if (!_SkipVector) _M_vector.resize(_Len);            _M_contexts.resize(_Len);        }         std::vector<_Type> _M_vector;        std::vector<_ContextCallback> _M_contexts;        _Type _M_mergeVal;        long volatile _M_lCompleteCount;        long volatile _M_lCancelCount;        size_t _M_numTasks;    };     // Helper struct specialization for void    template<>    struct _RunAllParam<void>    {        _RunAllParam() : _M_lCompleteCount(0), _M_lCancelCount(0), _M_numTasks(0)        {        }         void _Resize(size_t _Len)        {            _M_numTasks = _Len;        }         long volatile _M_lCompleteCount;        long volatile _M_lCancelCount;        size_t _M_numTasks;    };     template<typename _ElementType, typename _Function, typename _TaskType>    void _WhenAllContinuationWrapper(_RunAllParam<_ElementType>* _PParam, con

Page 108: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

st task_completion_event<_Unit_type>& _Completed, _Function _Func, task<_TaskType>& _Task)    {        if (_Task._GetImpl()->_IsCompleted())        {            _Func();            if (_InterlockedIncrement(&_PParam->_M_lCompleteCount) == ((long) _PParam->_M_numTasks))            {                if (!_Completed.set(_Unit_type()))                {                    delete _PParam;                }            }        }        else        {            _ASSERT(_Task._GetImpl()->_IsCanceled());            if (_Task._GetImpl()->_HasUserException())            {                // _Cancel will return false if the TCE is already canceled with or without exception                if (!_Completed._Cancel(_Task._GetImpl()->_GetExceptionHolder()))                {                    // If the TCE has already reached a terminal state we must observe this exception.                    _Task._GetImpl()->_ObserveUserException();                }            }            else            {                _Completed._Cancel();            }            if (_InterlockedIncrement(&_PParam->_M_lCompleteCount) == ((long) _PParam->_M_numTasks))            {                delete _PParam;            }        }    }     template<typename _ElementType, typename _Iterator>    struct _WhenAllImpl    {        static task<std::vector<_ElementType>> _Perform(_Iterator _Begin, _Iterator _End)        {            auto _PParam = new _RunAllParam<_ElementType>();            task_completion_event<_Unit_type> _Completed;            task<_Unit_type> _All_tasks_completed(_Completed);             bool _HasAsync = false;             if( _Begin == _End )

Page 109: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

            {                _Completed.set(_Unit_type());            }            else            {                // Copy the tasks to an internal vector for processing. This allows const iterator types                // to be processed.                std::vector<task<_ElementType>> _Tasks(_Begin, _End);                _PParam->_Resize(_Tasks.size());                 size_t _Index = 0;                for (auto _PTask = _Tasks.begin(); _PTask != _Tasks.end(); ++_PTask)                {                    if (_PTask->_IsAsync())                    {                        _HasAsync = true;                    }                     _PTask->_Then([_PParam, _Index, _Completed](task<_ElementType> _ResultTask) {                         auto _Func = [_PParam, _Index, &_ResultTask](){                            _PParam->_M_vector[_Index] = _ResultTask._GetImpl()->_GetResult();                            _PParam->_M_contexts[_Index] = _ResultContext<_ElementType>::_GetContext(false);                        };                         _WhenAllContinuationWrapper(_PParam, _Completed, _Func, _ResultTask);                    }, false, false);                     _Index++;                }            }             if (_HasAsync)            {                _All_tasks_completed._SetAsync();            }             return _All_tasks_completed._Then([=](_Unit_type) -> std::vector<_ElementType> {                auto _Result = _PParam->_M_vector; // copy by value                 size_t _Index = 0;                for (auto _It = _Result.begin(); _It != _Result.end(); ++_It)                {                    *_It = ::Concurrency::preview::details::_ResultContext<_ElementType>::_GetValue(*_It, _PParam->_M_contexts[_Index++], false);                }                 delete _PParam;

Page 110: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

                return _Result;            }, false, true);        }    };     template<typename _ElementType, typename _Iterator>    struct _WhenAllImpl<std::vector<_ElementType>, _Iterator>    {        static task<std::vector<_ElementType>> _Perform(_Iterator _Begin, _Iterator _End)        {            auto _PParam = new _RunAllParam<std::vector<_ElementType>>();            task_completion_event<_Unit_type> _Completed;            task<_Unit_type> _All_tasks_completed(_Completed);             bool _HasAsync = false;             if( _Begin == _End )            {                _Completed.set(_Unit_type());            }            else            {                // Copy the tasks to an internal vector for processing. This allows const iterator types                // to be processed.                std::vector<task<std::vector<_ElementType>>> _Tasks(_Begin, _End);                _PParam->_Resize(_Tasks.size());                 size_t _Index = 0;                for (auto _PTask = _Tasks.begin(); _PTask != _Tasks.end(); ++_PTask)                {                    if (_PTask->_IsAsync())                    {                        _HasAsync = true;                    }                     _PTask->_Then([_PParam, _Index, _Completed](task<std::vector<_ElementType>> _ResultTask) {                         auto _Func = [_PParam, _Index, &_ResultTask]() {                            _PParam->_M_vector[_Index] = _ResultTask._GetImpl()->_GetResult();                            _PParam->_M_contexts[_Index] = ::Concurrency::preview::details::_ResultContext<_ElementType>::_GetContext(false);                        };                         _WhenAllContinuationWrapper(_PParam, _Completed, _Func, _ResultTask);                    }, false, false);                    _Index++;                }            }

Page 111: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

            if (_HasAsync)            {                _All_tasks_completed._SetAsync();            }             return _All_tasks_completed._Then([=](_Unit_type) -> std::vector<_ElementType> {                _ASSERT(_PParam->_M_lCompleteCount == ((long) _PParam->_M_numTasks ));                std::vector<_ElementType> _Result;                for(unsigned int _I = 0; _I < _PParam->_M_numTasks; _I++)                {                    std::vector<_ElementType>& _Vec = _PParam->_M_vector[_I];                     for (auto _It = _Vec.begin(); _It != _Vec.end(); ++_It)                    {                        *_It = ::Concurrency::preview::details::_ResultContext<_ElementType>::_GetValue(*_It, _PParam->_M_contexts[_I], false);                    }                                        _Result.insert(_Result.end(), _Vec.begin(), _Vec.end());                }                delete _PParam;                return _Result;            }, false, true);        }    };     template<typename _Iterator>    struct _WhenAllImpl<void, _Iterator>    {        static task<void> _Perform(_Iterator _Begin, _Iterator _End)        {            auto _PParam = new _RunAllParam<_Unit_type>();            task_completion_event<_Unit_type> _Completed;            task<_Unit_type> _All_tasks_completed(_Completed);             bool _HasAsync = false;             if( _Begin == _End )            {                _Completed.set(_Unit_type());            }            else            {                // Copy the tasks to an internal vector for processing. This allows const iterator types                // to be processed.                std::vector<task<void>> _Tasks(_Begin, _End);                _PParam->_Resize(_Tasks.size());                 for (auto _PTask = _Tasks.begin(); _PTask != _Tasks.end(); ++_PTask)                {

Page 112: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

                    if (_PTask->_IsAsync())                    {                        _HasAsync = true;                    }                     _PTask->_Then([_PParam, _Completed](task<void> _ResultTask) {                         auto _Func = [](){};                        _WhenAllContinuationWrapper(_PParam, _Completed, _Func, _ResultTask);                    }, false, false);                }            }             if (_HasAsync)            {                _All_tasks_completed._SetAsync();            }             return _All_tasks_completed.then([=](_Unit_type){                delete _PParam;            });        }    };     template<typename _ReturnType>    task<std::vector<_ReturnType>> _WhenAllVectorAndValue(task<std::vector<_ReturnType>>& _VectorTask, task<_ReturnType>& _ValueTask,                                                          bool _OutputVectorFirst)    {        auto _PParam = new _RunAllParam<_ReturnType>();        task_completion_event<_Unit_type> _Completed;        task<_Unit_type> _All_tasks_completed(_Completed);         _PParam->_Resize(2, true);          _VectorTask._Then([_PParam, _Completed](task<std::vector<_ReturnType>> _ResultTask) {             auto _Func = [_PParam, &_ResultTask]() {                _PParam->_M_vector = _ResultTask._GetImpl()->_GetResult();                _PParam->_M_contexts[0] = _ResultContext<_ReturnType>::_GetContext(false);            };             _WhenAllContinuationWrapper(_PParam, _Completed, _Func, _ResultTask);        }, false, false);         _ValueTask._Then([_PParam, _Completed](task<_ReturnType> _ResultTask) {             auto _Func = [_PParam, &_ResultTask]() {

Page 113: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

                _PParam->_M_mergeVal = _ResultTask._GetImpl()->_GetResult();                _PParam->_M_contexts[1] = _ResultContext<_ReturnType>::_GetContext(false);            };             _WhenAllContinuationWrapper(_PParam, _Completed, _Func, _ResultTask);        }, false, false);         if (_VectorTask._IsAsync() || _ValueTask._IsAsync())        {            _All_tasks_completed._SetAsync();        }         return _All_tasks_completed._Then([=](_Unit_type) -> std::vector<_ReturnType> {            _ASSERT(_PParam->_M_lCompleteCount == ((long) 2));            auto _Result = _PParam->_M_vector; // copy by value             for (auto _It = _Result.begin(); _It != _Result.end(); ++_It)            {                *_It = ::Concurrency::preview::details::_ResultContext<_ReturnType>::_GetValue(*_It, _PParam->_M_contexts[0], false);            }             if (_OutputVectorFirst == true)            {                _Result.push_back(::Concurrency::preview::details::_ResultContext<_ReturnType>::_GetValue(_PParam->_M_mergeVal, _PParam->_M_contexts[1], false));            }            else            {                _Result.insert(_Result.begin(), ::Concurrency::preview::details::_ResultContext<_ReturnType>::_GetValue(_PParam->_M_mergeVal, _PParam->_M_contexts[1], false));            }             delete _PParam;            return _Result;        }, false, true);    }} // namespace details /// <summary>///     First-class tasks when_all API using begin and end iterators/// </summary>/// <typeparam name="_Iterator">///     The type of the input iterator./// </typeparam>/// <param name="_Begin">///     Position of the first element in the range of elements to be combined and waited on./// </param>/// <param name="_End">

Page 114: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

///     Position of the first element beyond the range of elements to be combined and waited on./// </param>/// <returns>///     A task that completes when all of the input tasks are complete. If the input tasks are of type <c>T</c>, the output///     of this function will be a <c>task<std::vector<T>></c>. If the input tasks are of type <c>void</c> the output will ///     also be a <c>task<void></c>./// </returns>/**/template <typename _Iterator>auto when_all(_Iterator _Begin, _Iterator _End)     -> decltype (details::_WhenAllImpl<std::iterator_traits<_Iterator>::value_type::_TaskType, _Iterator>::_Perform(_Begin, _End)){    typedef std::iterator_traits<_Iterator>::value_type::_TaskType _ElementType;    return details::_WhenAllImpl<_ElementType, _Iterator>::_Perform(_Begin, _End);} /// <summary>///     When_all operator (task1 && task2) for two tasks/// </summary>/// <typeparam name="_ReturnType">///     The type of the tasks./// </typeparam>/// <param name="_Lhs">///     The first task to combine into this when_all task./// </param>/// <param name="_Rhs">///     The second task to combine into this when_all task./// </param>/// <returns>///     A task that completes when all of the input tasks are complete. If the input tasks are of type <c>T</c>, the output///     of this function will be a <c>task<std::vector<T>></c>. If the input tasks are of type <c>void</c> the output will ///     also be a <c>task<void></c>./// </returns>/**/template<typename _ReturnType>task<std::vector<_ReturnType>> operator&&(task<_ReturnType> _Lhs, task<_ReturnType> _Rhs){    task<_ReturnType> _PTasks[2] = {_Lhs, _Rhs};    return when_all(_PTasks, _PTasks+2);} /// <summary>///     When_all operator (task1 && task2) for two tasks/// </summary>/// <typeparam name="_ReturnType">///     The type of the tasks.

Page 115: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

/// </typeparam>/// <param name="_Lhs">///     The first task to combine into this when_all task./// </param>/// <param name="_Rhs">///     The second task to combine into this when_all task./// </param>/// <returns>///     A task that completes when all of the input tasks are complete. If the input tasks are of type <c>T</c>, the output///     of this function will be a <c>task<std::vector<T>></c>. If the input tasks are of type <c>void</c> the output will ///     also be a <c>task<void></c>./// </returns>/**/template<typename _ReturnType>task<std::vector<_ReturnType>> operator&&(task<std::vector<_ReturnType>> _Lhs, task<_ReturnType> _Rhs){    return details::_WhenAllVectorAndValue(_Lhs, _Rhs, true);} /// <summary>///     When_all operator (task1 && task2) for two tasks/// </summary>/// <typeparam name="_ReturnType">///     The type of the tasks./// </typeparam>/// <param name="_Lhs">///     The first task to combine into this when_all task./// </param>/// <param name="_Rhs">///     The second task to combine into this when_all task./// </param>/// <returns>///     A task that completes when all of the input tasks are complete. If the input tasks are of type <c>T</c>, the output///     of this function will be a <c>task<std::vector<T>></c>. If the input tasks are of type <c>void</c> the output will ///     also be a <c>task<void></c>./// </returns>/**/template<typename _ReturnType>task<std::vector<_ReturnType>> operator&&(task<_ReturnType> _Lhs, task<std::vector<_ReturnType>> _Rhs){    return details::_WhenAllVectorAndValue(_Rhs, _Lhs, false);} /// <summary>///     When_all operator (task1 && task2) for two tasks/// </summary>/// <typeparam name="_ReturnType">///     The type of the tasks./// </typeparam>

Page 116: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

/// <param name="_Lhs">///     The first task to combine into this when_all task./// </param>/// <param name="_Rhs">///     The second task to combine into this when_all task./// </param>/// <returns>///     A task that completes when all of the input tasks are complete. If the input tasks are of type <c>T</c>, the output///     of this function will be a <c>task<std::vector<T>></c>. If the input tasks are of type <c>void</c> the output will ///     also be a <c>task<void></c>./// </returns>/**/template<typename _ReturnType>task<std::vector<_ReturnType>> operator&&(task<std::vector<_ReturnType>> _Lhs, task<std::vector<_ReturnType>> _Rhs){    task<std::vector<_ReturnType>> _PTasks[2] = {_Lhs, _Rhs};    return when_all(_PTasks, _PTasks+2);} /// <summary>///     When_all operator (task1 && task2) for two tasks/// </summary>/// <param name="_Lhs">///     The first task to combine into this when_all task./// </param>/// <param name="_Rhs">///     The second task to combine into this when_all task./// </param>/// <returns>///     A task that completes when all of the input tasks are complete. If the input tasks are of type <c>T</c>, the output///     of this function will be a <c>task<std::vector<T>></c>. If the input tasks are of type <c>void</c> the output will ///     also be a <c>task<void></c>./// </returns>/**/inline task<void> operator&&(task<void> _Lhs, task<void> _Rhs){    task<void> _PTasks[2] = {_Lhs, _Rhs};    return when_all(_PTasks, _PTasks+2);} namespace details {    // Helper struct for when_any operators to know when tasks have completed    struct _RunAnyParam    {        _RunAnyParam() : _M_lCompleteCount(0), _M_lCancelCount(0), _M_numTasks(0)        {        }        long volatile _M_lCompleteCount;

Page 117: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

        long volatile _M_lCancelCount;        size_t _M_numTasks;    };     template<typename _CompletionType, typename _Function, typename _TaskType>    void _WhenAnyContinuationWrapper(_RunAnyParam* _PParam, const task_completion_event<_CompletionType>& _Completed, _Function _Func, task<_TaskType>& _Task)    {        if (_Task._GetImpl()->_IsCompleted())        {            _Func();            if (_InterlockedIncrement(&_PParam->_M_lCompleteCount) == ((long) _PParam->_M_numTasks))            {                delete _PParam;            }        }        else        {            _ASSERT(_Task._GetImpl()->_IsCanceled());            if (_Task._GetImpl()->_HasUserException())            {                _Completed._StoreException(_Task._GetImpl()->_GetExceptionHolder());            }            if (_InterlockedIncrement(&_PParam->_M_lCancelCount) == ((long) _PParam->_M_numTasks))            {                _Completed._Cancel();            }            if (_InterlockedIncrement(&_PParam->_M_lCompleteCount) == ((long) _PParam->_M_numTasks))            {                delete _PParam;            }        }    }     template<typename _ElementType, typename _Iterator>    struct _WhenAnyImpl    {        static task<std::pair<_ElementType, size_t>> _Perform(_Iterator _Begin, _Iterator _End)        {            if( _Begin == _End )            {                throw invalid_operation("when_any(begin, end) cannot be called on an empty container.");            }             auto _PParam = new _RunAnyParam();            task_completion_event<std::pair<_ElementType, size_t>> _Completed;

Page 118: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

            task<std::pair<_ElementType, size_t>> _Any_tasks_completed(_Completed);            _Any_tasks_completed._GetImpl()->_M_fRuntimeAggregate = true;             bool _HasAsync = false;             // Copy the tasks to an internal vector for processing. This allows const iterator types            // to be processed.            std::vector<task<_ElementType>> _Tasks(_Begin, _End);            _PParam->_M_numTasks = _Tasks.size();             size_t index = 0;            for (auto _PTask = _Tasks.begin(); _PTask != _Tasks.end(); ++_PTask)            {                if (_PTask->_IsAsync())                {                    _HasAsync = true;                }                 _PTask->_Then([_PParam, _Completed, index](task<_ElementType> _ResultTask) {                     auto _Func = [&_ResultTask, &_Completed, index]() {                        _ElementType _Result = _ResultTask._GetImpl()->_GetResult();                        _Completed.set(std::make_pair(_Result, index));                    };                     _WhenAnyContinuationWrapper(_PParam, _Completed, _Func, _ResultTask);                }, false, false);                 index++;            }             if (_HasAsync)            {                _Any_tasks_completed._SetAsync();            }             return _Any_tasks_completed._Then([=](std::pair<_ElementType, size_t> _Result) -> std::pair<_ElementType, size_t> {                return _Result;            }, false, true);        }    };     template<typename _Iterator>    struct _WhenAnyImpl<void, _Iterator>    {        static task<size_t> _Perform(_Iterator _Begin, _Iterator _End)        {            if( _Begin == _End )

Page 119: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

            {                throw invalid_operation("when_any(begin, end) cannot be called on an empty container.");            }             auto _PParam = new _RunAnyParam();            task_completion_event<size_t> _Completed;            task<size_t> _Any_tasks_completed(_Completed);             bool _HasAsync = false;             // Copy the tasks to an internal vector for processing. This allows const iterator types            // to be processed.            std::vector<task<void>> _Tasks(_Begin, _End);            _PParam->_M_numTasks = _Tasks.size();             size_t index = 0;            for (auto _PTask = _Tasks.begin(); _PTask != _Tasks.end(); ++_PTask)            {                if (_PTask->_IsAsync())                {                    _HasAsync = true;                }                 _PTask->_Then([_PParam, _Completed, index](task<void> _ResultTask) {                    auto _Func = [&_ResultTask, &_Completed, index]() {                        _Completed.set(index);                    };                    _WhenAnyContinuationWrapper(_PParam, _Completed, _Func, _ResultTask);                }, false, false);                 index++;            }             if (_HasAsync)            {                _Any_tasks_completed._SetAsync();            }             return _Any_tasks_completed.then([=](size_t _Result) -> size_t {                return _Result;            });        }    }; #if defined(__cplusplus_winrt)    template<typename _T>    task<_T> _To_task_helper(Windows::Foundation::IAsyncOperation<_T>^ op)    {        return task<_T>(op);    }

Page 120: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

    template<typename _T, typename _Progress>    task<_T> _To_task_helper(Windows::Foundation::IAsyncOperationWithProgress<_T, _Progress>^ op)    {        return task<_T>(op);    }     inline task<void> _To_task_helper(Windows::Foundation::IAsyncAction^ op)    {        return task<void>(op);    }     template<typename _Progress>    task<void> _To_task_helper(Windows::Foundation::IAsyncActionWithProgress<_Progress>^ op)    {        return task<void>(op);    }#endif } // namespace details /// <summary>///     First-class tasks when_any API using begin and end iterators/// </summary>/// <typeparam name="_Iterator">///     The type of the input iterator./// </typeparam>/// <param name="_Begin">///     Position of the first element in the range of elements to be combined and waited on./// </param>/// <param name="_End">///     Position of the first element beyond the range of elements to be combined and waited on./// </param>/// <returns>///     A task that completes when any one of the input tasks are complete. If the input tasks are of type <c>T</c>, the output///     of this function will be a <c>task<std::pair<T, size_t>></c>. Where the first element of the pair is the result of the///     completing task, and the second element is the index of the task that finished.  If the input tasks are of type <c>void</c> ///     the output is a <c>task<size_t></c>, where the result is the index of the completing task./// </returns>/**/template<typename _Iterator>auto when_any(_Iterator _Begin, _Iterator _End)    -> decltype (details::_WhenAnyImpl<std::iterator_traits<_Iterator>::value_type::_TaskType, _Iterator>::_Perform(_Begin, _End)){    typedef std::iterator_traits<_Iterator>::value_type::_TaskType _ElementType;

Page 121: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

    return details::_WhenAnyImpl<_ElementType, _Iterator>::_Perform(_Begin, _End);} /// <summary>///     When_any operator (task1 || task2) for two task<T>/// </summary>/// <typeparam name="_ReturnType">///     The type of the tasks./// </typeparam>/// <param name="_Lhs">///     The first task to combine into this when_all task./// </param>/// <param name="_Rhs">///     The second task to combine into this when_all task./// </param>/// <returns>///     A task that completes when all of the input tasks are complete. If the input tasks are of type <c>T</c>, the output///     of this function will be a <c>task<T></c>. If the input tasks are of type <c>void</c> the output will ///     also be a <c>task<void></c>./// </returns>/**/template<typename _ReturnType>task<_ReturnType> operator||(task<_ReturnType> _Lhs, task<_ReturnType> _Rhs){    auto _PParam = new details::_RunAnyParam();    task_completion_event<_ReturnType> _Completed;    task<_ReturnType> _Any_tasks_completed(_Completed);    _PParam->_M_numTasks = 2;     auto _Continuation = [_PParam, _Completed](task<_ReturnType> _ResultTask) {        auto _Func = [&_ResultTask, &_Completed]() {            _ReturnType _Result = _ResultTask._GetImpl()->_GetResult();            _Completed.set(_Result);        };        _WhenAnyContinuationWrapper(_PParam, _Completed, _Func, _ResultTask);    };     _Lhs._Then(_Continuation, false, false);    _Rhs._Then(_Continuation, false, false);     if (_Lhs._IsAsync() || _Rhs._IsAsync())    {        _Any_tasks_completed._SetAsync();    }     return _Any_tasks_completed.then([=](_ReturnType _Ret) -> _ReturnType {        return _Ret;    });} /// <summary>

Page 122: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

///     When_any operator (task1 || task2) for one task<std::vector<T>> and a task<T>/// </summary>/// <typeparam name="_ReturnType">///     The type of the tasks./// </typeparam>/// <param name="_Lhs">///     The first task to combine into this when_all task./// </param>/// <param name="_Rhs">///     The second task to combine into this when_all task./// </param>/// <returns>///     A task that completes when all of the input tasks are complete. If the input tasks are of type <c>T</c>, the output///     of this function will be a <c>task<T></c>. If the input tasks are of type <c>void</c> the output will ///     also be a <c>task<void></c>./// </returns>/**/template<typename _ReturnType>task<std::vector<_ReturnType>> operator||(task<std::vector<_ReturnType>> _Lhs, task<_ReturnType> _Rhs){    auto _PParam = new details::_RunAnyParam();    task_completion_event<std::vector<_ReturnType>> _Completed;    task<std::vector<_ReturnType>> _Any_tasks_completed(_Completed);     _Any_tasks_completed._GetImpl()->_M_fRuntimeAggregate = true;    _PParam->_M_numTasks = 2;     _Lhs._Then([_PParam, _Completed](task<std::vector<_ReturnType>> _ResultTask) {        auto _Func = [&_ResultTask, &_Completed]() {            std::vector<_ReturnType> _Result = _ResultTask._GetImpl()->_GetResult();            _Completed.set(_Result);        };        _WhenAnyContinuationWrapper(_PParam, _Completed, _Func, _ResultTask);    }, false, false);     _Rhs._Then([_PParam, _Completed](task<_ReturnType> _ResultTask) {        auto _Func = [&_ResultTask, &_Completed]() {            _ReturnType _Result = _ResultTask._GetImpl()->_GetResult();             std::vector<_ReturnType> _Vec;            _Vec.push_back(_Result);            _Completed.set(_Vec);        };        _WhenAnyContinuationWrapper(_PParam, _Completed, _Func, _ResultTask);    }, false, false);     if (_Lhs._IsAsync() || _Rhs._IsAsync())    {        _Any_tasks_completed._SetAsync();

Page 123: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

    }     return _Any_tasks_completed._Then([=](std::vector<_ReturnType> _Ret) -> std::vector<_ReturnType> {        return _Ret;    }, false, true);} /// <summary>///     When_any operator (task1 || task2) for one task<T> and a task<std::vector<T>>/// </summary>/// <typeparam name="_ReturnType">///     The type of the tasks./// </typeparam>/// <param name="_Lhs">///     The first task to combine into this when_all task./// </param>/// <param name="_Rhs">///     The second task to combine into this when_all task./// </param>/// <returns>///     A task that completes when all of the input tasks are complete. If the input tasks are of type <c>T</c>, the output///     of this function will be a <c>task<T></c>. If the input tasks are of type <c>void</c> the output will ///     also be a <c>task<void></c>./// </returns>/**/template<typename _ReturnType>task<std::vector<_ReturnType>> operator||(task<_ReturnType> _Lhs, task<std::vector<_ReturnType>> _Rhs){    return _Rhs || _Lhs;} // When_any operator (task1 || task2) for two task<void>inline task<void> operator||(task<void> _Lhs, task<void> _Rhs){    auto _PParam = new details::_RunAnyParam();    task_completion_event<details::_Unit_type> _Completed;    task<details::_Unit_type> _Any_task_completed(_Completed);     _PParam->_M_numTasks = 2;     auto _Continuation = [_PParam, _Completed](task<void> _ResultTask) {        auto _Func = [&_Completed]() {            _Completed.set(details::_Unit_type());        };        _WhenAnyContinuationWrapper(_PParam, _Completed, _Func, _ResultTask);    };     _Lhs._Then(_Continuation, false, false);    _Rhs._Then(_Continuation, false, false);

Page 124: christophep.files.wordpress.com€¦ · Web viewnamespace details{ // // PREVIEW: Dummy definition to get the header to compile // class _Task_canceled : public std::exception ...

    if (_Lhs._IsAsync() || _Rhs._IsAsync())    {        _Any_task_completed._SetAsync();    }     return _Any_task_completed.then([=](details::_Unit_type){ });}} // namespace preview} // namespace Concurrency namespace concurrency = Concurrency; #pragma warning(pop) #pragma pack(pop) #endif // _PPLTASKS_H


Recommended