Fix corner case error handling (#505)
This change fixes a corner case where we could orphan a call if an async call was started after a queue was terminated.
This commit is contained in:
Родитель
98e0c141d6
Коммит
db4fb0c6c9
|
@ -158,6 +158,7 @@
|
|||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\Task\ThreadPool_win32.cpp" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer.h" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer_win32.cpp" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XAsyncProviderPriv.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XTaskQueuePriv.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\referenced_ptr.h" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\WebSocket\WinRT\winrt_websocket.cpp" />
|
||||
|
|
|
@ -159,6 +159,9 @@
|
|||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XAsyncProviderPriv.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XTaskQueuePriv.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
@ -141,6 +141,7 @@
|
|||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\Task\ThreadPool_win32.cpp" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer.h" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer_win32.cpp" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XAsyncProviderPriv.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XTaskQueuePriv.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\referenced_ptr.h" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\WebSocket\Websocketpp\websocketpp_websocket.cpp" />
|
||||
|
|
|
@ -138,6 +138,9 @@
|
|||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XAsyncProviderPriv.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XTaskQueuePriv.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
|
@ -183,46 +186,46 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="C++ Source">
|
||||
<UniqueIdentifier>{B348936D-D09B-3ACE-A476-12C7C5E48781}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{AB68AAD7-BF0D-34C3-BFBA-FB7594810503}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Common">
|
||||
<UniqueIdentifier>{6D290126-3831-3A04-903B-F2ADD104D81C}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{8B9EEA6A-3165-3A83-8CEB-648270B8C445}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Common\Win">
|
||||
<UniqueIdentifier>{E705B256-E422-3FF4-95FA-7E24B8A5474F}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{28B59420-8446-3F26-9AB1-72123FF92816}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Global">
|
||||
<UniqueIdentifier>{B5E18BF5-6C51-323C-96A0-81422D9D6069}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{A616C757-EB09-3284-8BA4-4C0B391C1672}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\HTTP">
|
||||
<UniqueIdentifier>{6DAD9E7F-080C-3264-920E-77D0AFFE8CC9}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{7607E023-D56D-300A-AAE7-35C1337C6EF3}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\HTTP\WinHttp">
|
||||
<UniqueIdentifier>{01466804-77B8-33C2-AAEE-469619C39927}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{6095F35A-0F36-3DA9-8D1A-8F2DA598B6E0}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Logger">
|
||||
<UniqueIdentifier>{FD710BAD-78A2-39F4-9CB7-90B1627CC1D5}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{658327C4-885D-3CF1-9061-DA642B97898A}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Logger\Win">
|
||||
<UniqueIdentifier>{CE716A57-F0D2-3112-9432-4955DE919940}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{89A6373D-D2E3-3B5B-B6CF-4AB7CDFB13B8}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Mock">
|
||||
<UniqueIdentifier>{ECB59FD8-67C4-354A-90B2-DFC893C0F2E5}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{57AC3982-96A9-3B0B-A7DF-8DF69AD19ECC}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Task">
|
||||
<UniqueIdentifier>{09ED63FC-76E4-368A-B7E4-40A1D70ABD31}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{075BEBE6-800C-3FB2-84E2-6443C472E199}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Task\Win">
|
||||
<UniqueIdentifier>{82CDC498-C15D-38CB-ABAF-432B4881A142}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{D0B227E9-0B82-3AF7-82EC-9581DA9FD1A3}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\WebSocket">
|
||||
<UniqueIdentifier>{09CB3AE4-1639-3274-BB94-99AAC498EA50}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{0974FCD6-8409-3FA3-A118-A58ED0FD041C}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\WebSocket\Win">
|
||||
<UniqueIdentifier>{802954F0-B5AC-3B13-A5F2-01E8A7888AAE}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{350A88A7-908E-346C-8EEC-8C500141D764}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Public Includes">
|
||||
<UniqueIdentifier>{42CA3718-AE3E-3CEB-A859-F23D0D7A9918}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{2F64C9BE-5116-3E71-971F-592C0D76A89D}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
|
@ -130,6 +130,7 @@
|
|||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\Task\ThreadPool_win32.cpp" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer.h" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer_win32.cpp" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XAsyncProviderPriv.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XTaskQueuePriv.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\referenced_ptr.h" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\WebSocket\WinRT\winrt_websocket.cpp" />
|
||||
|
|
|
@ -159,6 +159,9 @@
|
|||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XAsyncProviderPriv.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XTaskQueuePriv.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
<ApplicationTypeRevision>3.0</ApplicationTypeRevision>
|
||||
<HCLibPlatformType>Android</HCLibPlatformType>
|
||||
<HCLibImpl>true</HCLibImpl>
|
||||
<AndroidSdkBuildToolsVersion>25.0.3</AndroidSdkBuildToolsVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup>
|
||||
|
@ -126,6 +125,7 @@
|
|||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\Task\ThreadPool_stl.cpp" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer.h" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer_stl.cpp" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XAsyncProviderPriv.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XTaskQueuePriv.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\referenced_ptr.h" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\WebSocket\Websocketpp\websocketpp_websocket.cpp" />
|
||||
|
|
|
@ -147,6 +147,9 @@
|
|||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XAsyncProviderPriv.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XTaskQueuePriv.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
@ -169,6 +169,7 @@
|
|||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\Task\ThreadPool_win32.cpp" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer.h" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer_win32.cpp" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XAsyncProviderPriv.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XTaskQueuePriv.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\referenced_ptr.h" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\WebSocket\WinRT\winrt_websocket.cpp" />
|
||||
|
|
|
@ -159,6 +159,9 @@
|
|||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XAsyncProviderPriv.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XTaskQueuePriv.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
@ -150,6 +150,7 @@
|
|||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\Task\ThreadPool_win32.cpp" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer.h" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer_win32.cpp" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XAsyncProviderPriv.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XTaskQueuePriv.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\referenced_ptr.h" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\WebSocket\Websocketpp\websocketpp_websocket.cpp" />
|
||||
|
|
|
@ -138,6 +138,9 @@
|
|||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XAsyncProviderPriv.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XTaskQueuePriv.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
|
@ -183,46 +186,46 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="C++ Source">
|
||||
<UniqueIdentifier>{B348936D-D09B-3ACE-A476-12C7C5E48781}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{AB68AAD7-BF0D-34C3-BFBA-FB7594810503}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Common">
|
||||
<UniqueIdentifier>{6D290126-3831-3A04-903B-F2ADD104D81C}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{8B9EEA6A-3165-3A83-8CEB-648270B8C445}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Common\Win">
|
||||
<UniqueIdentifier>{E705B256-E422-3FF4-95FA-7E24B8A5474F}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{28B59420-8446-3F26-9AB1-72123FF92816}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Global">
|
||||
<UniqueIdentifier>{B5E18BF5-6C51-323C-96A0-81422D9D6069}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{A616C757-EB09-3284-8BA4-4C0B391C1672}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\HTTP">
|
||||
<UniqueIdentifier>{6DAD9E7F-080C-3264-920E-77D0AFFE8CC9}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{7607E023-D56D-300A-AAE7-35C1337C6EF3}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\HTTP\WinHttp">
|
||||
<UniqueIdentifier>{01466804-77B8-33C2-AAEE-469619C39927}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{6095F35A-0F36-3DA9-8D1A-8F2DA598B6E0}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Logger">
|
||||
<UniqueIdentifier>{FD710BAD-78A2-39F4-9CB7-90B1627CC1D5}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{658327C4-885D-3CF1-9061-DA642B97898A}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Logger\Win">
|
||||
<UniqueIdentifier>{CE716A57-F0D2-3112-9432-4955DE919940}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{89A6373D-D2E3-3B5B-B6CF-4AB7CDFB13B8}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Mock">
|
||||
<UniqueIdentifier>{ECB59FD8-67C4-354A-90B2-DFC893C0F2E5}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{57AC3982-96A9-3B0B-A7DF-8DF69AD19ECC}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Task">
|
||||
<UniqueIdentifier>{09ED63FC-76E4-368A-B7E4-40A1D70ABD31}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{075BEBE6-800C-3FB2-84E2-6443C472E199}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Task\Win">
|
||||
<UniqueIdentifier>{82CDC498-C15D-38CB-ABAF-432B4881A142}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{D0B227E9-0B82-3AF7-82EC-9581DA9FD1A3}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\WebSocket">
|
||||
<UniqueIdentifier>{09CB3AE4-1639-3274-BB94-99AAC498EA50}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{0974FCD6-8409-3FA3-A118-A58ED0FD041C}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\WebSocket\Win">
|
||||
<UniqueIdentifier>{802954F0-B5AC-3B13-A5F2-01E8A7888AAE}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{350A88A7-908E-346C-8EEC-8C500141D764}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Public Includes">
|
||||
<UniqueIdentifier>{42CA3718-AE3E-3CEB-A859-F23D0D7A9918}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{2F64C9BE-5116-3E71-971F-592C0D76A89D}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
|
@ -131,6 +131,7 @@
|
|||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\Task\ThreadPool_win32.cpp" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer.h" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer_win32.cpp" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XAsyncProviderPriv.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XTaskQueuePriv.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\referenced_ptr.h" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\WebSocket\WinRT\winrt_websocket.cpp" />
|
||||
|
|
|
@ -159,6 +159,9 @@
|
|||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XAsyncProviderPriv.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XTaskQueuePriv.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{5e0ce391-1ac5-4930-921e-2577a4b5c530}</ProjectGuid>
|
||||
<ProjectGuid>{80FE2440-4F89-4A47-88C6-E86447BC2319}</ProjectGuid>
|
||||
<Keyword>Android</Keyword>
|
||||
<PlatformToolset>Clang_5_0</PlatformToolset>
|
||||
<AndroidAPILevel Condition="'$(Platform)'!='ARM64' AND '$(Platform)'!='x64'">android-19</AndroidAPILevel>
|
||||
|
@ -46,7 +46,6 @@
|
|||
<ApplicationTypeRevision>3.0</ApplicationTypeRevision>
|
||||
<HCLibPlatformType>Android</HCLibPlatformType>
|
||||
<HCLibImpl>true</HCLibImpl>
|
||||
<AndroidSdkBuildToolsVersion>25.0.3</AndroidSdkBuildToolsVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup>
|
||||
|
@ -126,6 +125,7 @@
|
|||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\Task\ThreadPool_stl.cpp" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer.h" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer_stl.cpp" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XAsyncProviderPriv.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XTaskQueuePriv.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\referenced_ptr.h" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\WebSocket\Websocketpp\websocketpp_websocket.cpp" />
|
||||
|
|
|
@ -147,6 +147,9 @@
|
|||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XAsyncProviderPriv.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XTaskQueuePriv.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
|
@ -192,46 +195,46 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="C++ Source">
|
||||
<UniqueIdentifier>{A740C412-FB5D-3AAA-8C89-79F901BDFCAA}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{AB68AAD7-BF0D-34C3-BFBA-FB7594810503}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Common">
|
||||
<UniqueIdentifier>{27CFE030-22C9-3F80-BE9E-6C85269BA8CF}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{8B9EEA6A-3165-3A83-8CEB-648270B8C445}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Common\Android">
|
||||
<UniqueIdentifier>{7F5C193A-6335-3652-8522-F362DE77CEC5}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{F6086770-20F5-36E7-9347-F8E511A64421}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Global">
|
||||
<UniqueIdentifier>{3A5140CA-AFB5-3F07-934D-A8067647C112}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{A616C757-EB09-3284-8BA4-4C0B391C1672}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\HTTP">
|
||||
<UniqueIdentifier>{4C46FCD2-8942-35E4-A9F6-E32517A218FC}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{7607E023-D56D-300A-AAE7-35C1337C6EF3}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\HTTP\Android">
|
||||
<UniqueIdentifier>{3FE50A42-C399-35C5-807F-53541A10E202}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{15D2B7C4-8092-30BB-B45A-23FB8BB289F7}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Logger">
|
||||
<UniqueIdentifier>{F9631A84-9D6B-300A-B12D-A52D1FCE33D5}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{658327C4-885D-3CF1-9061-DA642B97898A}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Logger\Android">
|
||||
<UniqueIdentifier>{1CBA16A9-7A69-31BB-8A4F-0C4D1CC3CF66}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{5DE6DC08-DC97-3EDE-86DC-D80C73AB8212}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Mock">
|
||||
<UniqueIdentifier>{7E7975B0-87A8-3B63-AC39-F4B973EBFE5E}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{57AC3982-96A9-3B0B-A7DF-8DF69AD19ECC}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Task">
|
||||
<UniqueIdentifier>{A5C44A5C-F557-3485-B0F3-96924ED16997}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{075BEBE6-800C-3FB2-84E2-6443C472E199}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Task\Android">
|
||||
<UniqueIdentifier>{B18AF8F5-F9A5-3AA5-BCEA-7699667F4BEF}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{B2E61810-6BF3-36DB-9286-C42708123F18}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\WebSocket">
|
||||
<UniqueIdentifier>{0EAC292A-EAC0-3C04-9776-AA439EE69493}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{0974FCD6-8409-3FA3-A118-A58ED0FD041C}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\WebSocket\Android">
|
||||
<UniqueIdentifier>{1B92AFE8-7559-338C-9B27-68248D7AF766}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{683D025C-B830-3477-9275-4EA8A76EDB09}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Public Includes">
|
||||
<UniqueIdentifier>{D805E6E3-877C-379F-9EEB-B64746DE0E67}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{2F64C9BE-5116-3E71-971F-592C0D76A89D}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
|
@ -169,6 +169,7 @@
|
|||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\Task\ThreadPool_win32.cpp" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer.h" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer_win32.cpp" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XAsyncProviderPriv.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XTaskQueuePriv.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\referenced_ptr.h" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\WebSocket\WinRT\winrt_websocket.cpp" />
|
||||
|
@ -188,4 +189,4 @@
|
|||
<ItemGroup>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
</Project>
|
||||
</Project>
|
|
@ -159,6 +159,9 @@
|
|||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XAsyncProviderPriv.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XTaskQueuePriv.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
|
@ -201,46 +204,46 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="C++ Source">
|
||||
<UniqueIdentifier>{A740C412-FB5D-3AAA-8C89-79F901BDFCAA}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{AB68AAD7-BF0D-34C3-BFBA-FB7594810503}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Common">
|
||||
<UniqueIdentifier>{27CFE030-22C9-3F80-BE9E-6C85269BA8CF}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{8B9EEA6A-3165-3A83-8CEB-648270B8C445}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Common\Win">
|
||||
<UniqueIdentifier>{DFE90BE8-BA04-38D4-B957-489922F25F6C}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{28B59420-8446-3F26-9AB1-72123FF92816}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Global">
|
||||
<UniqueIdentifier>{3A5140CA-AFB5-3F07-934D-A8067647C112}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{A616C757-EB09-3284-8BA4-4C0B391C1672}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\HTTP">
|
||||
<UniqueIdentifier>{4C46FCD2-8942-35E4-A9F6-E32517A218FC}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{7607E023-D56D-300A-AAE7-35C1337C6EF3}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\HTTP\XMLHttp">
|
||||
<UniqueIdentifier>{9BC3BA0D-F317-3F19-87DD-76A8B0C73BEF}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{E77621FA-48B7-342B-A48A-7652D1F73D57}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Logger">
|
||||
<UniqueIdentifier>{F9631A84-9D6B-300A-B12D-A52D1FCE33D5}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{658327C4-885D-3CF1-9061-DA642B97898A}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Logger\Win">
|
||||
<UniqueIdentifier>{42447043-740A-346F-BF7B-15D083F4D78C}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{89A6373D-D2E3-3B5B-B6CF-4AB7CDFB13B8}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Mock">
|
||||
<UniqueIdentifier>{7E7975B0-87A8-3B63-AC39-F4B973EBFE5E}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{57AC3982-96A9-3B0B-A7DF-8DF69AD19ECC}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Task">
|
||||
<UniqueIdentifier>{A5C44A5C-F557-3485-B0F3-96924ED16997}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{075BEBE6-800C-3FB2-84E2-6443C472E199}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Task\Win">
|
||||
<UniqueIdentifier>{4075F186-2D52-323A-9287-AE69359740B8}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{D0B227E9-0B82-3AF7-82EC-9581DA9FD1A3}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\WebSocket">
|
||||
<UniqueIdentifier>{0EAC292A-EAC0-3C04-9776-AA439EE69493}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{0974FCD6-8409-3FA3-A118-A58ED0FD041C}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\WebSocket\WinRT">
|
||||
<UniqueIdentifier>{DA11A23D-43F8-30E7-A583-24AACCBE0501}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{E4F43182-9F97-3EBF-8BB9-4E51EB7E5C4D}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Public Includes">
|
||||
<UniqueIdentifier>{D805E6E3-877C-379F-9EEB-B64746DE0E67}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{2F64C9BE-5116-3E71-971F-592C0D76A89D}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
|
@ -150,6 +150,7 @@
|
|||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\Task\ThreadPool_win32.cpp" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer.h" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer_win32.cpp" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XAsyncProviderPriv.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XTaskQueuePriv.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\referenced_ptr.h" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\WebSocket\Websocketpp\websocketpp_websocket.cpp" />
|
||||
|
|
|
@ -138,6 +138,9 @@
|
|||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XAsyncProviderPriv.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XTaskQueuePriv.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
|
@ -183,46 +186,46 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="C++ Source">
|
||||
<UniqueIdentifier>{A740C412-FB5D-3AAA-8C89-79F901BDFCAA}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{AB68AAD7-BF0D-34C3-BFBA-FB7594810503}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Common">
|
||||
<UniqueIdentifier>{27CFE030-22C9-3F80-BE9E-6C85269BA8CF}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{8B9EEA6A-3165-3A83-8CEB-648270B8C445}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Common\Win">
|
||||
<UniqueIdentifier>{DFE90BE8-BA04-38D4-B957-489922F25F6C}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{28B59420-8446-3F26-9AB1-72123FF92816}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Global">
|
||||
<UniqueIdentifier>{3A5140CA-AFB5-3F07-934D-A8067647C112}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{A616C757-EB09-3284-8BA4-4C0B391C1672}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\HTTP">
|
||||
<UniqueIdentifier>{4C46FCD2-8942-35E4-A9F6-E32517A218FC}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{7607E023-D56D-300A-AAE7-35C1337C6EF3}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\HTTP\WinHttp">
|
||||
<UniqueIdentifier>{B97A6D17-B3B3-3752-AFCE-0EC15FD7B2D2}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{6095F35A-0F36-3DA9-8D1A-8F2DA598B6E0}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Logger">
|
||||
<UniqueIdentifier>{F9631A84-9D6B-300A-B12D-A52D1FCE33D5}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{658327C4-885D-3CF1-9061-DA642B97898A}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Logger\Win">
|
||||
<UniqueIdentifier>{42447043-740A-346F-BF7B-15D083F4D78C}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{89A6373D-D2E3-3B5B-B6CF-4AB7CDFB13B8}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Mock">
|
||||
<UniqueIdentifier>{7E7975B0-87A8-3B63-AC39-F4B973EBFE5E}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{57AC3982-96A9-3B0B-A7DF-8DF69AD19ECC}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Task">
|
||||
<UniqueIdentifier>{A5C44A5C-F557-3485-B0F3-96924ED16997}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{075BEBE6-800C-3FB2-84E2-6443C472E199}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Task\Win">
|
||||
<UniqueIdentifier>{4075F186-2D52-323A-9287-AE69359740B8}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{D0B227E9-0B82-3AF7-82EC-9581DA9FD1A3}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\WebSocket">
|
||||
<UniqueIdentifier>{0EAC292A-EAC0-3C04-9776-AA439EE69493}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{0974FCD6-8409-3FA3-A118-A58ED0FD041C}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\WebSocket\Win">
|
||||
<UniqueIdentifier>{35985716-80A2-3783-AE12-674A2189F43D}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{350A88A7-908E-346C-8EEC-8C500141D764}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Public Includes">
|
||||
<UniqueIdentifier>{D805E6E3-877C-379F-9EEB-B64746DE0E67}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{2F64C9BE-5116-3E71-971F-592C0D76A89D}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ApplicationEnvironment>title</ApplicationEnvironment>
|
||||
<ProjectGuid>{9E0EB8C2-40CD-448F-9B98-DAF9830EF9AD}</ProjectGuid>
|
||||
<ProjectGuid>{57C681F7-280F-45B8-9FA9-D556C24F2053}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectName>libHttpClient.142.XDK.C</ProjectName>
|
||||
<RootNamespace>xbox.httpclient</RootNamespace>
|
||||
|
|
|
@ -201,46 +201,46 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="C++ Source">
|
||||
<UniqueIdentifier>{A740C412-FB5D-3AAA-8C89-79F901BDFCAA}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{AB68AAD7-BF0D-34C3-BFBA-FB7594810503}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Common">
|
||||
<UniqueIdentifier>{27CFE030-22C9-3F80-BE9E-6C85269BA8CF}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{8B9EEA6A-3165-3A83-8CEB-648270B8C445}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Common\Win">
|
||||
<UniqueIdentifier>{DFE90BE8-BA04-38D4-B957-489922F25F6C}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{28B59420-8446-3F26-9AB1-72123FF92816}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Global">
|
||||
<UniqueIdentifier>{3A5140CA-AFB5-3F07-934D-A8067647C112}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{A616C757-EB09-3284-8BA4-4C0B391C1672}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\HTTP">
|
||||
<UniqueIdentifier>{4C46FCD2-8942-35E4-A9F6-E32517A218FC}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{7607E023-D56D-300A-AAE7-35C1337C6EF3}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\HTTP\XMLHttp">
|
||||
<UniqueIdentifier>{9BC3BA0D-F317-3F19-87DD-76A8B0C73BEF}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{E77621FA-48B7-342B-A48A-7652D1F73D57}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Logger">
|
||||
<UniqueIdentifier>{F9631A84-9D6B-300A-B12D-A52D1FCE33D5}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{658327C4-885D-3CF1-9061-DA642B97898A}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Logger\Win">
|
||||
<UniqueIdentifier>{42447043-740A-346F-BF7B-15D083F4D78C}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{89A6373D-D2E3-3B5B-B6CF-4AB7CDFB13B8}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Mock">
|
||||
<UniqueIdentifier>{7E7975B0-87A8-3B63-AC39-F4B973EBFE5E}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{57AC3982-96A9-3B0B-A7DF-8DF69AD19ECC}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Task">
|
||||
<UniqueIdentifier>{A5C44A5C-F557-3485-B0F3-96924ED16997}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{075BEBE6-800C-3FB2-84E2-6443C472E199}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\Task\Win">
|
||||
<UniqueIdentifier>{4075F186-2D52-323A-9287-AE69359740B8}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{D0B227E9-0B82-3AF7-82EC-9581DA9FD1A3}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\WebSocket">
|
||||
<UniqueIdentifier>{0EAC292A-EAC0-3C04-9776-AA439EE69493}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{0974FCD6-8409-3FA3-A118-A58ED0FD041C}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Source\WebSocket\WinRT">
|
||||
<UniqueIdentifier>{DA11A23D-43F8-30E7-A583-24AACCBE0501}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{E4F43182-9F97-3EBF-8BB9-4E51EB7E5C4D}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="C++ Public Includes">
|
||||
<UniqueIdentifier>{D805E6E3-877C-379F-9EEB-B64746DE0E67}</UniqueIdentifier>
|
||||
<UniqueIdentifier>{2F64C9BE-5116-3E71-971F-592C0D76A89D}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -157,6 +157,7 @@
|
|||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\Task\ThreadPool_win32.cpp" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer.h" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer_win32.cpp" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XAsyncProviderPriv.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XTaskQueuePriv.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\referenced_ptr.h" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\WebSocket\Unittest\websocket_unittest.cpp" />
|
||||
|
|
|
@ -159,6 +159,9 @@
|
|||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XAsyncProviderPriv.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XTaskQueuePriv.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
@ -221,6 +221,7 @@
|
|||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\Task\ThreadPool_win32.cpp" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer.h" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer_win32.cpp" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XAsyncProviderPriv.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XTaskQueuePriv.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\referenced_ptr.h" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\WebSocket\Unittest\websocket_unittest.cpp" />
|
||||
|
|
|
@ -156,6 +156,9 @@
|
|||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XAsyncProviderPriv.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XTaskQueuePriv.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectName>libHttpClient.UnitTest.142.TAEF</ProjectName>
|
||||
<ProjectGuid>{EBFE0314-0869-46B8-ABCE-A3EE223893B8}</ProjectGuid>
|
||||
<ProjectGuid>{9E0EB8C2-40CD-448F-9B98-DAF9830EF9AD}</ProjectGuid>
|
||||
<RootNamespace>libHttpClient.Test</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformMinVersion>10.0.10240.0</WindowsTargetPlatformMinVersion>
|
||||
|
@ -145,6 +145,7 @@
|
|||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\Task\ThreadPool_win32.cpp" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer.h" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer_win32.cpp" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XAsyncProviderPriv.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XTaskQueuePriv.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\referenced_ptr.h" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\WebSocket\Unittest\websocket_unittest.cpp" />
|
||||
|
|
|
@ -159,6 +159,9 @@
|
|||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XAsyncProviderPriv.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XTaskQueuePriv.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
@ -221,6 +221,7 @@
|
|||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\Task\ThreadPool_win32.cpp" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer.h" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer_win32.cpp" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XAsyncProviderPriv.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XTaskQueuePriv.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\referenced_ptr.h" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\Source\WebSocket\Unittest\websocket_unittest.cpp" />
|
||||
|
|
|
@ -156,6 +156,9 @@
|
|||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\WaitTimer.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XAsyncProviderPriv.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)..\..\Source\Task\XTaskQueuePriv.h">
|
||||
<Filter>C++ Source\Task</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
@ -113,36 +113,6 @@ STDAPI XAsyncBegin(
|
|||
_In_ XAsyncProvider* provider
|
||||
) noexcept;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes an async block for use. Once begun calls such
|
||||
/// as XAsyncGetStatus will provide meaningful data. It is assumed the
|
||||
/// async work will begin on some system defined thread after this call
|
||||
/// returns. The token and function parameters can be used to help identify
|
||||
/// mismatched Begin/GetResult calls. The token is typically the function
|
||||
/// pointer of the async API you are implementing, and the functionName parameter
|
||||
/// is typically the __FUNCTION__ compiler macro.
|
||||
///
|
||||
/// This variant of XAsyncBegin will allocate additional memory of size contextSize
|
||||
/// and use this as the context pointer for async provider callbacks. The memory
|
||||
/// pointer is returned in 'context'. The lifetime of this memory is managed
|
||||
/// by the async library and will be freed automatically when the call
|
||||
/// completes.
|
||||
/// </summary>
|
||||
/// <param name='asyncBlock'>A pointer to the XAsyncBlock that holds data for the call.</param>
|
||||
/// <param name='identity'>An optional arbitrary pointer that can be used to identify this call.</param>
|
||||
/// <param name='identityName'>An optional string that names the async call. This is typically the __FUNCTION__ compiler macro.</param>
|
||||
/// <param name='provider'>The function callback to invoke to implement the async call.</param>
|
||||
/// <param name='contextSize'>The size, in bytes, of additional context memory to allocate.</param>
|
||||
/// <param name='context'>The allocated context object pointer.</param>
|
||||
STDAPI XAsyncBeginAlloc(
|
||||
_Inout_ XAsyncBlock* asyncBlock,
|
||||
_In_opt_ const void* identity,
|
||||
_In_opt_ const char* identityName,
|
||||
_In_ XAsyncProvider* provider,
|
||||
_In_ size_t contextSize,
|
||||
_Out_ void** context
|
||||
) noexcept;
|
||||
|
||||
/// <summary>
|
||||
/// Schedules a callback to do async work. Calling this is optional. If the async work can be done
|
||||
/// through a system - async mechanism like overlapped IO or async COM, there is no need to schedule
|
||||
|
|
|
@ -18,3 +18,5 @@
|
|||
HC_TRACE_ERROR(HTTPCLIENT, fmt, ##__VA_ARGS__); \
|
||||
ASSERT(false); \
|
||||
|
||||
|
||||
#define FAIL_FAST_IF_FAILED(hr) do { HRESULT __hrRet = hr; if (FAILED(__hrRet)) { FAIL_FAST_MSG("%s 0x%08", #hr, __hrRet); }} while (0, 0)
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include <WinSock2.h>
|
||||
#include <windows.h>
|
||||
#include <objbase.h>
|
||||
|
||||
#else
|
||||
#define __STDC_LIMIT_MACROS
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#include "pch.h"
|
||||
#include "XTaskQueuePriv.h"
|
||||
|
||||
#define ASYNC_BLOCK_SIG 0x41535942 // ASYB
|
||||
#define ASYNC_STATE_SIG 0x41535445 // ASTE
|
||||
|
@ -9,6 +10,9 @@
|
|||
// Used by unit tests to verify we cleanup memory correctly.
|
||||
std::atomic<uint32_t> s_AsyncLibGlobalStateCount{ 0 };
|
||||
|
||||
// Set externally to enable pumping waits.
|
||||
bool s_AsyncLibEnablePumpingWait = false;
|
||||
|
||||
enum class ProviderCleanupLocation
|
||||
{
|
||||
Destructor,
|
||||
|
@ -42,6 +46,10 @@ struct AsyncState
|
|||
std::condition_variable waitCondition;
|
||||
bool waitSatisfied = false;
|
||||
|
||||
#if _WIN32
|
||||
HANDLE waitEvent = nullptr;
|
||||
#endif
|
||||
|
||||
const void* identity = nullptr;
|
||||
const char* identityName = nullptr;
|
||||
|
||||
|
@ -89,9 +97,17 @@ private:
|
|||
|
||||
if (queue != nullptr)
|
||||
{
|
||||
XTaskQueueResumeTermination(queue);
|
||||
XTaskQueueCloseHandle(queue);
|
||||
}
|
||||
|
||||
#if _WIN32
|
||||
if (waitEvent != nullptr)
|
||||
{
|
||||
CloseHandle(waitEvent);
|
||||
}
|
||||
#endif
|
||||
|
||||
--s_AsyncLibGlobalStateCount;
|
||||
}
|
||||
};
|
||||
|
@ -339,8 +355,8 @@ private:
|
|||
|
||||
static void CALLBACK CompletionCallback(_In_ void* context, _In_ bool canceled);
|
||||
static void CALLBACK WorkerCallback(_In_ void* context, _In_ bool canceled);
|
||||
static void SignalCompletion(_In_ AsyncStateRef const& state);
|
||||
static void SignalWait(_In_ AsyncStateRef const& state);
|
||||
static HRESULT SignalCompletion(_In_ AsyncStateRef const& state);
|
||||
static HRESULT AllocStateNoCompletion(_Inout_ XAsyncBlock* asyncBlock, _Inout_ AsyncBlockInternal* internal, _In_ size_t contextSize);
|
||||
static HRESULT AllocState(_Inout_ XAsyncBlock* asyncBlock, _In_ size_t contextSize);
|
||||
static void CleanupState(_Inout_ AsyncStateRef&& state);
|
||||
|
@ -368,9 +384,16 @@ static HRESULT AllocStateNoCompletion(_Inout_ XAsyncBlock* asyncBlock, _Inout_ A
|
|||
{
|
||||
RETURN_IF_FAILED(XTaskQueueDuplicateHandle(queue, &state->queue));
|
||||
}
|
||||
|
||||
|
||||
RETURN_IF_FAILED(XTaskQueueSuspendTermination(state->queue));
|
||||
|
||||
state->userAsyncBlock = asyncBlock;
|
||||
state->providerData.async = &state->providerAsyncBlock;
|
||||
|
||||
#if _WIN32
|
||||
state->waitEvent = CreateEvent(nullptr, TRUE, FALSE, nullptr);
|
||||
RETURN_LAST_ERROR_IF(state->waitEvent == nullptr);
|
||||
#endif
|
||||
|
||||
internal->state = state.Detach();
|
||||
|
||||
|
@ -437,12 +460,14 @@ static void CleanupProviderForLocation(_Inout_ AsyncStateRef& state, _In_ Provid
|
|||
}
|
||||
}
|
||||
|
||||
static void SignalCompletion(_In_ AsyncStateRef const& state)
|
||||
static HRESULT SignalCompletion(_In_ AsyncStateRef const& state)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
if (state->providerData.async->callback != nullptr)
|
||||
{
|
||||
AsyncStateRef callbackState(state.Get());
|
||||
HRESULT hr = XTaskQueueSubmitCallback(
|
||||
hr = XTaskQueueSubmitCallback(
|
||||
state->queue,
|
||||
XTaskQueuePort::Completion,
|
||||
callbackState.Get(),
|
||||
|
@ -457,6 +482,8 @@ static void SignalCompletion(_In_ AsyncStateRef const& state)
|
|||
{
|
||||
SignalWait(state);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static void SignalWait(_In_ AsyncStateRef const& state)
|
||||
|
@ -465,6 +492,9 @@ static void SignalWait(_In_ AsyncStateRef const& state)
|
|||
std::lock_guard<std::mutex> lock(state->waitMutex);
|
||||
state->waitSatisfied = true;
|
||||
}
|
||||
#if _WIN32
|
||||
SetEvent(state->waitEvent);
|
||||
#endif
|
||||
state->waitCondition.notify_all();
|
||||
}
|
||||
|
||||
|
@ -501,8 +531,6 @@ static void CALLBACK WorkerCallback(
|
|||
return;
|
||||
}
|
||||
|
||||
bool completedNow = false;
|
||||
|
||||
// If the queue is canceling callbacks, simply cancel this work. Since no
|
||||
// new work for this call will be scheduled, if the call didn't cancel
|
||||
// immediately do it ourselves.
|
||||
|
@ -536,20 +564,7 @@ static void CALLBACK WorkerCallback(
|
|||
result = E_UNEXPECTED;
|
||||
}
|
||||
|
||||
{
|
||||
AsyncBlockInternalGuard internal{ &state->providerAsyncBlock };
|
||||
completedNow = internal.TrySetTerminalStatus(result);
|
||||
|
||||
if (completedNow)
|
||||
{
|
||||
internal.ExtractState();
|
||||
}
|
||||
}
|
||||
|
||||
if (completedNow)
|
||||
{
|
||||
SignalCompletion(state);
|
||||
}
|
||||
XAsyncComplete(&state->providerAsyncBlock, result, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -557,11 +572,6 @@ static void CALLBACK WorkerCallback(
|
|||
// will change the provider cleanup to be "AfterWork", which is here. Cleanup
|
||||
// the provider if we need to.
|
||||
CleanupProviderForLocation(state, ProviderCleanupLocation::AfterDoWork);
|
||||
|
||||
if (completedNow)
|
||||
{
|
||||
CleanupState(std::move(state));
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -600,6 +610,27 @@ STDAPI XAsyncGetStatus(
|
|||
}
|
||||
else
|
||||
{
|
||||
// This codebase compiles for multiple platforms on GitHub. This is only
|
||||
// supported on win32 desktop platforms. It is enabled for Windows builds.
|
||||
#if _WIN32
|
||||
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
|
||||
|
||||
// If we're being asked to wait from a STA thread, use a CoWait to ensure we
|
||||
// don't totally gum up the thread. Then fall back to our normal condition
|
||||
// variable check (both are signaled during completion).
|
||||
|
||||
if (s_AsyncLibEnablePumpingWait)
|
||||
{
|
||||
APTTYPE aptType;
|
||||
APTTYPEQUALIFIER aptQualifier;
|
||||
if (SUCCEEDED(CoGetApartmentType(&aptType, &aptQualifier)) && aptType != APTTYPE_MTA && aptType != APTTYPE_NA)
|
||||
{
|
||||
DWORD idx;
|
||||
(void)CoWaitForMultipleHandles(COWAIT_DEFAULT, INFINITE, 1, &state->waitEvent, &idx);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(state->waitMutex);
|
||||
|
||||
|
@ -610,7 +641,10 @@ STDAPI XAsyncGetStatus(
|
|||
}
|
||||
}
|
||||
|
||||
result = XAsyncGetStatus(asyncBlock, false);
|
||||
{
|
||||
AsyncBlockInternalGuard internal{ asyncBlock };
|
||||
result = internal.GetStatus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -673,16 +707,30 @@ STDAPI XAsyncRun(
|
|||
__FUNCTION__,
|
||||
[](XAsyncOp op, const XAsyncProviderData* data)
|
||||
{
|
||||
if (op == XAsyncOp::DoWork)
|
||||
switch (op)
|
||||
{
|
||||
XAsyncWork* work = reinterpret_cast<XAsyncWork*>(data->context);
|
||||
HRESULT hr = work(data->async);
|
||||
XAsyncComplete(data->async, hr, 0);
|
||||
case XAsyncOp::Begin:
|
||||
return XAsyncSchedule(data->async, 0);
|
||||
|
||||
case XAsyncOp::DoWork:
|
||||
{
|
||||
XAsyncWork* work = reinterpret_cast<XAsyncWork*>(data->context);
|
||||
HRESULT hr = work(data->async);
|
||||
XAsyncComplete(data->async, hr, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case XAsyncOp::Cancel:
|
||||
case XAsyncOp::Cleanup:
|
||||
case XAsyncOp::GetResult:
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}));
|
||||
|
||||
RETURN_HR(XAsyncSchedule(asyncBlock, 0));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -718,7 +766,9 @@ STDAPI XAsyncBegin(
|
|||
|
||||
// We've successfully setup the call. Now kick off a
|
||||
// Begin opcode. If this call fails, we use it to fail
|
||||
// the async call, instead of failing XAsyncBegin.
|
||||
// the async call, instead of failing XAsyncBegin. This is
|
||||
// necessary to ensure that the async call state is properly
|
||||
// cleaned up, both for us and for the user call.
|
||||
|
||||
HRESULT hr = provider(XAsyncOp::Begin, &state->providerData);
|
||||
if (FAILED(hr))
|
||||
|
@ -750,10 +800,21 @@ STDAPI XAsyncBeginAlloc(
|
|||
_In_opt_ const char* identityName,
|
||||
_In_ XAsyncProvider* provider,
|
||||
_In_ size_t contextSize,
|
||||
_Out_ void** context
|
||||
_In_ size_t parameterBlockSize,
|
||||
_In_opt_ void* parameterBlock
|
||||
) noexcept
|
||||
{
|
||||
RETURN_HR_IF(E_INVALIDARG, contextSize == 0);
|
||||
|
||||
if (parameterBlockSize != 0)
|
||||
{
|
||||
RETURN_HR_IF(E_INVALIDARG, parameterBlock == nullptr || parameterBlockSize > contextSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
RETURN_HR_IF(E_INVALIDARG, parameterBlock != nullptr);
|
||||
}
|
||||
|
||||
RETURN_IF_FAILED(AllocState(asyncBlock, contextSize));
|
||||
|
||||
AsyncStateRef state;
|
||||
|
@ -772,13 +833,20 @@ STDAPI XAsyncBeginAlloc(
|
|||
|
||||
ASSERT(state->providerData.context != nullptr);
|
||||
memset(state->providerData.context, 0, contextSize);
|
||||
*context = state->providerData.context;
|
||||
|
||||
if (parameterBlockSize != 0)
|
||||
{
|
||||
memcpy(state->providerData.context, parameterBlock, parameterBlockSize);
|
||||
}
|
||||
|
||||
// We've successfully setup the call. Now kick off a
|
||||
// Begin opcode. If this call fails, we use it to fail
|
||||
// the async call, instead of failing XAsyncBegin.
|
||||
|
||||
// the async call, instead of failing XAsyncBegin. This is
|
||||
// necessary to ensure that the async call state is properly
|
||||
// cleaned up, both for us and for the user call.
|
||||
|
||||
HRESULT hr = provider(XAsyncOp::Begin, &state->providerData);
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
XAsyncComplete(asyncBlock, hr, 0);
|
||||
|
@ -865,7 +933,7 @@ STDAPI_(void) XAsyncComplete(
|
|||
// clean up now. Also clean up if the call failed. The caller should
|
||||
// have passed zero in here in that case but be tolerant for cases like
|
||||
// sizeof().
|
||||
if (requiredBufferSize == 0 || FAILED(result))
|
||||
if ((requiredBufferSize == 0 || FAILED(result)) && completedNow)
|
||||
{
|
||||
// If we are going to cleanup steal the reference from the block.
|
||||
doCleanup = true;
|
||||
|
@ -886,7 +954,7 @@ STDAPI_(void) XAsyncComplete(
|
|||
// Only signal / adjust needed buffer size if we were first to complete.
|
||||
if (completedNow)
|
||||
{
|
||||
SignalCompletion(state);
|
||||
FAIL_FAST_IF_FAILED(SignalCompletion(state));
|
||||
}
|
||||
|
||||
// At this point asyncBlock may be unsafe to touch. As we've cleaned up
|
||||
|
|
|
@ -271,6 +271,9 @@ HRESULT TaskQueuePortImpl::Initialize(
|
|||
m_terminationList.reset(new (std::nothrow) LocklessQueue<TerminationEntry*>(0));
|
||||
RETURN_IF_NULL_ALLOC(m_terminationList);
|
||||
|
||||
m_pendingTerminationList.reset(new (std::nothrow) LocklessQueue<TerminationEntry*>(*m_terminationList.get()));
|
||||
RETURN_IF_NULL_ALLOC(m_pendingTerminationList);
|
||||
|
||||
RETURN_IF_FAILED(m_timer.Initialize(this, [](void* context)
|
||||
{
|
||||
TaskQueuePortImpl* pthis = static_cast<TaskQueuePortImpl*>(context);
|
||||
|
@ -509,9 +512,31 @@ void __stdcall TaskQueuePortImpl::Terminate(
|
|||
_In_ void* token)
|
||||
{
|
||||
TerminationEntry* term = static_cast<TerminationEntry*>(token);
|
||||
|
||||
|
||||
// Prevent anything else from coming into the queue
|
||||
term->portContext->SetStatus(TaskQueuePortStatus::Terminated);
|
||||
|
||||
CancelPendingEntries(term->portContext, true);
|
||||
|
||||
// Are there existing suspends? AddSuspend returns
|
||||
// true if this is the first suspend added.
|
||||
if (term->portContext->AddSuspend())
|
||||
{
|
||||
ScheduleTermination(term);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pendingTerminationList->push_back(term, term->node);
|
||||
term->node = 0;
|
||||
}
|
||||
|
||||
// Balance our add
|
||||
term->portContext->RemoveSuspend();
|
||||
}
|
||||
|
||||
void __stdcall TaskQueuePortImpl::ScheduleTermination(
|
||||
_In_ TerminationEntry* term)
|
||||
{
|
||||
// Insert the termination callback into the queue. Even if the
|
||||
// main queue is empty, we still signal it and run through
|
||||
// a cycle. This ensures we flush the queue out with no
|
||||
|
@ -529,7 +554,6 @@ void __stdcall TaskQueuePortImpl::Terminate(
|
|||
// We will not signal until we are marked as terminated. The queue could
|
||||
// still be moving while we are running this terminate call.
|
||||
|
||||
term->portContext->SetStatus(TaskQueuePortStatus::Terminated);
|
||||
SignalQueue();
|
||||
|
||||
// We must ensure we poke the queue threads in case there's
|
||||
|
@ -683,6 +707,42 @@ bool __stdcall TaskQueuePortImpl::IsEmpty()
|
|||
return empty;
|
||||
}
|
||||
|
||||
HRESULT __stdcall TaskQueuePortImpl::SuspendTermination(
|
||||
_In_ ITaskQueuePortContext* portContext
|
||||
)
|
||||
{
|
||||
// This is necessary to ensure there is no race.
|
||||
portContext->AddSuspend();
|
||||
HRESULT hr = VerifyNotTerminated(portContext);
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
portContext->RemoveSuspend();
|
||||
RETURN_HR(hr);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void __stdcall TaskQueuePortImpl::ResumeTermination(
|
||||
_In_ ITaskQueuePortContext* portContext)
|
||||
{
|
||||
if (portContext->RemoveSuspend())
|
||||
{
|
||||
// Removed the last external callback. Look for
|
||||
// parked terminations and reschedule them.
|
||||
|
||||
TerminationEntry *entry;
|
||||
uint64_t address;
|
||||
|
||||
while (m_pendingTerminationList->pop_front(entry, address))
|
||||
{
|
||||
entry->node = address;
|
||||
ScheduleTermination(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT TaskQueuePortImpl::VerifyNotTerminated(
|
||||
_In_ ITaskQueuePortContext* portContext)
|
||||
{
|
||||
|
@ -1160,6 +1220,34 @@ void __stdcall TaskQueuePortContextImpl::ItemQueued()
|
|||
m_submitCallback->Invoke(m_type);
|
||||
}
|
||||
|
||||
bool __stdcall TaskQueuePortContextImpl::AddSuspend()
|
||||
{
|
||||
return (m_suspendCount.fetch_add(1) == 0);
|
||||
}
|
||||
|
||||
bool __stdcall TaskQueuePortContextImpl::RemoveSuspend()
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
uint32_t current = m_suspendCount.load();
|
||||
|
||||
// These should always be balanced and there is no
|
||||
// valid case where this should happen, even
|
||||
// for multiple therads racing.
|
||||
|
||||
if (current == 0)
|
||||
{
|
||||
ASSERT(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (m_suspendCount.compare_exchange_weak(current, current -1))
|
||||
{
|
||||
return current == 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// TaskQueueImpl
|
||||
//
|
||||
|
@ -1613,7 +1701,8 @@ STDAPI XTaskQueueSubmitDelayedCallback(
|
|||
referenced_ptr<ITaskQueuePortContext> portContext;
|
||||
RETURN_IF_FAILED(aq->GetPortContext(port, portContext.address_of()));
|
||||
|
||||
RETURN_HR(portContext->GetPort()->QueueItem(portContext.get(), delayMs, callbackContext, callback));
|
||||
RETURN_IF_FAILED(portContext->GetPort()->QueueItem(portContext.get(), delayMs, callbackContext, callback));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -1691,7 +1780,8 @@ STDAPI XTaskQueueRegisterMonitor(
|
|||
{
|
||||
referenced_ptr<ITaskQueue> aq(GetQueue(queue));
|
||||
RETURN_HR_IF(E_INVALIDARG, aq == nullptr);
|
||||
RETURN_HR(aq->RegisterSubmitCallback(callbackContext, callback, token));
|
||||
RETURN_IF_FAILED(aq->RegisterSubmitCallback(callbackContext, callback, token));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -1795,3 +1885,45 @@ STDAPI_(void) XTaskQueueSetCurrentProcessTaskQueue(
|
|||
XTaskQueueCloseHandle(previous);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Submits a callback that will be invoked asynchronously via some external
|
||||
// system. This is used to prevent queue termination while other work
|
||||
// is happening.
|
||||
//
|
||||
STDAPI XTaskQueueSuspendTermination(
|
||||
_In_ XTaskQueueHandle queue
|
||||
) noexcept
|
||||
{
|
||||
referenced_ptr<ITaskQueue> aq(GetQueue(queue));
|
||||
RETURN_HR_IF(E_INVALIDARG, aq == nullptr);
|
||||
|
||||
referenced_ptr<ITaskQueuePortContext> portContext;
|
||||
RETURN_IF_FAILED(aq->GetPortContext(XTaskQueuePort::Work, portContext.address_of()));
|
||||
|
||||
RETURN_IF_FAILED(portContext->GetPort()->SuspendTermination(portContext.get()));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
//
|
||||
// Tells the queue that a previously submitted external callback
|
||||
// has been dispatched.
|
||||
//
|
||||
STDAPI_(void) XTaskQueueResumeTermination(
|
||||
_In_ XTaskQueueHandle queue
|
||||
) noexcept
|
||||
{
|
||||
referenced_ptr<ITaskQueue> aq(GetQueue(queue));
|
||||
if (aq == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
referenced_ptr<ITaskQueuePortContext> portContext;
|
||||
if (FAILED(aq->GetPortContext(XTaskQueuePort::Work, portContext.address_of())))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
portContext->GetPort()->ResumeTermination(portContext.get());
|
||||
}
|
||||
|
|
|
@ -202,6 +202,12 @@ public:
|
|||
|
||||
bool __stdcall IsEmpty();
|
||||
|
||||
HRESULT __stdcall SuspendTermination(
|
||||
_In_ ITaskQueuePortContext* portContext);
|
||||
|
||||
void __stdcall ResumeTermination(
|
||||
_In_ ITaskQueuePortContext* portContext);
|
||||
|
||||
private:
|
||||
|
||||
struct WaitRegistration;
|
||||
|
@ -246,6 +252,7 @@ private:
|
|||
std::unique_ptr<LocklessQueue<QueueEntry>> m_queueList;
|
||||
std::unique_ptr<LocklessQueue<QueueEntry>> m_pendingList;
|
||||
std::unique_ptr<LocklessQueue<TerminationEntry*>> m_terminationList;
|
||||
std::unique_ptr<LocklessQueue<TerminationEntry*>> m_pendingTerminationList;
|
||||
OS::WaitTimer m_timer;
|
||||
OS::ThreadPool m_threadPool;
|
||||
std::atomic<uint64_t> m_timerDue = { UINT64_MAX };
|
||||
|
@ -285,6 +292,7 @@ private:
|
|||
void SubmitPendingCallback();
|
||||
|
||||
void SignalTerminations();
|
||||
void ScheduleTermination(_In_ TerminationEntry* term);
|
||||
|
||||
void SignalQueue();
|
||||
|
||||
|
@ -339,6 +347,9 @@ public:
|
|||
|
||||
void __stdcall ItemQueued() override;
|
||||
|
||||
bool __stdcall AddSuspend() override;
|
||||
bool __stdcall RemoveSuspend() override;
|
||||
|
||||
referenced_ptr<ITaskQueuePort> Port;
|
||||
referenced_ptr<ITaskQueue> Source;
|
||||
|
||||
|
@ -348,6 +359,7 @@ private:
|
|||
XTaskQueuePort m_type = XTaskQueuePort::Work;
|
||||
SubmitCallback* m_submitCallback = nullptr;
|
||||
std::atomic<TaskQueuePortStatus> m_status = { TaskQueuePortStatus::Active };
|
||||
std::atomic<uint32_t> m_suspendCount = { 0 };
|
||||
};
|
||||
|
||||
class TaskQueueImpl : public Api<ApiId::TaskQueue, ITaskQueue>
|
||||
|
|
|
@ -67,12 +67,18 @@ struct ITaskQueuePort: IApi
|
|||
_In_ ITaskQueuePortContext* portContext) = 0;
|
||||
|
||||
virtual bool __stdcall DrainOneItem() = 0;
|
||||
|
||||
|
||||
virtual bool __stdcall Wait(
|
||||
_In_ ITaskQueuePortContext* portContext,
|
||||
_In_ uint32_t timeout) = 0;
|
||||
|
||||
virtual bool __stdcall IsEmpty() = 0;
|
||||
|
||||
virtual HRESULT __stdcall SuspendTermination(
|
||||
_In_ ITaskQueuePortContext* portContext) = 0;
|
||||
|
||||
virtual void __stdcall ResumeTermination(
|
||||
_In_ ITaskQueuePortContext* portContext) = 0;
|
||||
};
|
||||
|
||||
// The status of a port on the queue.
|
||||
|
@ -102,6 +108,9 @@ struct ITaskQueuePortContext : IApi
|
|||
_In_ TaskQueuePortStatus status) = 0;
|
||||
|
||||
virtual void __stdcall ItemQueued() = 0;
|
||||
|
||||
virtual bool __stdcall AddSuspend() = 0;
|
||||
virtual bool __stdcall RemoveSuspend() = 0;
|
||||
};
|
||||
|
||||
// The task queue. The public flat API is built entirely on
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
// Copyright(c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// These APIs should be reserved for driving unit test harnesses.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "XAsyncProvider.h"
|
||||
|
||||
/// <summary>
|
||||
/// Initializes an async block for use. Once begun calls such
|
||||
/// as XAsyncGetStatus will provide meaningful data. It is assumed the
|
||||
/// async work will begin on some system defined thread after this call
|
||||
/// returns. The token and function parameters can be used to help identify
|
||||
/// mismatched Begin/GetResult calls. The token is typically the function
|
||||
/// pointer of the async API you are implementing, and the functionName parameter
|
||||
/// is typically the __FUNCTION__ compiler macro.
|
||||
///
|
||||
/// This variant of XAsyncBegin will allocate additional memory of size contextSize
|
||||
/// and use this as the context pointer for async provider callbacks. The memory
|
||||
/// pointer is returned in 'context'. The lifetime of this memory is managed
|
||||
/// by the async library and will be freed automatically when the call
|
||||
/// completes.
|
||||
/// </summary>
|
||||
/// <param name='asyncBlock'>A pointer to the XAsyncBlock that holds data for the call.</param>
|
||||
/// <param name='identity'>An optional arbitrary pointer that can be used to identify this call.</param>
|
||||
/// <param name='identityName'>An optional string that names the async call. This is typically the __FUNCTION__ compiler macro.</param>
|
||||
/// <param name='provider'>The function callback to invoke to implement the async call.</param>
|
||||
/// <param name='contextSize'>The size, in bytes, of additional context memory to allocate.</param>
|
||||
/// <param name='parameterBlockSize'>The size of a parameter block to copy into the allocated context.</param>
|
||||
/// <param name='parameterBlock'>The parameter block to copy. This will be copied into the allocated context.</param>
|
||||
STDAPI XAsyncBeginAlloc(
|
||||
_Inout_ XAsyncBlock* asyncBlock,
|
||||
_In_opt_ const void* identity,
|
||||
_In_opt_ const char* identityName,
|
||||
_In_ XAsyncProvider* provider,
|
||||
_In_ size_t contextSize,
|
||||
_In_ size_t parameterBlockSize,
|
||||
_In_opt_ void* parameterBlock
|
||||
) noexcept;
|
|
@ -14,4 +14,23 @@
|
|||
/// <param name='port'>The port to check.</param>
|
||||
STDAPI_(bool) XTaskQueueIsEmpty(
|
||||
_In_ XTaskQueueHandle queue,
|
||||
_In_ XTaskQueuePort port);
|
||||
_In_ XTaskQueuePort port
|
||||
) noexcept;
|
||||
|
||||
/// <summary>
|
||||
/// Suspends terminations on the task queue. May return an error if
|
||||
/// the queue is already terminated.
|
||||
/// </summary>
|
||||
/// <param name='queue'>The queue to suspend terminations.</param>
|
||||
STDAPI XTaskQueueSuspendTermination(
|
||||
_In_ XTaskQueueHandle queue
|
||||
) noexcept;
|
||||
|
||||
/// <summary>
|
||||
/// Resumes the ability to terminate the task queue. If a termination was
|
||||
/// attempted it will be continued.
|
||||
/// </summary>
|
||||
/// <param name='queue'>The queue resume terminations.</param>
|
||||
STDAPI_(void) XTaskQueueResumeTermination(
|
||||
_In_ XTaskQueueHandle queue
|
||||
) noexcept;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "UnitTestIncludes.h"
|
||||
#include "XAsync.h"
|
||||
#include "XAsyncProvider.h"
|
||||
#include "XAsyncProviderPriv.h"
|
||||
#include "XTaskQueue.h"
|
||||
#include "XTaskQueuePriv.h"
|
||||
|
||||
|
@ -71,7 +72,7 @@ DEFINE_TEST_CLASS(AsyncBlockTests)
|
|||
private:
|
||||
|
||||
XTaskQueueHandle queue = nullptr;
|
||||
|
||||
|
||||
struct FactorialCallData
|
||||
{
|
||||
DWORD value = 0;
|
||||
|
@ -219,6 +220,32 @@ private:
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT CALLBACK FactorialWorkerDistributedWithSchedule(XAsyncOp opCode, const XAsyncProviderData* data)
|
||||
{
|
||||
if (opCode == XAsyncOp::Begin)
|
||||
{
|
||||
FactorialCallData* d = (FactorialCallData*)data->context;
|
||||
|
||||
// leak a ref on this guy so we don't try to free it. We need
|
||||
// to do two addrefs because a new object starts with refcount
|
||||
// of zero. The factorial async process will addref/release so
|
||||
// we need two to "leak" it (not really leaked; the memory is
|
||||
// owned by the async logic)
|
||||
|
||||
d->AddRef();
|
||||
d->AddRef();
|
||||
}
|
||||
|
||||
HRESULT hr = FactorialWorkerDistributed(opCode, data);
|
||||
|
||||
if (SUCCEEDED(hr) && opCode == XAsyncOp::Begin)
|
||||
{
|
||||
hr = XAsyncSchedule(data->async, 0);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT FactorialAsync(FactorialCallData* data, XAsyncBlock* async)
|
||||
{
|
||||
HRESULT hr = XAsyncBegin(async, data, FactorialAsync, __FUNCTION__, FactorialWorkerSimple);
|
||||
|
@ -241,23 +268,7 @@ private:
|
|||
|
||||
static HRESULT FactorialAllocateAsync(DWORD value, XAsyncBlock* async)
|
||||
{
|
||||
void* context;
|
||||
HRESULT hr = XAsyncBeginAlloc(async, FactorialAsync, __FUNCTION__, FactorialWorkerDistributed, sizeof(FactorialCallData), &context);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
FactorialCallData* data = new (context) FactorialCallData;
|
||||
data->value = value;
|
||||
|
||||
// leak a ref on this guy so we don't try to free it. We need
|
||||
// to do two addrefs because a new object starts with refcount
|
||||
// of zero. The factorial async process will addref/release so
|
||||
// we need two to "leak" it (not really leaked; the memory is
|
||||
// owned by the async logic)
|
||||
|
||||
data->AddRef();
|
||||
data->AddRef();
|
||||
hr = XAsyncSchedule(async, 0);
|
||||
}
|
||||
HRESULT hr = XAsyncBeginAlloc(async, FactorialAsync, __FUNCTION__, FactorialWorkerDistributedWithSchedule, sizeof(FactorialCallData), sizeof(DWORD), &value);
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
@ -342,6 +353,7 @@ public:
|
|||
AsyncBlockTests::~AsyncBlockTests()
|
||||
{
|
||||
VERIFY_ARE_EQUAL(s_AsyncLibGlobalStateCount, (DWORD)0);
|
||||
XTaskQueueTerminate(queue, true, nullptr, nullptr);
|
||||
XTaskQueueCloseHandle(queue);
|
||||
}
|
||||
|
||||
|
@ -987,4 +999,58 @@ public:
|
|||
VERIFY_SUCCEEDED(XAsyncGetStatus(&async, true));
|
||||
VERIFY_ARE_EQUAL((DWORD)WAIT_OBJECT_0, WaitForSingleObject(context.evt, 2500));
|
||||
}
|
||||
|
||||
DEFINE_TEST_CASE(VerifyBeginAfterTerminate)
|
||||
{
|
||||
XAsyncBlock async{};
|
||||
VERIFY_SUCCEEDED(XTaskQueueCreate(XTaskQueueDispatchMode::ThreadPool, XTaskQueueDispatchMode::ThreadPool, &async.queue));
|
||||
|
||||
auto provider = [](XAsyncOp, const XAsyncProviderData*)
|
||||
{
|
||||
return S_OK;
|
||||
};
|
||||
|
||||
// Terminate the queue
|
||||
XTaskQueueTerminate(async.queue, true, nullptr, nullptr);
|
||||
|
||||
// XAsyncBegin should fail early with an abort.
|
||||
VERIFY_ARE_EQUAL(E_ABORT, XAsyncBegin(&async, nullptr, nullptr, nullptr, provider));
|
||||
|
||||
XTaskQueueCloseHandle(async.queue);
|
||||
}
|
||||
|
||||
DEFINE_TEST_CASE(VerifyFailureInDoWork)
|
||||
{
|
||||
XAsyncBlock async{};
|
||||
VERIFY_SUCCEEDED(XTaskQueueCreate(XTaskQueueDispatchMode::ThreadPool, XTaskQueueDispatchMode::ThreadPool, &async.queue));
|
||||
|
||||
constexpr static HRESULT hrSpecial = 0x8009ABCD;
|
||||
|
||||
auto provider = [](XAsyncOp op, const XAsyncProviderData* data)
|
||||
{
|
||||
switch(op)
|
||||
{
|
||||
case XAsyncOp::Begin:
|
||||
return XAsyncSchedule(data->async, 0);
|
||||
|
||||
case XAsyncOp::Cleanup:
|
||||
break;
|
||||
|
||||
case XAsyncOp::DoWork:
|
||||
return hrSpecial;
|
||||
|
||||
default:
|
||||
VERIFY_FAIL();
|
||||
break;
|
||||
}
|
||||
return S_OK;
|
||||
};
|
||||
|
||||
// Ensure that the call runs through and correctly reports our special
|
||||
// error.
|
||||
VERIFY_SUCCEEDED(XAsyncBegin(&async, nullptr, nullptr, nullptr, provider));
|
||||
VERIFY_ARE_EQUAL(hrSpecial, XAsyncGetStatus(&async, true));
|
||||
|
||||
XTaskQueueCloseHandle(async.queue);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -110,6 +110,11 @@ public:
|
|||
|
||||
TEST_CLASS_CLEANUP(ClassCleanup)
|
||||
{
|
||||
//
|
||||
// Note: this is a global refcount for tracking
|
||||
// leaks in the task queue. If any other tests fail
|
||||
// this may also fail, as those tests could have leaked.
|
||||
//
|
||||
uint32_t gr = ApiDiag::g_globalApiRefs;
|
||||
VERIFY_ARE_EQUAL(0u, gr);
|
||||
return true;
|
||||
|
@ -1184,4 +1189,28 @@ public:
|
|||
NextStep(&step, 7, L"Closing outer queue");
|
||||
XTaskQueueCloseHandle(outer.Release());
|
||||
}
|
||||
|
||||
DEFINE_TEST_CASE(VerifyTerminateWaitsForSuspends)
|
||||
{
|
||||
AutoQueueHandle queue;
|
||||
VERIFY_SUCCEEDED(XTaskQueueCreate(XTaskQueueDispatchMode::ThreadPool, XTaskQueueDispatchMode::ThreadPool, &queue));
|
||||
|
||||
AutoHandle waitHandle = CreateEvent(nullptr, TRUE, FALSE, nullptr);
|
||||
VERIFY_IS_NOT_NULL(waitHandle);
|
||||
|
||||
auto terminatedCallback = [](void* context)
|
||||
{
|
||||
HANDLE h = (HANDLE)context;
|
||||
SetEvent(h);
|
||||
};
|
||||
|
||||
VERIFY_SUCCEEDED(XTaskQueueSuspendTermination(queue));
|
||||
VERIFY_SUCCEEDED(XTaskQueueTerminate(queue, false, waitHandle.Handle(), terminatedCallback));
|
||||
|
||||
VERIFY_ARE_EQUAL((DWORD)WAIT_TIMEOUT, WaitForSingleObject(waitHandle, 2000));
|
||||
|
||||
XTaskQueueResumeTermination(queue);
|
||||
|
||||
VERIFY_ARE_EQUAL((DWORD)WAIT_OBJECT_0, WaitForSingleObject(waitHandle, 2000));
|
||||
}
|
||||
};
|
||||
|
|
|
@ -107,6 +107,7 @@ set(Task_Source_Files
|
|||
../../../Source/Task/ThreadPool.h
|
||||
../../../Source/Task/WaitTimer.h
|
||||
../../../Source/Task/XTaskQueuePriv.h
|
||||
../../../Source/Task/XAsyncProviderPriv.h
|
||||
)
|
||||
|
||||
set(Task_Windows_Source_Files
|
||||
|
|
Загрузка…
Ссылка в новой задаче