mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-02 08:55:53 +00:00
beast, beast::asio improvements and fixes:
* New maybe_const_t alias for maybe_const * New asio::enable_wait_for_async for safe cleanup * New asio::memory_buffer, a managed boost::asio compatible buffer * shared_handler improvements: - Can be 'empty' (no stored handler). - Default constructible as 'empty'. - Safe evaluation in bool contexts, false==empty * Fix is_call_possible metafunction: - Works on empty argument lists - Works with reference types * Replace SafeBool idiom with C++11 explicit operator bool * Move IPAddress function definitions to the header * Move cyclic_iterator to container/ * Remove unused BufferType * Remove obsolete classes: - NamedPipe - ReadWriteLock - ScopedReadLock - ScopedWriteLock - LockGuard
This commit is contained in:
@@ -21,6 +21,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="..\..\.gitattributes" />
|
<None Include="..\..\.gitattributes" />
|
||||||
<None Include="..\..\.gitignore" />
|
<None Include="..\..\.gitignore" />
|
||||||
|
<None Include="..\..\beast\asio\README.md" />
|
||||||
<None Include="..\..\beast\crypto\impl\sha2\README" />
|
<None Include="..\..\beast\crypto\impl\sha2\README" />
|
||||||
<None Include="..\..\beast\crypto\impl\sha2\sha2test.pl" />
|
<None Include="..\..\beast\crypto\impl\sha2\sha2test.pl" />
|
||||||
<None Include="..\..\beast\http\impl\http-parser\.gitignore" />
|
<None Include="..\..\beast\http\impl\http-parser\.gitignore" />
|
||||||
@@ -86,8 +87,10 @@
|
|||||||
<ClInclude Include="..\..\beast\asio\abstract_socket.h" />
|
<ClInclude Include="..\..\beast\asio\abstract_socket.h" />
|
||||||
<ClInclude Include="..\..\beast\asio\bind_handler.h" />
|
<ClInclude Include="..\..\beast\asio\bind_handler.h" />
|
||||||
<ClInclude Include="..\..\beast\asio\buffer_sequence.h" />
|
<ClInclude Include="..\..\beast\asio\buffer_sequence.h" />
|
||||||
|
<ClInclude Include="..\..\beast\asio\enable_wait_for_async.h" />
|
||||||
<ClInclude Include="..\..\beast\asio\io_latency_probe.h" />
|
<ClInclude Include="..\..\beast\asio\io_latency_probe.h" />
|
||||||
<ClInclude Include="..\..\beast\asio\IPAddressConversion.h" />
|
<ClInclude Include="..\..\beast\asio\IPAddressConversion.h" />
|
||||||
|
<ClInclude Include="..\..\beast\asio\memory_buffer.h" />
|
||||||
<ClInclude Include="..\..\beast\asio\placeholders.h" />
|
<ClInclude Include="..\..\beast\asio\placeholders.h" />
|
||||||
<ClInclude Include="..\..\beast\asio\shared_handler.h" />
|
<ClInclude Include="..\..\beast\asio\shared_handler.h" />
|
||||||
<ClInclude Include="..\..\beast\asio\socket_wrapper.h" />
|
<ClInclude Include="..\..\beast\asio\socket_wrapper.h" />
|
||||||
@@ -133,6 +136,7 @@
|
|||||||
<ClInclude Include="..\..\beast\container\aged_unordered_multimap.h" />
|
<ClInclude Include="..\..\beast\container\aged_unordered_multimap.h" />
|
||||||
<ClInclude Include="..\..\beast\container\aged_unordered_multiset.h" />
|
<ClInclude Include="..\..\beast\container\aged_unordered_multiset.h" />
|
||||||
<ClInclude Include="..\..\beast\container\aged_unordered_set.h" />
|
<ClInclude Include="..\..\beast\container\aged_unordered_set.h" />
|
||||||
|
<ClInclude Include="..\..\beast\container\cyclic_iterator.h" />
|
||||||
<ClInclude Include="..\..\beast\container\detail\aged_associative_container.h" />
|
<ClInclude Include="..\..\beast\container\detail\aged_associative_container.h" />
|
||||||
<ClInclude Include="..\..\beast\container\detail\aged_ordered_container.h" />
|
<ClInclude Include="..\..\beast\container\detail\aged_ordered_container.h" />
|
||||||
<ClInclude Include="..\..\beast\container\detail\aged_container_iterator.h" />
|
<ClInclude Include="..\..\beast\container\detail\aged_container_iterator.h" />
|
||||||
@@ -152,7 +156,6 @@
|
|||||||
<ClInclude Include="..\..\beast\cxx14\memory.h" />
|
<ClInclude Include="..\..\beast\cxx14\memory.h" />
|
||||||
<ClInclude Include="..\..\beast\cxx14\type_traits.h" />
|
<ClInclude Include="..\..\beast\cxx14\type_traits.h" />
|
||||||
<ClInclude Include="..\..\beast\cxx14\utility.h" />
|
<ClInclude Include="..\..\beast\cxx14\utility.h" />
|
||||||
<ClInclude Include="..\..\beast\cyclic_iterator.h" />
|
|
||||||
<ClInclude Include="..\..\beast\FixedArray.h" />
|
<ClInclude Include="..\..\beast\FixedArray.h" />
|
||||||
<ClInclude Include="..\..\beast\HeapBlock.h" />
|
<ClInclude Include="..\..\beast\HeapBlock.h" />
|
||||||
<ClInclude Include="..\..\beast\HTTP.h" />
|
<ClInclude Include="..\..\beast\HTTP.h" />
|
||||||
@@ -185,14 +188,12 @@
|
|||||||
<ClInclude Include="..\..\beast\MPL.h" />
|
<ClInclude Include="..\..\beast\MPL.h" />
|
||||||
<ClInclude Include="..\..\beast\mpl\IsCallPossible.h" />
|
<ClInclude Include="..\..\beast\mpl\IsCallPossible.h" />
|
||||||
<ClInclude Include="..\..\beast\Net.h" />
|
<ClInclude Include="..\..\beast\Net.h" />
|
||||||
<ClInclude Include="..\..\beast\net\BufferType.h" />
|
|
||||||
<ClInclude Include="..\..\beast\net\detail\Parse.h" />
|
<ClInclude Include="..\..\beast\net\detail\Parse.h" />
|
||||||
<ClInclude Include="..\..\beast\net\DynamicBuffer.h" />
|
<ClInclude Include="..\..\beast\net\DynamicBuffer.h" />
|
||||||
<ClInclude Include="..\..\beast\net\IPAddress.h" />
|
<ClInclude Include="..\..\beast\net\IPAddress.h" />
|
||||||
<ClInclude Include="..\..\beast\net\IPAddressV4.h" />
|
<ClInclude Include="..\..\beast\net\IPAddressV4.h" />
|
||||||
<ClInclude Include="..\..\beast\net\IPAddressV6.h" />
|
<ClInclude Include="..\..\beast\net\IPAddressV6.h" />
|
||||||
<ClInclude Include="..\..\beast\net\IPEndpoint.h" />
|
<ClInclude Include="..\..\beast\net\IPEndpoint.h" />
|
||||||
<ClInclude Include="..\..\beast\SafeBool.h" />
|
|
||||||
<ClInclude Include="..\..\beast\SmartPtr.h" />
|
<ClInclude Include="..\..\beast\SmartPtr.h" />
|
||||||
<ClInclude Include="..\..\beast\smart_ptr\AbstractObject.h" />
|
<ClInclude Include="..\..\beast\smart_ptr\AbstractObject.h" />
|
||||||
<ClInclude Include="..\..\beast\smart_ptr\ContainerDeletePolicy.h" />
|
<ClInclude Include="..\..\beast\smart_ptr\ContainerDeletePolicy.h" />
|
||||||
@@ -214,7 +215,6 @@
|
|||||||
<ClInclude Include="..\..\beast\Chrono.h" />
|
<ClInclude Include="..\..\beast\Chrono.h" />
|
||||||
<ClInclude Include="..\..\beast\threads\detail\BindHandler.h" />
|
<ClInclude Include="..\..\beast\threads\detail\BindHandler.h" />
|
||||||
<ClInclude Include="..\..\beast\threads\detail\DispatchedHandler.h" />
|
<ClInclude Include="..\..\beast\threads\detail\DispatchedHandler.h" />
|
||||||
<ClInclude Include="..\..\beast\threads\LockGuard.h" />
|
|
||||||
<ClInclude Include="..\..\beast\threads\RecursiveMutex.h" />
|
<ClInclude Include="..\..\beast\threads\RecursiveMutex.h" />
|
||||||
<ClInclude Include="..\..\beast\threads\semaphore.h" />
|
<ClInclude Include="..\..\beast\threads\semaphore.h" />
|
||||||
<ClInclude Include="..\..\beast\threads\ServiceQueue.h" />
|
<ClInclude Include="..\..\beast\threads\ServiceQueue.h" />
|
||||||
@@ -333,7 +333,6 @@
|
|||||||
<ClInclude Include="..\..\modules\beast_core\native\posix_SharedCode.h" />
|
<ClInclude Include="..\..\modules\beast_core\native\posix_SharedCode.h" />
|
||||||
<ClInclude Include="..\..\modules\beast_core\native\win32_ComSmartPtr.h" />
|
<ClInclude Include="..\..\modules\beast_core\native\win32_ComSmartPtr.h" />
|
||||||
<ClInclude Include="..\..\modules\beast_core\network\MACAddress.h" />
|
<ClInclude Include="..\..\modules\beast_core\network\MACAddress.h" />
|
||||||
<ClInclude Include="..\..\modules\beast_core\network\NamedPipe.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\network\Socket.h" />
|
<ClInclude Include="..\..\modules\beast_core\network\Socket.h" />
|
||||||
<ClInclude Include="..\..\modules\beast_core\streams\BufferedInputStream.h" />
|
<ClInclude Include="..\..\modules\beast_core\streams\BufferedInputStream.h" />
|
||||||
<ClInclude Include="..\..\modules\beast_core\streams\FileInputSource.h" />
|
<ClInclude Include="..\..\modules\beast_core\streams\FileInputSource.h" />
|
||||||
@@ -362,10 +361,7 @@
|
|||||||
<ClInclude Include="..\..\modules\beast_core\threads\HighResolutionTimer.h" />
|
<ClInclude Include="..\..\modules\beast_core\threads\HighResolutionTimer.h" />
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\InterProcessLock.h" />
|
<ClInclude Include="..\..\modules\beast_core\threads\InterProcessLock.h" />
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\Process.h" />
|
<ClInclude Include="..\..\modules\beast_core\threads\Process.h" />
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\ReadWriteLock.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\ScopedLock.h" />
|
<ClInclude Include="..\..\modules\beast_core\threads\ScopedLock.h" />
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\ScopedReadLock.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\ScopedWriteLock.h" />
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\SpinDelay.h" />
|
<ClInclude Include="..\..\modules\beast_core\threads\SpinDelay.h" />
|
||||||
<ClInclude Include="..\..\modules\beast_core\thread\DeadlineTimer.h" />
|
<ClInclude Include="..\..\modules\beast_core\thread\DeadlineTimer.h" />
|
||||||
<ClInclude Include="..\..\modules\beast_core\thread\Workers.h" />
|
<ClInclude Include="..\..\modules\beast_core\thread\Workers.h" />
|
||||||
@@ -433,6 +429,30 @@
|
|||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\beast\asio\tests\bind_handler_tests.cpp">
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\beast\asio\tests\enable_wait_for_async.test.cpp">
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\beast\asio\tests\shared_handler_tests.cpp">
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\beast\asio\tests\wrap_handler_tests.cpp">
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\beast\boost\Boost.cpp" />
|
<ClCompile Include="..\..\beast\boost\Boost.cpp" />
|
||||||
<ClCompile Include="..\..\beast\chrono\Chrono.cpp" />
|
<ClCompile Include="..\..\beast\chrono\Chrono.cpp" />
|
||||||
<ClCompile Include="..\..\beast\chrono\impl\basic_seconds_clock.cpp">
|
<ClCompile Include="..\..\beast\chrono\impl\basic_seconds_clock.cpp">
|
||||||
@@ -1115,12 +1135,6 @@
|
|||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\modules\beast_core\native\posix_NamedPipe.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\native\win32_Files.cpp">
|
<ClCompile Include="..\..\modules\beast_core\native\win32_Files.cpp">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||||
@@ -1163,12 +1177,6 @@
|
|||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\modules\beast_core\network\NamedPipe.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\network\Socket.cpp">
|
<ClCompile Include="..\..\modules\beast_core\network\Socket.cpp">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||||
@@ -1277,12 +1285,6 @@
|
|||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\modules\beast_core\threads\ReadWriteLock.cpp">
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\threads\SpinDelay.cpp">
|
<ClCompile Include="..\..\modules\beast_core\threads\SpinDelay.cpp">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||||
|
|||||||
@@ -76,6 +76,9 @@
|
|||||||
<None Include="..\..\scripts\compile.sh">
|
<None Include="..\..\scripts\compile.sh">
|
||||||
<Filter>scripts</Filter>
|
<Filter>scripts</Filter>
|
||||||
</None>
|
</None>
|
||||||
|
<None Include="..\..\beast\asio\README.md">
|
||||||
|
<Filter>beast\asio</Filter>
|
||||||
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Filter Include="beast_core">
|
<Filter Include="beast_core">
|
||||||
@@ -309,6 +312,9 @@
|
|||||||
<Filter Include="beast\cxx14\tests">
|
<Filter Include="beast\cxx14\tests">
|
||||||
<UniqueIdentifier>{1271ee71-5754-46ef-845b-84e53eed11c0}</UniqueIdentifier>
|
<UniqueIdentifier>{1271ee71-5754-46ef-845b-84e53eed11c0}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="beast\asio\tests">
|
||||||
|
<UniqueIdentifier>{f2594738-6447-447b-8f51-2d42fbe8a6ee}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\modules\beast_core\beast_core.h">
|
<ClInclude Include="..\..\modules\beast_core\beast_core.h">
|
||||||
@@ -419,9 +425,6 @@
|
|||||||
<ClInclude Include="..\..\modules\beast_core\network\MACAddress.h">
|
<ClInclude Include="..\..\modules\beast_core\network\MACAddress.h">
|
||||||
<Filter>beast_core\network</Filter>
|
<Filter>beast_core\network</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\modules\beast_core\network\NamedPipe.h">
|
|
||||||
<Filter>beast_core\network</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\network\Socket.h">
|
<ClInclude Include="..\..\modules\beast_core\network\Socket.h">
|
||||||
<Filter>beast_core\network</Filter>
|
<Filter>beast_core\network</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@@ -482,18 +485,9 @@
|
|||||||
<ClInclude Include="..\..\modules\beast_core\threads\Process.h">
|
<ClInclude Include="..\..\modules\beast_core\threads\Process.h">
|
||||||
<Filter>beast_core\threads</Filter>
|
<Filter>beast_core\threads</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\ReadWriteLock.h">
|
|
||||||
<Filter>beast_core\threads</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\ScopedLock.h">
|
<ClInclude Include="..\..\modules\beast_core\threads\ScopedLock.h">
|
||||||
<Filter>beast_core\threads</Filter>
|
<Filter>beast_core\threads</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\ScopedReadLock.h">
|
|
||||||
<Filter>beast_core\threads</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\threads\ScopedWriteLock.h">
|
|
||||||
<Filter>beast_core\threads</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_core\time\PerformanceCounter.h">
|
<ClInclude Include="..\..\modules\beast_core\time\PerformanceCounter.h">
|
||||||
<Filter>beast_core\time</Filter>
|
<Filter>beast_core\time</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@@ -956,9 +950,6 @@
|
|||||||
<ClInclude Include="..\..\beast\Chrono.h">
|
<ClInclude Include="..\..\beast\Chrono.h">
|
||||||
<Filter>beast</Filter>
|
<Filter>beast</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\beast\SafeBool.h">
|
|
||||||
<Filter>beast</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\config\BeastConfig.h" />
|
<ClInclude Include="..\..\config\BeastConfig.h" />
|
||||||
<ClInclude Include="..\..\beast\utility\Error.h">
|
<ClInclude Include="..\..\beast\utility\Error.h">
|
||||||
<Filter>beast\utility</Filter>
|
<Filter>beast\utility</Filter>
|
||||||
@@ -1014,9 +1005,6 @@
|
|||||||
<ClInclude Include="..\..\beast\net\DynamicBuffer.h">
|
<ClInclude Include="..\..\beast\net\DynamicBuffer.h">
|
||||||
<Filter>beast\net</Filter>
|
<Filter>beast\net</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\beast\net\BufferType.h">
|
|
||||||
<Filter>beast\net</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\modules\beast_asio\http\HTTPRequestParser.h">
|
<ClInclude Include="..\..\modules\beast_asio\http\HTTPRequestParser.h">
|
||||||
<Filter>beast_asio\http</Filter>
|
<Filter>beast_asio\http</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@@ -1032,9 +1020,6 @@
|
|||||||
<ClInclude Include="..\..\beast\Threads.h">
|
<ClInclude Include="..\..\beast\Threads.h">
|
||||||
<Filter>beast</Filter>
|
<Filter>beast</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\beast\threads\LockGuard.h">
|
|
||||||
<Filter>beast\threads</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\beast\threads\RecursiveMutex.h">
|
<ClInclude Include="..\..\beast\threads\RecursiveMutex.h">
|
||||||
<Filter>beast\threads</Filter>
|
<Filter>beast\threads</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@@ -1149,9 +1134,6 @@
|
|||||||
<ClInclude Include="..\..\beast\insight\HookImpl.h">
|
<ClInclude Include="..\..\beast\insight\HookImpl.h">
|
||||||
<Filter>beast\insight</Filter>
|
<Filter>beast\insight</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\beast\cyclic_iterator.h">
|
|
||||||
<Filter>beast</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\beast\threads\semaphore.h">
|
<ClInclude Include="..\..\beast\threads\semaphore.h">
|
||||||
<Filter>beast\threads</Filter>
|
<Filter>beast\threads</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@@ -1323,6 +1305,15 @@
|
|||||||
<ClInclude Include="..\..\beast\http\impl\http_parser.h">
|
<ClInclude Include="..\..\beast\http\impl\http_parser.h">
|
||||||
<Filter>beast\http\impl</Filter>
|
<Filter>beast\http\impl</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\beast\container\cyclic_iterator.h">
|
||||||
|
<Filter>beast\container</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\beast\asio\enable_wait_for_async.h">
|
||||||
|
<Filter>beast\asio</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\beast\asio\memory_buffer.h">
|
||||||
|
<Filter>beast\asio</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\..\modules\beast_core\containers\DynamicObject.cpp">
|
<ClCompile Include="..\..\modules\beast_core\containers\DynamicObject.cpp">
|
||||||
@@ -1406,9 +1397,6 @@
|
|||||||
<ClCompile Include="..\..\modules\beast_core\native\linux_Threads.cpp">
|
<ClCompile Include="..\..\modules\beast_core\native\linux_Threads.cpp">
|
||||||
<Filter>beast_core\native</Filter>
|
<Filter>beast_core\native</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\modules\beast_core\native\posix_NamedPipe.cpp">
|
|
||||||
<Filter>beast_core\native</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\native\win32_Files.cpp">
|
<ClCompile Include="..\..\modules\beast_core\native\win32_Files.cpp">
|
||||||
<Filter>beast_core\native</Filter>
|
<Filter>beast_core\native</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@@ -1427,9 +1415,6 @@
|
|||||||
<ClCompile Include="..\..\modules\beast_core\network\MACAddress.cpp">
|
<ClCompile Include="..\..\modules\beast_core\network\MACAddress.cpp">
|
||||||
<Filter>beast_core\network</Filter>
|
<Filter>beast_core\network</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\modules\beast_core\network\NamedPipe.cpp">
|
|
||||||
<Filter>beast_core\network</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\network\Socket.cpp">
|
<ClCompile Include="..\..\modules\beast_core\network\Socket.cpp">
|
||||||
<Filter>beast_core\network</Filter>
|
<Filter>beast_core\network</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@@ -1475,9 +1460,6 @@
|
|||||||
<ClCompile Include="..\..\modules\beast_core\threads\HighResolutionTimer.cpp">
|
<ClCompile Include="..\..\modules\beast_core\threads\HighResolutionTimer.cpp">
|
||||||
<Filter>beast_core\threads</Filter>
|
<Filter>beast_core\threads</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\modules\beast_core\threads\ReadWriteLock.cpp">
|
|
||||||
<Filter>beast_core\threads</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\modules\beast_core\time\PerformanceCounter.cpp">
|
<ClCompile Include="..\..\modules\beast_core\time\PerformanceCounter.cpp">
|
||||||
<Filter>beast_core\time</Filter>
|
<Filter>beast_core\time</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@@ -1910,6 +1892,18 @@
|
|||||||
<ClCompile Include="..\..\beast\asio\abstract_socket.cpp">
|
<ClCompile Include="..\..\beast\asio\abstract_socket.cpp">
|
||||||
<Filter>beast\asio</Filter>
|
<Filter>beast\asio</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\beast\asio\tests\bind_handler_tests.cpp">
|
||||||
|
<Filter>beast\asio\tests</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\beast\asio\tests\shared_handler_tests.cpp">
|
||||||
|
<Filter>beast\asio\tests</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\beast\asio\tests\wrap_handler_tests.cpp">
|
||||||
|
<Filter>beast\asio\tests</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\..\beast\asio\tests\enable_wait_for_async.test.cpp">
|
||||||
|
<Filter>beast\asio\tests</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Text Include="..\..\TODO.txt">
|
<Text Include="..\..\TODO.txt">
|
||||||
|
|||||||
2
TODO.txt
2
TODO.txt
@@ -58,8 +58,6 @@ BEAST TODO
|
|||||||
|
|
||||||
- Rename SharedData to SharedState or something?
|
- Rename SharedData to SharedState or something?
|
||||||
|
|
||||||
- Figure out what to do with ReadWriteLock, and NamedPipe which uses it?
|
|
||||||
|
|
||||||
- Put BEAST_PUBLIC_FUNCTION in front of all loose functions
|
- Put BEAST_PUBLIC_FUNCTION in front of all loose functions
|
||||||
|
|
||||||
- restructure the repo sources to look like this:
|
- restructure the repo sources to look like this:
|
||||||
|
|||||||
@@ -20,7 +20,6 @@
|
|||||||
#ifndef BEAST_NET_H_INCLUDED
|
#ifndef BEAST_NET_H_INCLUDED
|
||||||
#define BEAST_NET_H_INCLUDED
|
#define BEAST_NET_H_INCLUDED
|
||||||
|
|
||||||
#include "net/BufferType.h"
|
|
||||||
#include "net/DynamicBuffer.h"
|
#include "net/DynamicBuffer.h"
|
||||||
|
|
||||||
#include "net/IPEndpoint.h"
|
#include "net/IPEndpoint.h"
|
||||||
|
|||||||
@@ -1,95 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_SAFEBOOL_H_INCLUDED
|
|
||||||
#define BEAST_SAFEBOOL_H_INCLUDED
|
|
||||||
|
|
||||||
namespace beast {
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
class SafeBoolBase
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
void disallowed () const { }
|
|
||||||
|
|
||||||
public:
|
|
||||||
void allowed () const { }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
typedef void (SafeBoolBase::*boolean_t) () const;
|
|
||||||
|
|
||||||
SafeBoolBase () { }
|
|
||||||
SafeBoolBase (SafeBoolBase const&) { }
|
|
||||||
SafeBoolBase& operator= (SafeBoolBase const&)
|
|
||||||
{
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
~SafeBoolBase () { }
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Safe evaluation of class as `bool`.
|
|
||||||
|
|
||||||
This allows a class to be safely evaluated as a bool without the usual
|
|
||||||
harmful side effects of the straightforward operator conversion approach.
|
|
||||||
To use it, derive your class from SafeBool and implement `asBoolean()` as:
|
|
||||||
|
|
||||||
@code
|
|
||||||
|
|
||||||
bool asBoolean () const;
|
|
||||||
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
Ideas from http://www.artima.com/cppsource/safebool.html
|
|
||||||
|
|
||||||
@class SafeBool
|
|
||||||
*/
|
|
||||||
template <typename T = void>
|
|
||||||
class SafeBool : public detail::SafeBoolBase
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
operator detail::SafeBoolBase::boolean_t () const
|
|
||||||
{
|
|
||||||
return (static_cast <T const*> (this))->asBoolean ()
|
|
||||||
? &SafeBoolBase::allowed : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
~SafeBool () { }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T, typename U>
|
|
||||||
void operator== (SafeBool <T> const& lhs, SafeBool <U> const& rhs)
|
|
||||||
{
|
|
||||||
lhs.disallowed ();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, typename U>
|
|
||||||
void operator!= (SafeBool <T> const& lhs, SafeBool <U> const& rhs)
|
|
||||||
{
|
|
||||||
lhs.disallowed ();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
@@ -20,7 +20,6 @@
|
|||||||
#ifndef BEAST_THREADS_H_INCLUDED
|
#ifndef BEAST_THREADS_H_INCLUDED
|
||||||
#define BEAST_THREADS_H_INCLUDED
|
#define BEAST_THREADS_H_INCLUDED
|
||||||
|
|
||||||
#include "threads/LockGuard.h"
|
|
||||||
#include "threads/UnlockGuard.h"
|
#include "threads/UnlockGuard.h"
|
||||||
#include "threads/TryLockGuard.h"
|
#include "threads/TryLockGuard.h"
|
||||||
#include "threads/SharedLockGuard.h"
|
#include "threads/SharedLockGuard.h"
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include "tests/wrap_handler_tests.cpp"
|
#include "tests/wrap_handler_tests.cpp"
|
||||||
#include "tests/bind_handler_tests.cpp"
|
#include "tests/bind_handler_tests.cpp"
|
||||||
|
#include "tests/enable_wait_for_async.test.cpp"
|
||||||
#include "tests/shared_handler_tests.cpp"
|
#include "tests/shared_handler_tests.cpp"
|
||||||
|
|
||||||
#include "abstract_socket.cpp" // TEMPORARY!
|
#include "abstract_socket.cpp" // TEMPORARY!
|
||||||
|
|||||||
14
beast/asio/README.md
Normal file
14
beast/asio/README.md
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# beast::asio
|
||||||
|
|
||||||
|
Wrappers and utilities to make working with boost::asio easier.
|
||||||
|
|
||||||
|
## Rules for asynchronous objects
|
||||||
|
|
||||||
|
If an object calls asynchronous initiating functions it must either:
|
||||||
|
|
||||||
|
1. Manage its lifetime by being reference counted
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
2. Wait for all pending completion handlers to be called before
|
||||||
|
allowing itself to be destroyed.
|
||||||
@@ -99,6 +99,21 @@ public:
|
|||||||
{
|
{
|
||||||
return m_buffers.end ();
|
return m_buffers.end ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
template <class ConstBufferSequence>
|
||||||
|
void
|
||||||
|
assign (ConstBufferSequence const& buffers)
|
||||||
|
{
|
||||||
|
auto const n (std::distance (
|
||||||
|
std::begin (buffers), std::end (buffers)));
|
||||||
|
|
||||||
|
for (int i = 0, auto iter (std::begin (buffers));
|
||||||
|
iter != std::end (buffers); ++iter, ++i)
|
||||||
|
m_buffers[i] = Buffer (boost::asio::buffer_cast <void*> (
|
||||||
|
*iter), boost::asio::buffer_size (*iter));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef buffer_sequence <boost::asio::const_buffer> const_buffers;
|
typedef buffer_sequence <boost::asio::const_buffer> const_buffers;
|
||||||
|
|||||||
265
beast/asio/enable_wait_for_async.h
Normal file
265
beast/asio/enable_wait_for_async.h
Normal file
@@ -0,0 +1,265 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||||
|
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
#ifndef BEAST_ASIO_ENABLE_WAIT_FOR_ASYNC_H_INCLUDED
|
||||||
|
#define BEAST_ASIO_ENABLE_WAIT_FOR_ASYNC_H_INCLUDED
|
||||||
|
|
||||||
|
#include "wrap_handler.h"
|
||||||
|
|
||||||
|
#include "../mpl/IsCallPossible.h"
|
||||||
|
|
||||||
|
#include <boost/asio/detail/handler_alloc_helpers.hpp>
|
||||||
|
#include <boost/asio/detail/handler_cont_helpers.hpp>
|
||||||
|
#include <boost/asio/detail/handler_invoke_helpers.hpp>
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <mutex>
|
||||||
|
#include "../cxx14/type_traits.h" // <type_traits>
|
||||||
|
|
||||||
|
namespace beast {
|
||||||
|
namespace asio {
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template <class Owner, class Handler>
|
||||||
|
class ref_counted_wrapped_handler
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
static_assert (std::is_same <std::decay_t <Owner>, Owner>::value,
|
||||||
|
"Owner cannot be a const or reference type");
|
||||||
|
|
||||||
|
Handler m_handler;
|
||||||
|
std::reference_wrapper <Owner> m_owner;
|
||||||
|
bool m_continuation;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ref_counted_wrapped_handler (Owner& owner,
|
||||||
|
Handler&& handler, bool continuation)
|
||||||
|
: m_handler (std::move (handler))
|
||||||
|
, m_owner (owner)
|
||||||
|
, m_continuation (continuation ? true :
|
||||||
|
boost_asio_handler_cont_helpers::is_continuation (m_handler))
|
||||||
|
{
|
||||||
|
m_owner.get().increment();
|
||||||
|
}
|
||||||
|
|
||||||
|
ref_counted_wrapped_handler (Owner& owner,
|
||||||
|
Handler const& handler, bool continuation)
|
||||||
|
: m_handler (handler)
|
||||||
|
, m_owner (owner)
|
||||||
|
, m_continuation (continuation ? true :
|
||||||
|
boost_asio_handler_cont_helpers::is_continuation (m_handler))
|
||||||
|
{
|
||||||
|
m_owner.get().increment();
|
||||||
|
}
|
||||||
|
|
||||||
|
~ref_counted_wrapped_handler ()
|
||||||
|
{
|
||||||
|
m_owner.get().decrement();
|
||||||
|
}
|
||||||
|
|
||||||
|
ref_counted_wrapped_handler (ref_counted_wrapped_handler const& other)
|
||||||
|
: m_handler (other.m_handler)
|
||||||
|
, m_owner (other.m_owner)
|
||||||
|
, m_continuation (other.m_continuation)
|
||||||
|
{
|
||||||
|
m_owner.get().increment();
|
||||||
|
}
|
||||||
|
|
||||||
|
ref_counted_wrapped_handler (ref_counted_wrapped_handler&& other)
|
||||||
|
: m_handler (std::move (other.m_handler))
|
||||||
|
, m_owner (other.m_owner)
|
||||||
|
, m_continuation (other.m_continuation)
|
||||||
|
{
|
||||||
|
m_owner.get().increment();
|
||||||
|
}
|
||||||
|
|
||||||
|
ref_counted_wrapped_handler& operator= (
|
||||||
|
ref_counted_wrapped_handler const&) = delete;
|
||||||
|
|
||||||
|
template <class... Args>
|
||||||
|
void
|
||||||
|
operator() (Args&&... args)
|
||||||
|
{
|
||||||
|
m_handler (std::forward <Args> (args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class... Args>
|
||||||
|
void
|
||||||
|
operator() (Args&&... args) const
|
||||||
|
{
|
||||||
|
m_handler (std::forward <Args> (args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Function>
|
||||||
|
friend
|
||||||
|
void
|
||||||
|
asio_handler_invoke (Function& f,
|
||||||
|
ref_counted_wrapped_handler* h)
|
||||||
|
{
|
||||||
|
boost_asio_handler_invoke_helpers::
|
||||||
|
invoke (f, h->m_handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Function>
|
||||||
|
friend
|
||||||
|
void
|
||||||
|
asio_handler_invoke (Function const& f,
|
||||||
|
ref_counted_wrapped_handler* h)
|
||||||
|
{
|
||||||
|
boost_asio_handler_invoke_helpers::
|
||||||
|
invoke (f, h->m_handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend
|
||||||
|
void*
|
||||||
|
asio_handler_allocate (std::size_t size,
|
||||||
|
ref_counted_wrapped_handler* h)
|
||||||
|
{
|
||||||
|
return boost_asio_handler_alloc_helpers::
|
||||||
|
allocate (size, h->m_handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend
|
||||||
|
void
|
||||||
|
asio_handler_deallocate (void* p, std::size_t size,
|
||||||
|
ref_counted_wrapped_handler* h)
|
||||||
|
{
|
||||||
|
boost_asio_handler_alloc_helpers::
|
||||||
|
deallocate (p, size, h->m_handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend
|
||||||
|
bool
|
||||||
|
asio_handler_is_continuation (ref_counted_wrapped_handler* h)
|
||||||
|
{
|
||||||
|
return h->m_continuation;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/** Facilitates blocking until no completion handlers are remaining.
|
||||||
|
If Derived has this member function:
|
||||||
|
|
||||||
|
@code
|
||||||
|
void on_wait_for_async (void)
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
Then it will be called every time the number of pending completion
|
||||||
|
handlers transitions to zero from a non-zero value. The call is made
|
||||||
|
while holding the internal mutex.
|
||||||
|
*/
|
||||||
|
template <class Derived>
|
||||||
|
class enable_wait_for_async
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
BEAST_DEFINE_IS_CALL_POSSIBLE(
|
||||||
|
has_on_wait_for_async,on_wait_for_async);
|
||||||
|
|
||||||
|
void increment()
|
||||||
|
{
|
||||||
|
std::lock_guard <decltype(m_mutex)> lock (m_mutex);
|
||||||
|
++m_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void notify (std::true_type)
|
||||||
|
{
|
||||||
|
static_cast <Derived*> (this)->on_wait_for_async();
|
||||||
|
}
|
||||||
|
|
||||||
|
void notify (std::false_type)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void decrement()
|
||||||
|
{
|
||||||
|
std::lock_guard <decltype(m_mutex)> lock (m_mutex);
|
||||||
|
--m_count;
|
||||||
|
if (m_count == 0)
|
||||||
|
{
|
||||||
|
m_cond.notify_all();
|
||||||
|
notify (std::integral_constant <bool,
|
||||||
|
has_on_wait_for_async<Derived, void(void)>::value>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Owner, class Handler>
|
||||||
|
friend class detail::ref_counted_wrapped_handler;
|
||||||
|
|
||||||
|
std::mutex m_mutex;
|
||||||
|
std::condition_variable m_cond;
|
||||||
|
std::size_t m_count;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/** Blocks if there are any pending completion handlers. */
|
||||||
|
void
|
||||||
|
wait_for_async()
|
||||||
|
{
|
||||||
|
std::unique_lock <decltype (m_mutex)> lock (m_mutex);
|
||||||
|
while (m_count != 0)
|
||||||
|
m_cond.wait (lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
enable_wait_for_async()
|
||||||
|
: m_count (0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~enable_wait_for_async()
|
||||||
|
{
|
||||||
|
assert (m_count == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Wraps the specified handler so it can be counted. */
|
||||||
|
/** @{ */
|
||||||
|
template <class Handler>
|
||||||
|
detail::ref_counted_wrapped_handler <
|
||||||
|
enable_wait_for_async,
|
||||||
|
std::remove_reference_t <Handler>
|
||||||
|
>
|
||||||
|
wrap_with_counter (Handler&& handler, bool continuation = false)
|
||||||
|
{
|
||||||
|
return detail::ref_counted_wrapped_handler <enable_wait_for_async,
|
||||||
|
std::remove_reference_t <Handler>> (*this,
|
||||||
|
std::forward <Handler> (handler), continuation);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Handler>
|
||||||
|
detail::ref_counted_wrapped_handler <
|
||||||
|
enable_wait_for_async,
|
||||||
|
std::remove_reference_t <Handler>
|
||||||
|
>
|
||||||
|
wrap_with_counter (continuation_t, Handler&& handler)
|
||||||
|
{
|
||||||
|
return detail::ref_counted_wrapped_handler <enable_wait_for_async,
|
||||||
|
std::remove_reference_t <Handler>> (*this,
|
||||||
|
std::forward <Handler> (handler), true);
|
||||||
|
}
|
||||||
|
/** @} */
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
423
beast/asio/memory_buffer.h
Normal file
423
beast/asio/memory_buffer.h
Normal file
@@ -0,0 +1,423 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||||
|
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
#ifndef BEAST_ASIO_MEMORY_BUFFER_H_INCLUDED
|
||||||
|
#define BEAST_ASIO_MEMORY_BUFFER_H_INCLUDED
|
||||||
|
|
||||||
|
#include "../utility/empty_base_optimization.h"
|
||||||
|
|
||||||
|
#include <boost/asio/buffer.hpp>
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace beast {
|
||||||
|
namespace asio {
|
||||||
|
|
||||||
|
template <
|
||||||
|
class T,
|
||||||
|
class Alloc = std::allocator <T>
|
||||||
|
>
|
||||||
|
class memory_buffer
|
||||||
|
: private empty_base_optimization <Alloc>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
static_assert (std::is_trivially_constructible <T>::value,
|
||||||
|
"T must be trivially constructible");
|
||||||
|
|
||||||
|
typedef empty_base_optimization <Alloc> Base;
|
||||||
|
|
||||||
|
using AllocTraits = std::allocator_traits <Alloc>;
|
||||||
|
|
||||||
|
T* m_base;
|
||||||
|
std::size_t m_size;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef std::size_t size_type;
|
||||||
|
typedef std::ptrdiff_t difference_type;
|
||||||
|
typedef T& reference;
|
||||||
|
typedef T const& const_reference;
|
||||||
|
typedef T* pointer;
|
||||||
|
typedef T const* const_pointer;
|
||||||
|
typedef Alloc allocator_type;
|
||||||
|
typedef T* iterator;
|
||||||
|
typedef T const* const_iterator;
|
||||||
|
typedef std::reverse_iterator <iterator> reverse_iterator;
|
||||||
|
typedef std::reverse_iterator <const_iterator> const_reverse_iterator;
|
||||||
|
|
||||||
|
memory_buffer ()
|
||||||
|
: m_base (nullptr)
|
||||||
|
, m_size (0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
memory_buffer (memory_buffer&& other)
|
||||||
|
: Base (std::move (other))
|
||||||
|
, m_base (other.m_base)
|
||||||
|
, m_size (other.m_size)
|
||||||
|
{
|
||||||
|
other.m_base = nullptr;
|
||||||
|
other.m_size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit memory_buffer (size_type n)
|
||||||
|
: m_base (AllocTraits::allocate (Base::member(), n))
|
||||||
|
, m_size (n)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit memory_buffer (Alloc const& alloc)
|
||||||
|
: Base (alloc)
|
||||||
|
, m_base (nullptr)
|
||||||
|
, m_size (0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
memory_buffer (size_type n, Alloc const& alloc)
|
||||||
|
: Base (alloc)
|
||||||
|
, m_base (AllocTraits::allocate (Base::member(), n))
|
||||||
|
, m_size (n)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~memory_buffer()
|
||||||
|
{
|
||||||
|
if (m_base != nullptr)
|
||||||
|
AllocTraits::deallocate (Base::member(), m_base, m_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
memory_buffer& operator= (memory_buffer const&) = delete;
|
||||||
|
|
||||||
|
allocator_type
|
||||||
|
get_allocator() const
|
||||||
|
{
|
||||||
|
return Base::member;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// asio support
|
||||||
|
//
|
||||||
|
|
||||||
|
boost::asio::mutable_buffer
|
||||||
|
buffer()
|
||||||
|
{
|
||||||
|
return boost::asio::mutable_buffer (
|
||||||
|
data(), bytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::asio::const_buffer
|
||||||
|
buffer() const
|
||||||
|
{
|
||||||
|
return boost::asio::const_buffer (
|
||||||
|
data(), bytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::asio::mutable_buffers_1
|
||||||
|
buffers()
|
||||||
|
{
|
||||||
|
return boost::asio::mutable_buffers_1 (
|
||||||
|
data(), bytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::asio::const_buffers_1
|
||||||
|
buffers() const
|
||||||
|
{
|
||||||
|
return boost::asio::const_buffers_1 (
|
||||||
|
data(), bytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
operator boost::asio::mutable_buffer()
|
||||||
|
{
|
||||||
|
return buffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
operator boost::asio::const_buffer() const
|
||||||
|
{
|
||||||
|
return buffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
operator boost::asio::mutable_buffers_1()
|
||||||
|
{
|
||||||
|
return buffers();
|
||||||
|
}
|
||||||
|
|
||||||
|
operator boost::asio::const_buffers_1() const
|
||||||
|
{
|
||||||
|
return buffers();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Element access
|
||||||
|
//
|
||||||
|
|
||||||
|
reference
|
||||||
|
at (size_type pos)
|
||||||
|
{
|
||||||
|
if (! (pos < size()))
|
||||||
|
throw std::out_of_range ("bad array index");
|
||||||
|
return m_base [pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
const_reference
|
||||||
|
at (size_type pos) const
|
||||||
|
{
|
||||||
|
if (! (pos < size()))
|
||||||
|
throw std::out_of_range ("bad array index");
|
||||||
|
return m_base [pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
reference
|
||||||
|
operator[] (size_type pos) noexcept
|
||||||
|
{
|
||||||
|
return m_base [pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
const_reference
|
||||||
|
operator[] (size_type pos) const noexcept
|
||||||
|
{
|
||||||
|
return m_base [pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
reference
|
||||||
|
back() noexcept
|
||||||
|
{
|
||||||
|
return m_base [m_size - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
const_reference
|
||||||
|
back() const noexcept
|
||||||
|
{
|
||||||
|
return m_base [m_size - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
reference
|
||||||
|
front() noexcept
|
||||||
|
{
|
||||||
|
return *m_base;
|
||||||
|
}
|
||||||
|
|
||||||
|
const_reference
|
||||||
|
front() const noexcept
|
||||||
|
{
|
||||||
|
return *m_base;
|
||||||
|
}
|
||||||
|
|
||||||
|
pointer
|
||||||
|
data() noexcept
|
||||||
|
{
|
||||||
|
return m_base;
|
||||||
|
}
|
||||||
|
|
||||||
|
const_pointer
|
||||||
|
data() const noexcept
|
||||||
|
{
|
||||||
|
return m_base;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Iterators
|
||||||
|
//
|
||||||
|
|
||||||
|
iterator
|
||||||
|
begin() noexcept
|
||||||
|
{
|
||||||
|
return m_base;
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator
|
||||||
|
begin() const noexcept
|
||||||
|
{
|
||||||
|
return m_base;
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator
|
||||||
|
cbegin() const noexcept
|
||||||
|
{
|
||||||
|
return m_base;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator
|
||||||
|
end() noexcept
|
||||||
|
{
|
||||||
|
return m_base + m_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator
|
||||||
|
end() const noexcept
|
||||||
|
{
|
||||||
|
return m_base + m_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator
|
||||||
|
cend() const noexcept
|
||||||
|
{
|
||||||
|
return m_base + m_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
reverse_iterator
|
||||||
|
rbegin() noexcept
|
||||||
|
{
|
||||||
|
return reverse_iterator (end());
|
||||||
|
}
|
||||||
|
|
||||||
|
const_reverse_iterator
|
||||||
|
rbegin() const noexcept
|
||||||
|
{
|
||||||
|
return const_reverse_iterator (cend());
|
||||||
|
}
|
||||||
|
|
||||||
|
const_reverse_iterator
|
||||||
|
crbegin() const noexcept
|
||||||
|
{
|
||||||
|
return const_reverse_iterator (cend());
|
||||||
|
}
|
||||||
|
|
||||||
|
reverse_iterator
|
||||||
|
rend() noexcept
|
||||||
|
{
|
||||||
|
return reverse_iterator (begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
const_reverse_iterator
|
||||||
|
rend() const noexcept
|
||||||
|
{
|
||||||
|
return const_reverse_iterator (cbegin());
|
||||||
|
}
|
||||||
|
|
||||||
|
const_reverse_iterator
|
||||||
|
crend() const noexcept
|
||||||
|
{
|
||||||
|
return const_reverse_iterator (cbegin());
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Capacity
|
||||||
|
//
|
||||||
|
|
||||||
|
bool
|
||||||
|
empty() const noexcept
|
||||||
|
{
|
||||||
|
return m_size == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_type
|
||||||
|
size() const noexcept
|
||||||
|
{
|
||||||
|
return m_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_type
|
||||||
|
max_size() const noexcept
|
||||||
|
{
|
||||||
|
return size();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_type
|
||||||
|
capacity() const noexcept
|
||||||
|
{
|
||||||
|
return size();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_type bytes() const
|
||||||
|
{
|
||||||
|
return m_size * sizeof(T);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Modifiers
|
||||||
|
//
|
||||||
|
|
||||||
|
template <class U, class A>
|
||||||
|
friend
|
||||||
|
void
|
||||||
|
swap (memory_buffer <U, A>& lhs,
|
||||||
|
memory_buffer <U, A>& rhs) noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <class T, class Alloc>
|
||||||
|
void
|
||||||
|
swap (memory_buffer <T, Alloc>& lhs,
|
||||||
|
memory_buffer <T, Alloc>& rhs) noexcept
|
||||||
|
{
|
||||||
|
std::swap (lhs.m_base, rhs.m_base);
|
||||||
|
std::swap (lhs.m_size, rhs.m_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T, class A1, class A2>
|
||||||
|
inline
|
||||||
|
bool
|
||||||
|
operator== (memory_buffer <T, A1> const& lhs,
|
||||||
|
memory_buffer <T, A2> const& rhs)
|
||||||
|
{
|
||||||
|
return std::equal (lhs.cbegin(), lhs.cend(),
|
||||||
|
rhs.cbegin(), rhs.cend());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T, class A1, class A2>
|
||||||
|
inline
|
||||||
|
bool
|
||||||
|
operator!= (memory_buffer <T, A1> const& lhs,
|
||||||
|
memory_buffer <T, A2> const& rhs)
|
||||||
|
{
|
||||||
|
return ! (lhs == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T, class A1, class A2>
|
||||||
|
inline
|
||||||
|
bool
|
||||||
|
operator< (memory_buffer <T, A1> const& lhs,
|
||||||
|
memory_buffer <T, A2> const& rhs)
|
||||||
|
{
|
||||||
|
return std::lexicographical_compare (
|
||||||
|
lhs.cbegin(), lhs.cend(), rhs.cbegin(), rhs.cend());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T, class A1, class A2>
|
||||||
|
inline
|
||||||
|
bool
|
||||||
|
operator>= (memory_buffer <T, A1> const& lhs,
|
||||||
|
memory_buffer <T, A2> const& rhs)
|
||||||
|
{
|
||||||
|
return ! (lhs < rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T, class A1, class A2>
|
||||||
|
inline
|
||||||
|
bool
|
||||||
|
operator> (memory_buffer <T, A1> const& lhs,
|
||||||
|
memory_buffer <T, A2> const& rhs)
|
||||||
|
{
|
||||||
|
return rhs < lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T, class A1, class A2>
|
||||||
|
inline
|
||||||
|
bool
|
||||||
|
operator<= (memory_buffer <T, A1> const& lhs,
|
||||||
|
memory_buffer <T, A2> const& rhs)
|
||||||
|
{
|
||||||
|
return ! (rhs < lhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -20,6 +20,8 @@
|
|||||||
#ifndef BEAST_ASIO_SHARED_HANDLER_H_INCLUDED
|
#ifndef BEAST_ASIO_SHARED_HANDLER_H_INCLUDED
|
||||||
#define BEAST_ASIO_SHARED_HANDLER_H_INCLUDED
|
#define BEAST_ASIO_SHARED_HANDLER_H_INCLUDED
|
||||||
|
|
||||||
|
#include "../Config.h"
|
||||||
|
|
||||||
#include "../mpl/IsCallPossible.h"
|
#include "../mpl/IsCallPossible.h"
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
@@ -260,9 +262,7 @@ public:
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
/** Handler shared reference that provides io_service execution guarantees. */
|
/** Handler shared reference that provides io_service execution guarantees. */
|
||||||
template <
|
template <class Signature>
|
||||||
class Signature
|
|
||||||
>
|
|
||||||
class shared_handler
|
class shared_handler
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
@@ -318,6 +318,7 @@ public:
|
|||||||
operator= (std::nullptr_t)
|
operator= (std::nullptr_t)
|
||||||
{
|
{
|
||||||
m_ptr = nullptr;
|
m_ptr = nullptr;
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_handler&
|
shared_handler&
|
||||||
@@ -327,15 +328,17 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
shared_handler&
|
||||||
empty() const
|
operator= (shared_handler&& rhs)
|
||||||
{
|
{
|
||||||
return ! m_ptr.operator bool();
|
m_ptr = std::move (rhs.m_ptr);
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
operator bool() const
|
explicit
|
||||||
|
operator bool() const noexcept
|
||||||
{
|
{
|
||||||
return !empty();
|
return m_ptr.operator bool();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -225,14 +225,9 @@ private:
|
|||||||
|
|
||||||
boost::asio::io_service& get_io_service () override
|
boost::asio::io_service& get_io_service () override
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
// Apparently has_get_io_service always results in false
|
|
||||||
return get_io_service (
|
return get_io_service (
|
||||||
Enabled <has_get_io_service <this_layer_type,
|
Enabled <has_get_io_service <this_layer_type,
|
||||||
boost::asio::io_service&()> > ());
|
boost::asio::io_service&()> > ());
|
||||||
#else
|
|
||||||
return get_io_service (std::true_type ());
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::asio::io_service& get_io_service (
|
boost::asio::io_service& get_io_service (
|
||||||
|
|||||||
108
beast/asio/tests/enable_wait_for_async.test.cpp
Normal file
108
beast/asio/tests/enable_wait_for_async.test.cpp
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||||
|
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
#include "BeastConfig.h"
|
||||||
|
|
||||||
|
#include "../../../modules/beast_core/beast_core.h" // for UnitTest
|
||||||
|
|
||||||
|
#include "../bind_handler.h"
|
||||||
|
#include "../enable_wait_for_async.h"
|
||||||
|
|
||||||
|
#include <boost/asio/io_service.hpp>
|
||||||
|
|
||||||
|
namespace beast {
|
||||||
|
|
||||||
|
class enable_wait_for_async_Tests : public UnitTest
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef boost::system::error_code error_code;
|
||||||
|
|
||||||
|
void test()
|
||||||
|
{
|
||||||
|
struct handler
|
||||||
|
{
|
||||||
|
void operator()(error_code)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct owner : asio::enable_wait_for_async <owner>
|
||||||
|
{
|
||||||
|
bool notified;
|
||||||
|
|
||||||
|
owner()
|
||||||
|
: notified (false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
boost::asio::io_service ios;
|
||||||
|
ios.post (asio::bind_handler (handler(),
|
||||||
|
error_code()));
|
||||||
|
ios.run();
|
||||||
|
ios.reset();
|
||||||
|
wait_for_async();
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::asio::io_service ios;
|
||||||
|
ios.post (wrap_with_counter (asio::bind_handler (
|
||||||
|
handler(), error_code())));
|
||||||
|
ios.run();
|
||||||
|
wait_for_async();
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::asio::io_service ios;
|
||||||
|
handler h;
|
||||||
|
ios.post (wrap_with_counter (std::bind (
|
||||||
|
&handler::operator(), &h,
|
||||||
|
error_code())));
|
||||||
|
ios.run();
|
||||||
|
wait_for_async();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_wait_for_async()
|
||||||
|
{
|
||||||
|
notified = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
beginTestCase ("wait_for_async");
|
||||||
|
owner o;
|
||||||
|
o();
|
||||||
|
expect (o.notified);
|
||||||
|
}
|
||||||
|
|
||||||
|
void runTest()
|
||||||
|
{
|
||||||
|
test();
|
||||||
|
}
|
||||||
|
|
||||||
|
enable_wait_for_async_Tests() : UnitTest ("enable_wait_for_async", "beast")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static enable_wait_for_async_Tests enable_wait_for_async_tests;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -20,7 +20,6 @@
|
|||||||
#ifndef BEAST_CRYPTO_UNSIGNEDINTEGER_H_INCLUDED
|
#ifndef BEAST_CRYPTO_UNSIGNEDINTEGER_H_INCLUDED
|
||||||
#define BEAST_CRYPTO_UNSIGNEDINTEGER_H_INCLUDED
|
#define BEAST_CRYPTO_UNSIGNEDINTEGER_H_INCLUDED
|
||||||
|
|
||||||
#include "../SafeBool.h"
|
|
||||||
#include "UnsignedIntegerCalc.h"
|
#include "UnsignedIntegerCalc.h"
|
||||||
#include "MurmurHash.h"
|
#include "MurmurHash.h"
|
||||||
|
|
||||||
@@ -38,7 +37,7 @@ namespace beast {
|
|||||||
may not be aligned.
|
may not be aligned.
|
||||||
*/
|
*/
|
||||||
template <std::size_t Bytes>
|
template <std::size_t Bytes>
|
||||||
class UnsignedInteger : public SafeBool <UnsignedInteger <Bytes> >
|
class UnsignedInteger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/** Constant for determining the number of bytes. */
|
/** Constant for determining the number of bytes. */
|
||||||
@@ -201,9 +200,9 @@ public:
|
|||||||
|
|
||||||
/** Support conversion to `bool`.
|
/** Support conversion to `bool`.
|
||||||
@return `true` if any bit is non-zero.
|
@return `true` if any bit is non-zero.
|
||||||
@see SafeBool
|
|
||||||
*/
|
*/
|
||||||
bool asBoolean () const
|
explicit
|
||||||
|
operator bool() const
|
||||||
{
|
{
|
||||||
return isNotZero ();
|
return isNotZero ();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ struct DoubleWidthUInt <std::uint32_t>
|
|||||||
which return results by value cannot be included in the interface.
|
which return results by value cannot be included in the interface.
|
||||||
*/
|
*/
|
||||||
template <typename UInt>
|
template <typename UInt>
|
||||||
class UnsignedIntegerCalc : public SafeBool <UnsignedIntegerCalc <UInt> >
|
class UnsignedIntegerCalc
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef typename detail::DoubleWidthUInt <UInt>::type UIntBig;
|
typedef typename detail::DoubleWidthUInt <UInt>::type UIntBig;
|
||||||
@@ -182,7 +182,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Safe conversion to `bool`, `true` means a non-zero value. */
|
/** Safe conversion to `bool`, `true` means a non-zero value. */
|
||||||
bool asBoolean () const
|
explicit
|
||||||
|
operator bool() const
|
||||||
{
|
{
|
||||||
return isNotZero ();
|
return isNotZero ();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,8 @@
|
|||||||
#ifndef BEAST_MPL_ISCALLPOSSIBLE_H_INCLUDED
|
#ifndef BEAST_MPL_ISCALLPOSSIBLE_H_INCLUDED
|
||||||
#define BEAST_MPL_ISCALLPOSSIBLE_H_INCLUDED
|
#define BEAST_MPL_ISCALLPOSSIBLE_H_INCLUDED
|
||||||
|
|
||||||
|
#include "../cxx14/type_traits.h" // <type_traits>
|
||||||
|
|
||||||
namespace beast {
|
namespace beast {
|
||||||
namespace mpl {
|
namespace mpl {
|
||||||
|
|
||||||
@@ -160,10 +162,11 @@ struct trait_name##_detail
|
|||||||
BEAST_DEFINE_HAS_MEMBER_FUNCTION(has_member, member_function_name); \
|
BEAST_DEFINE_HAS_MEMBER_FUNCTION(has_member, member_function_name); \
|
||||||
}; \
|
}; \
|
||||||
\
|
\
|
||||||
template <typename T, typename IsCallPossibleSignature> \
|
template <typename DT, typename IsCallPossibleSignature> \
|
||||||
struct trait_name \
|
struct trait_name \
|
||||||
{ \
|
{ \
|
||||||
private: \
|
private: \
|
||||||
|
typedef std::remove_reference_t <DT> T; \
|
||||||
class yes {}; \
|
class yes {}; \
|
||||||
class no { yes m[2]; }; \
|
class no { yes m[2]; }; \
|
||||||
struct derived : public T \
|
struct derived : public T \
|
||||||
@@ -197,6 +200,18 @@ struct trait_name
|
|||||||
static const bool value = false; \
|
static const bool value = false; \
|
||||||
}; \
|
}; \
|
||||||
\
|
\
|
||||||
|
template <typename Result> \
|
||||||
|
struct impl<true, Result(void)> \
|
||||||
|
{ \
|
||||||
|
static typename beast::mpl::is_call_possible_detail::add_reference<derived_type>::type test_me; \
|
||||||
|
\
|
||||||
|
static const bool value = \
|
||||||
|
sizeof( \
|
||||||
|
return_value_check<T, Result>::deduce( \
|
||||||
|
(test_me.member_function_name(), beast::mpl::is_call_possible_detail::void_exp_result<T>())) \
|
||||||
|
) == sizeof(yes); \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
template <typename Result, typename Arg> \
|
template <typename Result, typename Arg> \
|
||||||
struct impl<true, Result(Arg)> \
|
struct impl<true, Result(Arg)> \
|
||||||
{ \
|
{ \
|
||||||
|
|||||||
@@ -1,106 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_NET_BASICS_BUFFERTYPE_H_INCLUDED
|
|
||||||
#define BEAST_NET_BASICS_BUFFERTYPE_H_INCLUDED
|
|
||||||
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
namespace beast {
|
|
||||||
|
|
||||||
/** General linear memory buffer.
|
|
||||||
This wraps the underlying buffer type and provides additional methods
|
|
||||||
to create a uniform interface. Specializations allow asio-compatible
|
|
||||||
buffers without having to include boost/asio.h.
|
|
||||||
*/
|
|
||||||
/** @{ */
|
|
||||||
template <bool IsConst>
|
|
||||||
class BufferType
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
typedef typename std::conditional <IsConst,
|
|
||||||
void const*, void*>::type pointer_type;
|
|
||||||
|
|
||||||
typedef typename std::conditional <IsConst,
|
|
||||||
uint8 const, uint8>::type byte_type;
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef std::size_t size_type;
|
|
||||||
|
|
||||||
BufferType ()
|
|
||||||
: m_data (nullptr)
|
|
||||||
, m_size (0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template <bool OtherIsConst>
|
|
||||||
BufferType (BufferType <OtherIsConst> const& other)
|
|
||||||
: m_data (other.template cast <pointer_type> ())
|
|
||||||
, m_size (other.size ())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
BufferType (pointer_type data, std::size_t size) noexcept
|
|
||||||
: m_data (data)
|
|
||||||
, m_size (size)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
BufferType& operator= (BufferType const& other) noexcept
|
|
||||||
{
|
|
||||||
m_data = other.cast <pointer_type> ();
|
|
||||||
m_size = other.size ();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <bool OtherIsConst>
|
|
||||||
BufferType& operator= (
|
|
||||||
BufferType <OtherIsConst> const& other) noexcept
|
|
||||||
{
|
|
||||||
m_data = other.template cast <pointer_type> ();
|
|
||||||
m_size = other.size ();
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T cast () const noexcept
|
|
||||||
{
|
|
||||||
return static_cast <T> (m_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_type size () const
|
|
||||||
{
|
|
||||||
return m_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
BufferType operator+ (size_type n) const noexcept
|
|
||||||
{
|
|
||||||
return BufferType (cast <byte_type*> (),
|
|
||||||
size () - std::min (size(), n));
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
pointer_type m_data;
|
|
||||||
std::size_t m_size;
|
|
||||||
};
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -40,61 +40,159 @@ class Address
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/** Create an unspecified IPv4 address. */
|
/** Create an unspecified IPv4 address. */
|
||||||
Address ();
|
Address ()
|
||||||
|
: m_type (ipv4)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/** Create an IPv4 address. */
|
/** Create an IPv4 address. */
|
||||||
Address (AddressV4 const& addr);
|
Address (AddressV4 const& addr)
|
||||||
|
: m_type (ipv4)
|
||||||
|
, m_v4 (addr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/** Create an IPv6 address. */
|
/** Create an IPv6 address. */
|
||||||
Address (AddressV6 const& addr);
|
Address (AddressV6 const& addr)
|
||||||
|
: m_type (ipv6)
|
||||||
|
, m_v6 (addr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/** Assign a copy from another address in any format. */
|
/** Assign a copy from another address in any format. */
|
||||||
/** @{ */
|
/** @{ */
|
||||||
Address& operator= (AddressV4 const& addr);
|
Address&
|
||||||
Address& operator= (AddressV6 const& addr);
|
operator= (AddressV4 const& addr)
|
||||||
|
{
|
||||||
|
m_type = ipv4;
|
||||||
|
m_v6 = AddressV6();
|
||||||
|
m_v4 = addr;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Address&
|
||||||
|
operator= (AddressV6 const& addr)
|
||||||
|
{
|
||||||
|
m_type = ipv6;
|
||||||
|
m_v4 = AddressV4();
|
||||||
|
m_v6 = addr;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/** Create an Address from a string.
|
/** Create an Address from a string.
|
||||||
@return A pair with the address, and bool set to `true` on success.
|
@return A pair with the address, and bool set to `true` on success.
|
||||||
*/
|
*/
|
||||||
static std::pair <Address, bool> from_string (std::string const& s);
|
static
|
||||||
|
std::pair <Address, bool>
|
||||||
|
from_string (std::string const& s);
|
||||||
|
|
||||||
/** Returns a string representing the address. */
|
/** Returns a string representing the address. */
|
||||||
std::string to_string () const;
|
std::string
|
||||||
|
to_string () const
|
||||||
|
{
|
||||||
|
return (is_v4 ())
|
||||||
|
? IP::to_string (to_v4())
|
||||||
|
: IP::to_string (to_v6());
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns `true` if this address represents an IPv4 address. */
|
/** Returns `true` if this address represents an IPv4 address. */
|
||||||
bool is_v4 () const
|
bool
|
||||||
{ return m_type == ipv4; }
|
is_v4 () const
|
||||||
|
{
|
||||||
|
return m_type == ipv4;
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns `true` if this address represents an IPv6 address. */
|
/** Returns `true` if this address represents an IPv6 address. */
|
||||||
bool is_v6 () const
|
bool
|
||||||
{ return m_type == ipv6; }
|
is_v6() const
|
||||||
|
{
|
||||||
|
return m_type == ipv6;
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns the IPv4 address.
|
/** Returns the IPv4 address.
|
||||||
Precondition:
|
Precondition:
|
||||||
is_v4() returns true
|
is_v4() == `true`
|
||||||
*/
|
*/
|
||||||
AddressV4 const& to_v4 () const;
|
AddressV4 const&
|
||||||
|
to_v4 () const
|
||||||
|
{
|
||||||
|
if (m_type != ipv4)
|
||||||
|
throw std::bad_cast();
|
||||||
|
return m_v4;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Returns the IPv6 address.
|
/** Returns the IPv6 address.
|
||||||
Precondition:
|
Precondition:
|
||||||
is_v6() returns true
|
is_v6() == `true`
|
||||||
*/
|
*/
|
||||||
AddressV6 const& to_v6 () const;
|
AddressV6 const&
|
||||||
|
to_v6 () const
|
||||||
|
{
|
||||||
|
if (m_type != ipv6)
|
||||||
|
throw std::bad_cast();
|
||||||
|
return m_v6;
|
||||||
|
}
|
||||||
|
|
||||||
/** Arithmetic comparison. */
|
/** Arithmetic comparison. */
|
||||||
/** @{ */
|
/** @{ */
|
||||||
friend bool operator== (Address const& lhs, Address const& rhs);
|
friend
|
||||||
friend bool operator< (Address const& lhs, Address const& rhs);
|
bool
|
||||||
|
operator== (Address const& lhs, Address const& rhs)
|
||||||
|
{
|
||||||
|
if (lhs.is_v4 ())
|
||||||
|
{
|
||||||
|
if (rhs.is_v4 ())
|
||||||
|
return lhs.to_v4() == rhs.to_v4();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (rhs.is_v6 ())
|
||||||
|
return lhs.to_v6() == rhs.to_v6();
|
||||||
|
}
|
||||||
|
|
||||||
friend bool operator!= (Address const& lhs, Address const& rhs)
|
return false;
|
||||||
{ return ! (lhs == rhs); }
|
}
|
||||||
friend bool operator> (Address const& lhs, Address const& rhs)
|
|
||||||
{ return rhs < lhs; }
|
friend
|
||||||
friend bool operator<= (Address const& lhs, Address const& rhs)
|
bool
|
||||||
{ return ! (lhs > rhs); }
|
operator< (Address const& lhs, Address const& rhs)
|
||||||
friend bool operator>= (Address const& lhs, Address const& rhs)
|
{
|
||||||
{ return ! (rhs > lhs); }
|
if (lhs.m_type < rhs.m_type)
|
||||||
|
return true;
|
||||||
|
if (lhs.is_v4 ())
|
||||||
|
return lhs.to_v4() < rhs.to_v4();
|
||||||
|
return lhs.to_v6() < rhs.to_v6();
|
||||||
|
}
|
||||||
|
|
||||||
|
friend
|
||||||
|
bool
|
||||||
|
operator!= (Address const& lhs, Address const& rhs)
|
||||||
|
{
|
||||||
|
return ! (lhs == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend
|
||||||
|
bool
|
||||||
|
operator> (Address const& lhs, Address const& rhs)
|
||||||
|
{
|
||||||
|
return rhs < lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend
|
||||||
|
bool
|
||||||
|
operator<= (Address const& lhs, Address const& rhs)
|
||||||
|
{
|
||||||
|
return ! (lhs > rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend
|
||||||
|
bool
|
||||||
|
operator>= (Address const& lhs, Address const& rhs)
|
||||||
|
{
|
||||||
|
return ! (rhs > lhs);
|
||||||
|
}
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -114,36 +212,104 @@ private:
|
|||||||
// Properties
|
// Properties
|
||||||
|
|
||||||
/** Returns `true` if this is a loopback address. */
|
/** Returns `true` if this is a loopback address. */
|
||||||
bool is_loopback (Address const& addr);
|
inline
|
||||||
|
bool
|
||||||
|
is_loopback (Address const& addr)
|
||||||
|
{
|
||||||
|
return (addr.is_v4 ())
|
||||||
|
? is_loopback (addr.to_v4 ())
|
||||||
|
: is_loopback (addr.to_v6 ());
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns `true` if the address is unspecified. */
|
/** Returns `true` if the address is unspecified. */
|
||||||
bool is_unspecified (Address const& addr);
|
inline
|
||||||
|
bool
|
||||||
|
is_unspecified (Address const& addr)
|
||||||
|
{
|
||||||
|
return (addr.is_v4 ())
|
||||||
|
? is_unspecified (addr.to_v4 ())
|
||||||
|
: is_unspecified (addr.to_v6 ());
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns `true` if the address is a multicast address. */
|
/** Returns `true` if the address is a multicast address. */
|
||||||
bool is_multicast (Address const& addr);
|
inline
|
||||||
|
bool
|
||||||
|
is_multicast (Address const& addr)
|
||||||
|
{
|
||||||
|
return (addr.is_v4 ())
|
||||||
|
? is_multicast (addr.to_v4 ())
|
||||||
|
: is_multicast (addr.to_v6 ());
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns `true` if the address is a private unroutable address. */
|
/** Returns `true` if the address is a private unroutable address. */
|
||||||
bool is_private (Address const& addr);
|
inline
|
||||||
|
bool
|
||||||
|
is_private (Address const& addr)
|
||||||
|
{
|
||||||
|
return (addr.is_v4 ())
|
||||||
|
? is_private (addr.to_v4 ())
|
||||||
|
: is_private (addr.to_v6 ());
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns `true` if the address is a public routable address. */
|
/** Returns `true` if the address is a public routable address. */
|
||||||
bool is_public (Address const& addr);
|
inline
|
||||||
|
bool
|
||||||
|
is_public (Address const& addr)
|
||||||
|
{
|
||||||
|
return (addr.is_v4 ())
|
||||||
|
? is_public (addr.to_v4 ())
|
||||||
|
: is_public (addr.to_v6 ());
|
||||||
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
/** boost::hash support. */
|
/** boost::hash support. */
|
||||||
std::size_t hash_value (Address const& addr);
|
inline
|
||||||
|
std::size_t
|
||||||
|
hash_value (Address const& addr)
|
||||||
|
{
|
||||||
|
return (addr.is_v4 ())
|
||||||
|
? hash_value (addr.to_v4())
|
||||||
|
: hash_value (addr.to_v6());
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns the address represented as a string. */
|
/** Returns the address represented as a string. */
|
||||||
inline std::string to_string (Address const& addr)
|
inline std::string to_string (Address const& addr)
|
||||||
{ return addr.to_string (); }
|
{
|
||||||
|
return addr.to_string ();
|
||||||
|
}
|
||||||
|
|
||||||
/** Output stream conversion. */
|
/** Output stream conversion. */
|
||||||
template <typename OutputStream>
|
template <typename OutputStream>
|
||||||
OutputStream& operator<< (OutputStream& os, Address const& addr)
|
OutputStream&
|
||||||
{ return os << to_string (addr); }
|
operator<< (OutputStream& os, Address const& addr)
|
||||||
|
{
|
||||||
|
return os << to_string (addr);
|
||||||
|
}
|
||||||
|
|
||||||
/** Input stream conversion. */
|
/** Input stream conversion. */
|
||||||
std::istream& operator>> (std::istream& is, Address& addr);
|
inline
|
||||||
|
std::istream&
|
||||||
|
operator>> (std::istream& is, Address& addr)
|
||||||
|
{
|
||||||
|
// VFALCO TODO Support ipv6!
|
||||||
|
AddressV4 addrv4;
|
||||||
|
is >> addrv4;
|
||||||
|
addr = Address (addrv4);
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
std::pair <Address, bool>
|
||||||
|
Address::from_string (std::string const& s)
|
||||||
|
{
|
||||||
|
std::stringstream is (s);
|
||||||
|
Address addr;
|
||||||
|
is >> addr;
|
||||||
|
if (! is.fail() && is.rdbuf()->in_avail() == 0)
|
||||||
|
return std::make_pair (addr, true);
|
||||||
|
return std::make_pair (Address (), false);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -154,8 +320,11 @@ namespace std {
|
|||||||
template <>
|
template <>
|
||||||
struct hash <beast::IP::Address>
|
struct hash <beast::IP::Address>
|
||||||
{
|
{
|
||||||
std::size_t operator() (beast::IP::Address const& addr) const
|
std::size_t
|
||||||
{ return hash_value (addr); }
|
operator() (beast::IP::Address const& addr) const
|
||||||
|
{
|
||||||
|
return hash_value (addr);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,150 +25,6 @@
|
|||||||
namespace beast {
|
namespace beast {
|
||||||
namespace IP {
|
namespace IP {
|
||||||
|
|
||||||
Address::Address ()
|
|
||||||
: m_type (ipv4)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Address::Address (AddressV4 const& addr)
|
|
||||||
: m_type (ipv4)
|
|
||||||
, m_v4 (addr)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Address::Address (AddressV6 const& addr)
|
|
||||||
: m_type (ipv6)
|
|
||||||
, m_v6 (addr)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Address& Address::operator= (AddressV4 const& addr)
|
|
||||||
{
|
|
||||||
m_type = ipv4;
|
|
||||||
m_v6 = AddressV6();
|
|
||||||
m_v4 = addr;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
Address& Address::operator= (AddressV6 const& addr)
|
|
||||||
{
|
|
||||||
m_type = ipv6;
|
|
||||||
m_v4 = AddressV4();
|
|
||||||
m_v6 = addr;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::pair <Address, bool> Address::from_string (std::string const& s)
|
|
||||||
{
|
|
||||||
std::stringstream is (s);
|
|
||||||
Address addr;
|
|
||||||
is >> addr;
|
|
||||||
if (! is.fail() && is.rdbuf()->in_avail() == 0)
|
|
||||||
return std::make_pair (addr, true);
|
|
||||||
return std::make_pair (Address (), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Address::to_string () const
|
|
||||||
{
|
|
||||||
return (is_v4 ())
|
|
||||||
? IP::to_string (to_v4())
|
|
||||||
: IP::to_string (to_v6());
|
|
||||||
}
|
|
||||||
|
|
||||||
AddressV4 const& Address::to_v4 () const
|
|
||||||
{
|
|
||||||
if (m_type != ipv4)
|
|
||||||
throw std::bad_cast();
|
|
||||||
return m_v4;
|
|
||||||
}
|
|
||||||
|
|
||||||
AddressV6 const& Address::to_v6 () const
|
|
||||||
{
|
|
||||||
if (m_type != ipv6)
|
|
||||||
throw std::bad_cast();
|
|
||||||
return m_v6;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator== (Address const& lhs, Address const& rhs)
|
|
||||||
{
|
|
||||||
if (lhs.is_v4 ())
|
|
||||||
{
|
|
||||||
if (rhs.is_v4 ())
|
|
||||||
return lhs.to_v4() == rhs.to_v4();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (rhs.is_v6 ())
|
|
||||||
return lhs.to_v6() == rhs.to_v6();
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator< (Address const& lhs, Address const& rhs)
|
|
||||||
{
|
|
||||||
if (lhs.m_type < rhs.m_type)
|
|
||||||
return true;
|
|
||||||
if (lhs.is_v4 ())
|
|
||||||
return lhs.to_v4() < rhs.to_v4();
|
|
||||||
return lhs.to_v6() < rhs.to_v6();
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
bool is_loopback (Address const& addr)
|
|
||||||
{
|
|
||||||
return (addr.is_v4 ())
|
|
||||||
? is_loopback (addr.to_v4 ())
|
|
||||||
: is_loopback (addr.to_v6 ());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_unspecified (Address const& addr)
|
|
||||||
{
|
|
||||||
return (addr.is_v4 ())
|
|
||||||
? is_unspecified (addr.to_v4 ())
|
|
||||||
: is_unspecified (addr.to_v6 ());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_multicast (Address const& addr)
|
|
||||||
{
|
|
||||||
return (addr.is_v4 ())
|
|
||||||
? is_multicast (addr.to_v4 ())
|
|
||||||
: is_multicast (addr.to_v6 ());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_private (Address const& addr)
|
|
||||||
{
|
|
||||||
return (addr.is_v4 ())
|
|
||||||
? is_private (addr.to_v4 ())
|
|
||||||
: is_private (addr.to_v6 ());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_public (Address const& addr)
|
|
||||||
{
|
|
||||||
return (addr.is_v4 ())
|
|
||||||
? is_public (addr.to_v4 ())
|
|
||||||
: is_public (addr.to_v6 ());
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
std::size_t hash_value (Address const& addr)
|
|
||||||
{
|
|
||||||
return (addr.is_v4 ())
|
|
||||||
? hash_value (addr.to_v4())
|
|
||||||
: hash_value (addr.to_v6());
|
|
||||||
}
|
|
||||||
|
|
||||||
std::istream& operator>> (std::istream& is, Address& addr)
|
|
||||||
{
|
|
||||||
// VFALCO TODO Support ipv6!
|
|
||||||
AddressV4 addrv4;
|
|
||||||
is >> addrv4;
|
|
||||||
addr = Address (addrv4);
|
|
||||||
return is;
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
class IPAddressTests : public UnitTest
|
class IPAddressTests : public UnitTest
|
||||||
|
|||||||
@@ -1,50 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_THREADS_LOCKGUARD_H_INCLUDED
|
|
||||||
#define BEAST_THREADS_LOCKGUARD_H_INCLUDED
|
|
||||||
|
|
||||||
#include "../Uncopyable.h"
|
|
||||||
|
|
||||||
namespace beast {
|
|
||||||
|
|
||||||
template <typename Mutex>
|
|
||||||
class LockGuard : public Uncopyable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef Mutex MutexType;
|
|
||||||
|
|
||||||
explicit LockGuard (Mutex const& mutex)
|
|
||||||
: m_mutex (mutex)
|
|
||||||
{
|
|
||||||
m_mutex.lock();
|
|
||||||
}
|
|
||||||
|
|
||||||
~LockGuard ()
|
|
||||||
{
|
|
||||||
m_mutex.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Mutex const& m_mutex;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -25,10 +25,11 @@
|
|||||||
#define BEAST_THREADS_RECURSIVEMUTEX_H_INCLUDED
|
#define BEAST_THREADS_RECURSIVEMUTEX_H_INCLUDED
|
||||||
|
|
||||||
#include "../Config.h"
|
#include "../Config.h"
|
||||||
#include "LockGuard.h"
|
|
||||||
#include "UnlockGuard.h"
|
#include "UnlockGuard.h"
|
||||||
#include "TryLockGuard.h"
|
#include "TryLockGuard.h"
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
#if ! BEAST_WINDOWS
|
#if ! BEAST_WINDOWS
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -38,7 +39,7 @@ namespace beast {
|
|||||||
class RecursiveMutex
|
class RecursiveMutex
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef LockGuard <RecursiveMutex> ScopedLockType;
|
typedef std::lock_guard <RecursiveMutex> ScopedLockType;
|
||||||
typedef UnlockGuard <RecursiveMutex> ScopedUnlockType;
|
typedef UnlockGuard <RecursiveMutex> ScopedUnlockType;
|
||||||
typedef TryLockGuard <RecursiveMutex> ScopedTryLockType;
|
typedef TryLockGuard <RecursiveMutex> ScopedTryLockType;
|
||||||
|
|
||||||
|
|||||||
@@ -30,19 +30,20 @@ template <typename ScopedType, typename Context, typename Handler>
|
|||||||
class ScopedWrapper
|
class ScopedWrapper
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ScopedWrapper (Context const& context, Handler const& handler)
|
ScopedWrapper (Context& context, Handler const& handler)
|
||||||
: m_context (context)
|
: m_context (context)
|
||||||
, m_handler (handler)
|
, m_handler (handler)
|
||||||
{ }
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void operator() ()
|
void operator() ()
|
||||||
{
|
{
|
||||||
ScopedType const scope (m_context);
|
ScopedType scope (m_context);
|
||||||
m_handler();
|
m_handler();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Context const& m_context;
|
Context& m_context;
|
||||||
Handler m_handler;
|
Handler m_handler;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -63,9 +64,11 @@ public:
|
|||||||
public:
|
public:
|
||||||
explicit Scope (ScopedWrapperContext const& owner)
|
explicit Scope (ScopedWrapperContext const& owner)
|
||||||
: m_scope (owner.m_context)
|
: m_scope (owner.m_context)
|
||||||
{ }
|
{
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
scoped_type m_scope;
|
scoped_type mutable m_scope;
|
||||||
};
|
};
|
||||||
|
|
||||||
ScopedWrapperContext ()
|
ScopedWrapperContext ()
|
||||||
@@ -74,7 +77,8 @@ public:
|
|||||||
template <typename Arg>
|
template <typename Arg>
|
||||||
explicit ScopedWrapperContext (Arg& arg)
|
explicit ScopedWrapperContext (Arg& arg)
|
||||||
: m_context (arg)
|
: m_context (arg)
|
||||||
{ }
|
{
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Handler>
|
template <typename Handler>
|
||||||
detail::ScopedWrapper <ScopedType, Context, Handler> wrap (
|
detail::ScopedWrapper <ScopedType, Context, Handler> wrap (
|
||||||
@@ -85,7 +89,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Context m_context;
|
Context mutable m_context;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,9 +20,10 @@
|
|||||||
#ifndef BEAST_THREADS_SHAREDMUTEXADAPTER_H_INCLUDED
|
#ifndef BEAST_THREADS_SHAREDMUTEXADAPTER_H_INCLUDED
|
||||||
#define BEAST_THREADS_SHAREDMUTEXADAPTER_H_INCLUDED
|
#define BEAST_THREADS_SHAREDMUTEXADAPTER_H_INCLUDED
|
||||||
|
|
||||||
#include "LockGuard.h"
|
|
||||||
#include "SharedLockGuard.h"
|
#include "SharedLockGuard.h"
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
namespace beast {
|
namespace beast {
|
||||||
|
|
||||||
/** Adapts a regular Lockable to conform to the SharedMutex concept.
|
/** Adapts a regular Lockable to conform to the SharedMutex concept.
|
||||||
@@ -35,7 +36,7 @@ class SharedMutexAdapter
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef Mutex MutexType;
|
typedef Mutex MutexType;
|
||||||
typedef LockGuard <SharedMutexAdapter> LockGuardType;
|
typedef std::lock_guard <SharedMutexAdapter> LockGuardType;
|
||||||
typedef SharedLockGuard <SharedMutexAdapter> SharedLockGuardType;
|
typedef SharedLockGuard <SharedMutexAdapter> SharedLockGuardType;
|
||||||
|
|
||||||
void lock() const
|
void lock() const
|
||||||
|
|||||||
@@ -25,9 +25,10 @@
|
|||||||
#define BEAST_THREADS_SPINLOCK_H_INCLUDED
|
#define BEAST_THREADS_SPINLOCK_H_INCLUDED
|
||||||
|
|
||||||
#include "../Atomic.h"
|
#include "../Atomic.h"
|
||||||
#include "LockGuard.h"
|
|
||||||
#include "UnlockGuard.h"
|
#include "UnlockGuard.h"
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
namespace beast {
|
namespace beast {
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
@@ -47,7 +48,7 @@ class BEAST_API SpinLock : public Uncopyable
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/** Provides the type of scoped lock to use for locking a SpinLock. */
|
/** Provides the type of scoped lock to use for locking a SpinLock. */
|
||||||
typedef LockGuard <SpinLock> ScopedLockType;
|
typedef std::lock_guard <SpinLock> ScopedLockType;
|
||||||
|
|
||||||
/** Provides the type of scoped unlocker to use with a SpinLock. */
|
/** Provides the type of scoped unlocker to use with a SpinLock. */
|
||||||
typedef UnlockGuard <SpinLock> ScopedUnlockType;
|
typedef UnlockGuard <SpinLock> ScopedUnlockType;
|
||||||
|
|||||||
@@ -187,8 +187,8 @@ private:
|
|||||||
Type object;
|
Type object;
|
||||||
};
|
};
|
||||||
|
|
||||||
mutable Atomic<ObjectHolder*> first;
|
Atomic<ObjectHolder*> mutable first;
|
||||||
SpinLock lock;
|
SpinLock mutable lock;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,10 @@ struct maybe_const
|
|||||||
typename std::remove_const <T>::type>::type type;
|
typename std::remove_const <T>::type>::type type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Alias for omitting `typename`. */
|
||||||
|
template <bool IsConst, class T>
|
||||||
|
using maybe_const_t = typename maybe_const <IsConst,T>::type;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
|
|
||||||
#include "../Config.h"
|
#include "../Config.h"
|
||||||
|
|
||||||
#include "../SafeBool.h"
|
|
||||||
#include "../strings/String.h"
|
#include "../strings/String.h"
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
@@ -43,7 +42,6 @@ namespace beast {
|
|||||||
*/
|
*/
|
||||||
class Error
|
class Error
|
||||||
: public std::exception
|
: public std::exception
|
||||||
, public SafeBool <Error>
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/** Numeric code.
|
/** Numeric code.
|
||||||
@@ -88,7 +86,10 @@ public:
|
|||||||
Code code () const;
|
Code code () const;
|
||||||
bool failed () const;
|
bool failed () const;
|
||||||
|
|
||||||
bool asBoolean () const;
|
explicit operator bool () const
|
||||||
|
{
|
||||||
|
return code () != success;
|
||||||
|
}
|
||||||
|
|
||||||
String const getReasonText () const;
|
String const getReasonText () const;
|
||||||
String const getSourceFilename () const;
|
String const getSourceFilename () const;
|
||||||
|
|||||||
@@ -20,8 +20,6 @@
|
|||||||
#ifndef BEAST_UTILITY_JOURNAL_H_INCLUDED
|
#ifndef BEAST_UTILITY_JOURNAL_H_INCLUDED
|
||||||
#define BEAST_UTILITY_JOURNAL_H_INCLUDED
|
#define BEAST_UTILITY_JOURNAL_H_INCLUDED
|
||||||
|
|
||||||
#include "../SafeBool.h"
|
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
namespace beast {
|
namespace beast {
|
||||||
@@ -150,7 +148,7 @@ public:
|
|||||||
|
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
class Stream : public SafeBool <Stream>
|
class Stream
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/** Create a stream which produces no output. */
|
/** Create a stream which produces no output. */
|
||||||
@@ -177,7 +175,12 @@ public:
|
|||||||
/** Returns `true` if sink logs anything at this stream's severity. */
|
/** Returns `true` if sink logs anything at this stream's severity. */
|
||||||
/** @{ */
|
/** @{ */
|
||||||
bool active() const;
|
bool active() const;
|
||||||
bool asBoolean() const;
|
|
||||||
|
explicit
|
||||||
|
operator bool() const
|
||||||
|
{
|
||||||
|
return ! m_disabled;
|
||||||
|
}
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/** Output stream support. */
|
/** Output stream support. */
|
||||||
|
|||||||
@@ -81,11 +81,6 @@ bool Error::failed () const
|
|||||||
return code () != success;
|
return code () != success;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Error::asBoolean () const
|
|
||||||
{
|
|
||||||
return code () != success;
|
|
||||||
}
|
|
||||||
|
|
||||||
String const Error::getReasonText () const
|
String const Error::getReasonText () const
|
||||||
{
|
{
|
||||||
return m_reasonText;
|
return m_reasonText;
|
||||||
|
|||||||
@@ -211,11 +211,6 @@ bool Journal::Stream::active () const
|
|||||||
return ! m_disabled && m_sink->active (m_level);
|
return ! m_disabled && m_sink->active (m_level);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Journal::Stream::asBoolean () const
|
|
||||||
{
|
|
||||||
return active();
|
|
||||||
}
|
|
||||||
|
|
||||||
Journal::Stream& Journal::Stream::operator= (Stream const& other)
|
Journal::Stream& Journal::Stream::operator= (Stream const& other)
|
||||||
{
|
{
|
||||||
m_sink = other.m_sink;
|
m_sink = other.m_sink;
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ namespace InputParser {
|
|||||||
Or you can use stop() to decide if you should return.
|
Or you can use stop() to decide if you should return.
|
||||||
After a stop you can use failed () to determine if parsing failed.
|
After a stop you can use failed () to determine if parsing failed.
|
||||||
*/
|
*/
|
||||||
struct State : SafeBool <State>
|
struct State
|
||||||
{
|
{
|
||||||
enum State_t
|
enum State_t
|
||||||
{
|
{
|
||||||
@@ -54,7 +54,7 @@ struct State : SafeBool <State>
|
|||||||
bool stop () const noexcept { return m_state != pass; }
|
bool stop () const noexcept { return m_state != pass; }
|
||||||
bool passed () const noexcept { return m_state == pass; }
|
bool passed () const noexcept { return m_state == pass; }
|
||||||
bool failed () const noexcept { return m_state == fail; }
|
bool failed () const noexcept { return m_state == fail; }
|
||||||
bool asBoolean () const noexcept { return m_state == pass; } // for SafeBool<>
|
explicit operator bool() const noexcept { return m_state == pass; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
State_t m_state;
|
State_t m_state;
|
||||||
|
|||||||
@@ -163,7 +163,6 @@ namespace beast
|
|||||||
#include "misc/Uuid.cpp"
|
#include "misc/Uuid.cpp"
|
||||||
|
|
||||||
#include "network/MACAddress.cpp"
|
#include "network/MACAddress.cpp"
|
||||||
#include "network/NamedPipe.cpp"
|
|
||||||
#include "network/Socket.cpp"
|
#include "network/Socket.cpp"
|
||||||
|
|
||||||
#include "streams/BufferedInputStream.cpp"
|
#include "streams/BufferedInputStream.cpp"
|
||||||
@@ -188,7 +187,6 @@ namespace beast
|
|||||||
#include "thread/Workers.cpp"
|
#include "thread/Workers.cpp"
|
||||||
|
|
||||||
#include "threads/ChildProcess.cpp"
|
#include "threads/ChildProcess.cpp"
|
||||||
#include "threads/ReadWriteLock.cpp"
|
|
||||||
#include "threads/SpinDelay.cpp"
|
#include "threads/SpinDelay.cpp"
|
||||||
|
|
||||||
#include "time/PerformanceCounter.cpp"
|
#include "time/PerformanceCounter.cpp"
|
||||||
@@ -218,7 +216,6 @@ namespace beast
|
|||||||
|
|
||||||
#if ! BEAST_WINDOWS
|
#if ! BEAST_WINDOWS
|
||||||
#include "native/posix_SharedCode.h"
|
#include "native/posix_SharedCode.h"
|
||||||
#include "native/posix_NamedPipe.cpp"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if BEAST_MAC || BEAST_IOS
|
#if BEAST_MAC || BEAST_IOS
|
||||||
|
|||||||
@@ -55,7 +55,6 @@
|
|||||||
#include "../../beast/Memory.h"
|
#include "../../beast/Memory.h"
|
||||||
#include "../../beast/Intrusive.h"
|
#include "../../beast/Intrusive.h"
|
||||||
#include "../../beast/Net.h"
|
#include "../../beast/Net.h"
|
||||||
#include "../../beast/SafeBool.h"
|
|
||||||
#include "../../beast/Strings.h"
|
#include "../../beast/Strings.h"
|
||||||
#include "../../beast/TypeTraits.h"
|
#include "../../beast/TypeTraits.h"
|
||||||
#include "../../beast/Threads.h"
|
#include "../../beast/Threads.h"
|
||||||
@@ -181,8 +180,6 @@ class FileOutputStream;
|
|||||||
#include "misc/Uuid.h"
|
#include "misc/Uuid.h"
|
||||||
#include "misc/WindowsRegistry.h"
|
#include "misc/WindowsRegistry.h"
|
||||||
#include "network/MACAddress.h"
|
#include "network/MACAddress.h"
|
||||||
#include "threads/ReadWriteLock.h"
|
|
||||||
#include "network/NamedPipe.h"
|
|
||||||
#include "network/Socket.h"
|
#include "network/Socket.h"
|
||||||
#include "streams/BufferedInputStream.h"
|
#include "streams/BufferedInputStream.h"
|
||||||
#include "streams/MemoryInputStream.h"
|
#include "streams/MemoryInputStream.h"
|
||||||
@@ -198,8 +195,6 @@ class FileOutputStream;
|
|||||||
#include "threads/HighResolutionTimer.h"
|
#include "threads/HighResolutionTimer.h"
|
||||||
#include "threads/InterProcessLock.h"
|
#include "threads/InterProcessLock.h"
|
||||||
#include "threads/Process.h"
|
#include "threads/Process.h"
|
||||||
#include "threads/ScopedReadLock.h"
|
|
||||||
#include "threads/ScopedWriteLock.h"
|
|
||||||
#include "diagnostic/UnitTest.h"
|
#include "diagnostic/UnitTest.h"
|
||||||
#include "xml/XmlDocument.h"
|
#include "xml/XmlDocument.h"
|
||||||
#include "xml/XmlElement.h"
|
#include "xml/XmlElement.h"
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ void UnitTest::beginTestCase (String const& name)
|
|||||||
m_case = new Case (name, m_className);
|
m_case = new Case (name, m_className);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UnitTest::expect (bool trueCondition, String const& failureMessage)
|
bool UnitTest::expect_bool (bool trueCondition, String const& failureMessage)
|
||||||
{
|
{
|
||||||
if (trueCondition)
|
if (trueCondition)
|
||||||
{
|
{
|
||||||
@@ -144,7 +144,7 @@ bool UnitTest::expect (bool trueCondition, String const& failureMessage)
|
|||||||
return trueCondition;
|
return trueCondition;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UnitTest::unexpected (bool falseCondition, String const& failureMessage)
|
bool UnitTest::unexpected_bool (bool falseCondition, String const& failureMessage)
|
||||||
{
|
{
|
||||||
return expect (! falseCondition, failureMessage);
|
return expect (! falseCondition, failureMessage);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -266,16 +266,34 @@ public:
|
|||||||
|
|
||||||
If Suite is true, a pass is logged; if it's false, a failure is logged.
|
If Suite is true, a pass is logged; if it's false, a failure is logged.
|
||||||
If the failure message is specified, it will be written to the log if the test fails.
|
If the failure message is specified, it will be written to the log if the test fails.
|
||||||
|
|
||||||
|
Requirements:
|
||||||
|
Condition must be explicitly convertible to bool
|
||||||
*/
|
*/
|
||||||
bool expect (bool trueCondition, String const& failureMessage = String::empty);
|
template <class Condition>
|
||||||
|
bool expect (Condition trueCondition, String const& failureMessage = String::empty)
|
||||||
|
{
|
||||||
|
return expect_bool (!!trueCondition, failureMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool expect_bool (bool trueCondition, String const& failureMessage);
|
||||||
|
|
||||||
/** Checks that the result of a test is false, and logs this result.
|
/** Checks that the result of a test is false, and logs this result.
|
||||||
|
|
||||||
This is basically the opposite of expect().
|
This is basically the opposite of expect().
|
||||||
|
|
||||||
@see expect
|
@see expect
|
||||||
|
|
||||||
|
Requirements:
|
||||||
|
Condition must be explicitly convertible to bool
|
||||||
*/
|
*/
|
||||||
bool unexpected (bool falseCondition, String const& failureMessage = String::empty);
|
template <class Condition>
|
||||||
|
bool unexpected (Condition falseCondition, String const& failureMessage = String::empty)
|
||||||
|
{
|
||||||
|
return unexpected_bool (!!falseCondition, failureMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool unexpected_bool (bool falseCondition, String const& failureMessage);
|
||||||
|
|
||||||
/** Compares two values, and if they don't match, prints out a message containing the
|
/** Compares two values, and if they don't match, prints out a message containing the
|
||||||
expected and actual result values.
|
expected and actual result values.
|
||||||
|
|||||||
@@ -1,212 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Portions of this file are from JUCE.
|
|
||||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
|
||||||
Please visit http://www.juce.com
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
class NamedPipe::Pimpl : LeakChecked <Pimpl>, public Uncopyable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Pimpl (const String& pipePath, bool createPipe)
|
|
||||||
: pipeInName (pipePath + "_in"),
|
|
||||||
pipeOutName (pipePath + "_out"),
|
|
||||||
pipeIn (-1), pipeOut (-1),
|
|
||||||
createdPipe (createPipe),
|
|
||||||
stopReadOperation (false)
|
|
||||||
{
|
|
||||||
signal (SIGPIPE, signalHandler);
|
|
||||||
beast_siginterrupt (SIGPIPE, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
~Pimpl()
|
|
||||||
{
|
|
||||||
if (pipeIn != -1) ::close (pipeIn);
|
|
||||||
if (pipeOut != -1) ::close (pipeOut);
|
|
||||||
|
|
||||||
if (createdPipe)
|
|
||||||
{
|
|
||||||
unlink (pipeInName.toUTF8());
|
|
||||||
unlink (pipeOutName.toUTF8());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int read (char* destBuffer, int maxBytesToRead, int timeOutMilliseconds)
|
|
||||||
{
|
|
||||||
const uint32 timeoutEnd = getTimeoutEnd (timeOutMilliseconds);
|
|
||||||
|
|
||||||
if (pipeIn == -1)
|
|
||||||
{
|
|
||||||
pipeIn = openPipe (createdPipe ? pipeInName : pipeOutName, O_RDWR | O_NONBLOCK, timeoutEnd);
|
|
||||||
|
|
||||||
if (pipeIn == -1)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bytesRead = 0;
|
|
||||||
|
|
||||||
while (bytesRead < maxBytesToRead)
|
|
||||||
{
|
|
||||||
const int bytesThisTime = maxBytesToRead - bytesRead;
|
|
||||||
const int numRead = (int) ::read (pipeIn, destBuffer, (size_t) bytesThisTime);
|
|
||||||
|
|
||||||
if (numRead <= 0)
|
|
||||||
{
|
|
||||||
if (errno != EWOULDBLOCK || stopReadOperation || hasExpired (timeoutEnd))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
const int maxWaitingTime = 30;
|
|
||||||
waitForInput (pipeIn, timeoutEnd == 0 ? maxWaitingTime
|
|
||||||
: bmin (maxWaitingTime,
|
|
||||||
(int) (timeoutEnd - Time::getMillisecondCounter())));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
bytesRead += numRead;
|
|
||||||
destBuffer += numRead;
|
|
||||||
}
|
|
||||||
|
|
||||||
return bytesRead;
|
|
||||||
}
|
|
||||||
|
|
||||||
int write (const char* sourceBuffer, int numBytesToWrite, int timeOutMilliseconds)
|
|
||||||
{
|
|
||||||
const uint32 timeoutEnd = getTimeoutEnd (timeOutMilliseconds);
|
|
||||||
|
|
||||||
if (pipeOut == -1)
|
|
||||||
{
|
|
||||||
pipeOut = openPipe (createdPipe ? pipeOutName : pipeInName, O_WRONLY, timeoutEnd);
|
|
||||||
|
|
||||||
if (pipeOut == -1)
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bytesWritten = 0;
|
|
||||||
|
|
||||||
while (bytesWritten < numBytesToWrite && ! hasExpired (timeoutEnd))
|
|
||||||
{
|
|
||||||
const int bytesThisTime = numBytesToWrite - bytesWritten;
|
|
||||||
const int numWritten = (int) ::write (pipeOut, sourceBuffer, (size_t) bytesThisTime);
|
|
||||||
|
|
||||||
if (numWritten <= 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
bytesWritten += numWritten;
|
|
||||||
sourceBuffer += numWritten;
|
|
||||||
}
|
|
||||||
|
|
||||||
return bytesWritten;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool createFifos() const
|
|
||||||
{
|
|
||||||
return (mkfifo (pipeInName .toUTF8(), 0666) == 0 || errno == EEXIST)
|
|
||||||
&& (mkfifo (pipeOutName.toUTF8(), 0666) == 0 || errno == EEXIST);
|
|
||||||
}
|
|
||||||
|
|
||||||
const String pipeInName, pipeOutName;
|
|
||||||
int pipeIn, pipeOut;
|
|
||||||
|
|
||||||
const bool createdPipe;
|
|
||||||
bool stopReadOperation;
|
|
||||||
|
|
||||||
private:
|
|
||||||
static void signalHandler (int) {}
|
|
||||||
|
|
||||||
static uint32 getTimeoutEnd (const int timeOutMilliseconds)
|
|
||||||
{
|
|
||||||
return timeOutMilliseconds >= 0 ? Time::getMillisecondCounter() + (uint32) timeOutMilliseconds : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool hasExpired (const uint32 timeoutEnd)
|
|
||||||
{
|
|
||||||
return timeoutEnd != 0 && Time::getMillisecondCounter() >= timeoutEnd;
|
|
||||||
}
|
|
||||||
|
|
||||||
int openPipe (const String& name, int flags, const uint32 timeoutEnd)
|
|
||||||
{
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
const int p = ::open (name.toUTF8(), flags);
|
|
||||||
|
|
||||||
if (p != -1 || hasExpired (timeoutEnd) || stopReadOperation)
|
|
||||||
return p;
|
|
||||||
|
|
||||||
Thread::sleep (2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void waitForInput (const int handle, const int timeoutMsecs) noexcept
|
|
||||||
{
|
|
||||||
struct timeval timeout;
|
|
||||||
timeout.tv_sec = timeoutMsecs / 1000;
|
|
||||||
timeout.tv_usec = (timeoutMsecs % 1000) * 1000;
|
|
||||||
|
|
||||||
fd_set rset;
|
|
||||||
FD_ZERO (&rset);
|
|
||||||
FD_SET (handle, &rset);
|
|
||||||
|
|
||||||
select (handle + 1, &rset, nullptr, 0, &timeout);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void NamedPipe::close()
|
|
||||||
{
|
|
||||||
if (pimpl != nullptr)
|
|
||||||
{
|
|
||||||
pimpl->stopReadOperation = true;
|
|
||||||
|
|
||||||
char buffer[1] = { 0 };
|
|
||||||
ssize_t done = ::write (pimpl->pipeIn, buffer, 1);
|
|
||||||
(void) done;
|
|
||||||
|
|
||||||
ScopedWriteLock sl (lock);
|
|
||||||
pimpl = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NamedPipe::openInternal (const String& pipeName, const bool createPipe)
|
|
||||||
{
|
|
||||||
#if BEAST_IOS
|
|
||||||
pimpl = new Pimpl (File::getSpecialLocation (File::tempDirectory)
|
|
||||||
.getChildFile (File::createLegalFileName (pipeName)).getFullPathName(), createPipe);
|
|
||||||
#else
|
|
||||||
pimpl = new Pimpl ("/tmp/" + File::createLegalFileName (pipeName), createPipe);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (createPipe && ! pimpl->createFifos())
|
|
||||||
{
|
|
||||||
pimpl = nullptr;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int NamedPipe::read (void* destBuffer, int maxBytesToRead, int timeOutMilliseconds)
|
|
||||||
{
|
|
||||||
ScopedReadLock sl (lock);
|
|
||||||
return pimpl != nullptr ? pimpl->read (static_cast <char*> (destBuffer), maxBytesToRead, timeOutMilliseconds) : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int NamedPipe::write (const void* sourceBuffer, int numBytesToWrite, int timeOutMilliseconds)
|
|
||||||
{
|
|
||||||
ScopedReadLock sl (lock);
|
|
||||||
return pimpl != nullptr ? pimpl->write (static_cast <const char*> (sourceBuffer), numBytesToWrite, timeOutMilliseconds) : -1;
|
|
||||||
}
|
|
||||||
@@ -883,226 +883,3 @@ void File::revealToUser() const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
class NamedPipe::Pimpl : LeakChecked <NamedPipe::Pimpl>, public Uncopyable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Pimpl (const String& pipeName, const bool createPipe)
|
|
||||||
: filename ("\\\\.\\pipe\\" + File::createLegalFileName (pipeName)),
|
|
||||||
pipeH (INVALID_HANDLE_VALUE),
|
|
||||||
cancelEvent (CreateEvent (0, FALSE, FALSE, 0)),
|
|
||||||
connected (false), ownsPipe (createPipe), shouldStop (false)
|
|
||||||
{
|
|
||||||
if (createPipe)
|
|
||||||
pipeH = CreateNamedPipe (filename.toWideCharPointer(),
|
|
||||||
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, 0,
|
|
||||||
PIPE_UNLIMITED_INSTANCES, 4096, 4096, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
~Pimpl()
|
|
||||||
{
|
|
||||||
disconnectPipe();
|
|
||||||
|
|
||||||
if (pipeH != INVALID_HANDLE_VALUE)
|
|
||||||
CloseHandle (pipeH);
|
|
||||||
|
|
||||||
CloseHandle (cancelEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool connect (const int timeOutMs)
|
|
||||||
{
|
|
||||||
if (! ownsPipe)
|
|
||||||
{
|
|
||||||
if (pipeH != INVALID_HANDLE_VALUE)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
const Time timeOutEnd (Time::getCurrentTime() + RelativeTime::milliseconds (timeOutMs));
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
{
|
|
||||||
const ScopedLock sl (createFileLock);
|
|
||||||
|
|
||||||
if (pipeH == INVALID_HANDLE_VALUE)
|
|
||||||
pipeH = CreateFile (filename.toWideCharPointer(),
|
|
||||||
GENERIC_READ | GENERIC_WRITE, 0, 0,
|
|
||||||
OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pipeH != INVALID_HANDLE_VALUE)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (shouldStop || (timeOutMs >= 0 && Time::getCurrentTime() > timeOutEnd))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Thread::sleep (1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! connected)
|
|
||||||
{
|
|
||||||
OverlappedEvent over;
|
|
||||||
|
|
||||||
if (ConnectNamedPipe (pipeH, &over.over) == 0)
|
|
||||||
{
|
|
||||||
switch (GetLastError())
|
|
||||||
{
|
|
||||||
case ERROR_PIPE_CONNECTED: connected = true; break;
|
|
||||||
case ERROR_IO_PENDING:
|
|
||||||
case ERROR_PIPE_LISTENING: connected = waitForIO (over, timeOutMs); break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return connected;
|
|
||||||
}
|
|
||||||
|
|
||||||
void disconnectPipe()
|
|
||||||
{
|
|
||||||
if (ownsPipe && connected)
|
|
||||||
{
|
|
||||||
DisconnectNamedPipe (pipeH);
|
|
||||||
connected = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int read (void* destBuffer, const int maxBytesToRead, const int timeOutMilliseconds)
|
|
||||||
{
|
|
||||||
while (connect (timeOutMilliseconds))
|
|
||||||
{
|
|
||||||
if (maxBytesToRead <= 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
OverlappedEvent over;
|
|
||||||
unsigned long numRead;
|
|
||||||
|
|
||||||
if (ReadFile (pipeH, destBuffer, (DWORD) maxBytesToRead, &numRead, &over.over))
|
|
||||||
return (int) numRead;
|
|
||||||
|
|
||||||
const DWORD lastError = GetLastError();
|
|
||||||
|
|
||||||
if (lastError == ERROR_IO_PENDING)
|
|
||||||
{
|
|
||||||
if (! waitForIO (over, timeOutMilliseconds))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (GetOverlappedResult (pipeH, &over.over, &numRead, FALSE))
|
|
||||||
return (int) numRead;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ownsPipe && (GetLastError() == ERROR_BROKEN_PIPE || GetLastError() == ERROR_PIPE_NOT_CONNECTED))
|
|
||||||
disconnectPipe();
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int write (const void* sourceBuffer, int numBytesToWrite, int timeOutMilliseconds)
|
|
||||||
{
|
|
||||||
if (connect (timeOutMilliseconds))
|
|
||||||
{
|
|
||||||
if (numBytesToWrite <= 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
OverlappedEvent over;
|
|
||||||
unsigned long numWritten;
|
|
||||||
|
|
||||||
if (WriteFile (pipeH, sourceBuffer, (DWORD) numBytesToWrite, &numWritten, &over.over))
|
|
||||||
return (int) numWritten;
|
|
||||||
|
|
||||||
if (GetLastError() == ERROR_IO_PENDING)
|
|
||||||
{
|
|
||||||
if (! waitForIO (over, timeOutMilliseconds))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (GetOverlappedResult (pipeH, &over.over, &numWritten, FALSE))
|
|
||||||
return (int) numWritten;
|
|
||||||
|
|
||||||
if (GetLastError() == ERROR_BROKEN_PIPE && ownsPipe)
|
|
||||||
disconnectPipe();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
const String filename;
|
|
||||||
HANDLE pipeH, cancelEvent;
|
|
||||||
bool connected, ownsPipe, shouldStop;
|
|
||||||
CriticalSection createFileLock;
|
|
||||||
|
|
||||||
private:
|
|
||||||
struct OverlappedEvent
|
|
||||||
{
|
|
||||||
OverlappedEvent()
|
|
||||||
{
|
|
||||||
zerostruct (over);
|
|
||||||
over.hEvent = CreateEvent (0, TRUE, FALSE, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
~OverlappedEvent()
|
|
||||||
{
|
|
||||||
CloseHandle (over.hEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
OVERLAPPED over;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool waitForIO (OverlappedEvent& over, int timeOutMilliseconds)
|
|
||||||
{
|
|
||||||
if (shouldStop)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
HANDLE handles[] = { over.over.hEvent, cancelEvent };
|
|
||||||
DWORD waitResult = WaitForMultipleObjects (2, handles, FALSE,
|
|
||||||
timeOutMilliseconds >= 0 ? timeOutMilliseconds
|
|
||||||
: INFINITE);
|
|
||||||
|
|
||||||
if (waitResult == WAIT_OBJECT_0)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
CancelIo (pipeH);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void NamedPipe::close()
|
|
||||||
{
|
|
||||||
if (pimpl != nullptr)
|
|
||||||
{
|
|
||||||
pimpl->shouldStop = true;
|
|
||||||
SetEvent (pimpl->cancelEvent);
|
|
||||||
|
|
||||||
ScopedWriteLock sl (lock);
|
|
||||||
pimpl = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NamedPipe::openInternal (const String& pipeName, const bool createPipe)
|
|
||||||
{
|
|
||||||
pimpl = new Pimpl (pipeName, createPipe);
|
|
||||||
|
|
||||||
if (createPipe && pimpl->pipeH == INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
pimpl = nullptr;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int NamedPipe::read (void* destBuffer, int maxBytesToRead, int timeOutMilliseconds)
|
|
||||||
{
|
|
||||||
ScopedReadLock sl (lock);
|
|
||||||
return pimpl != nullptr ? pimpl->read (destBuffer, maxBytesToRead, timeOutMilliseconds) : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int NamedPipe::write (const void* sourceBuffer, int numBytesToWrite, int timeOutMilliseconds)
|
|
||||||
{
|
|
||||||
ScopedReadLock sl (lock);
|
|
||||||
return pimpl != nullptr ? pimpl->write (sourceBuffer, numBytesToWrite, timeOutMilliseconds) : -1;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ bool TrackedMutex::Record::isNotNull () const noexcept
|
|||||||
return m_mutexName != "";
|
return m_mutexName != "";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TrackedMutex::Record::asBoolean () const noexcept
|
TrackedMutex::Record::operator bool() const noexcept
|
||||||
{
|
{
|
||||||
return isNotNull ();
|
return isNotNull ();
|
||||||
}
|
}
|
||||||
@@ -170,7 +170,7 @@ bool TrackedMutex::Agent::isNotNull () const noexcept
|
|||||||
return m_thread != nullptr;
|
return m_thread != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TrackedMutex::Agent::asBoolean () const noexcept
|
TrackedMutex::Agent::operator bool() const noexcept
|
||||||
{
|
{
|
||||||
return isNotNull ();
|
return isNotNull ();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public:
|
|||||||
|
|
||||||
/** A triplet identifying a mutex, a thread, and source code location.
|
/** A triplet identifying a mutex, a thread, and source code location.
|
||||||
*/
|
*/
|
||||||
class Record : public SafeBool <Record>
|
class Record
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Record () noexcept;
|
Record () noexcept;
|
||||||
@@ -41,7 +41,7 @@ public:
|
|||||||
|
|
||||||
bool isNull () const noexcept;
|
bool isNull () const noexcept;
|
||||||
bool isNotNull () const noexcept;
|
bool isNotNull () const noexcept;
|
||||||
bool asBoolean () const noexcept;
|
explicit operator bool() const noexcept;
|
||||||
|
|
||||||
/** Returns the name of the mutex.
|
/** Returns the name of the mutex.
|
||||||
Since the Mutex may not exist after the Record record is
|
Since the Mutex may not exist after the Record record is
|
||||||
@@ -76,7 +76,7 @@ public:
|
|||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
/** Describes a thread that can acquire mutexes. */
|
/** Describes a thread that can acquire mutexes. */
|
||||||
class Agent : public SafeBool <Agent>
|
class Agent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Agent () noexcept;
|
Agent () noexcept;
|
||||||
@@ -85,7 +85,7 @@ public:
|
|||||||
|
|
||||||
bool isNull () const noexcept;
|
bool isNull () const noexcept;
|
||||||
bool isNotNull () const noexcept;
|
bool isNotNull () const noexcept;
|
||||||
bool asBoolean () const noexcept;
|
explicit operator bool() const noexcept;
|
||||||
|
|
||||||
/** Returns the name of the thread.
|
/** Returns the name of the thread.
|
||||||
The name is generated at the time the Agent record is created,
|
The name is generated at the time the Agent record is created,
|
||||||
|
|||||||
@@ -1,153 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Portions of this file are from JUCE.
|
|
||||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
|
||||||
Please visit http://www.juce.com
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
ReadWriteLock::ReadWriteLock() noexcept
|
|
||||||
: numWaitingWriters (0),
|
|
||||||
numWriters (0),
|
|
||||||
writerThreadId (0)
|
|
||||||
{
|
|
||||||
readerThreads.ensureStorageAllocated (16);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReadWriteLock::~ReadWriteLock() noexcept
|
|
||||||
{
|
|
||||||
bassert (readerThreads.size() == 0);
|
|
||||||
bassert (numWriters == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
void ReadWriteLock::enterRead() const noexcept
|
|
||||||
{
|
|
||||||
while (! tryEnterRead())
|
|
||||||
waitEvent.wait (100);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ReadWriteLock::tryEnterRead() const noexcept
|
|
||||||
{
|
|
||||||
const Thread::ThreadID threadId = Thread::getCurrentThreadId();
|
|
||||||
|
|
||||||
const SpinLock::ScopedLockType sl (accessLock);
|
|
||||||
|
|
||||||
for (int i = 0; i < readerThreads.size(); ++i)
|
|
||||||
{
|
|
||||||
ThreadRecursionCount& trc = readerThreads.getReference(i);
|
|
||||||
|
|
||||||
if (trc.threadID == threadId)
|
|
||||||
{
|
|
||||||
trc.count++;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (numWriters + numWaitingWriters == 0
|
|
||||||
|| (threadId == writerThreadId && numWriters > 0))
|
|
||||||
{
|
|
||||||
ThreadRecursionCount trc = { threadId, 1 };
|
|
||||||
readerThreads.add (trc);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReadWriteLock::exitRead() const noexcept
|
|
||||||
{
|
|
||||||
const Thread::ThreadID threadId = Thread::getCurrentThreadId();
|
|
||||||
const SpinLock::ScopedLockType sl (accessLock);
|
|
||||||
|
|
||||||
for (int i = 0; i < readerThreads.size(); ++i)
|
|
||||||
{
|
|
||||||
ThreadRecursionCount& trc = readerThreads.getReference(i);
|
|
||||||
|
|
||||||
if (trc.threadID == threadId)
|
|
||||||
{
|
|
||||||
if (--(trc.count) == 0)
|
|
||||||
{
|
|
||||||
readerThreads.remove (i);
|
|
||||||
waitEvent.signal();
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bassertfalse; // unlocking a lock that wasn't locked..
|
|
||||||
}
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
void ReadWriteLock::enterWrite() const noexcept
|
|
||||||
{
|
|
||||||
const Thread::ThreadID threadId = Thread::getCurrentThreadId();
|
|
||||||
const SpinLock::ScopedLockType sl (accessLock);
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
if (readerThreads.size() + numWriters == 0
|
|
||||||
|| threadId == writerThreadId
|
|
||||||
|| (readerThreads.size() == 1
|
|
||||||
&& readerThreads.getReference(0).threadID == threadId))
|
|
||||||
{
|
|
||||||
writerThreadId = threadId;
|
|
||||||
++numWriters;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
++numWaitingWriters;
|
|
||||||
accessLock.exit();
|
|
||||||
waitEvent.wait (100);
|
|
||||||
accessLock.enter();
|
|
||||||
--numWaitingWriters;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ReadWriteLock::tryEnterWrite() const noexcept
|
|
||||||
{
|
|
||||||
const Thread::ThreadID threadId = Thread::getCurrentThreadId();
|
|
||||||
const SpinLock::ScopedLockType sl (accessLock);
|
|
||||||
|
|
||||||
if (readerThreads.size() + numWriters == 0
|
|
||||||
|| threadId == writerThreadId
|
|
||||||
|| (readerThreads.size() == 1
|
|
||||||
&& readerThreads.getReference(0).threadID == threadId))
|
|
||||||
{
|
|
||||||
writerThreadId = threadId;
|
|
||||||
++numWriters;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReadWriteLock::exitWrite() const noexcept
|
|
||||||
{
|
|
||||||
const SpinLock::ScopedLockType sl (accessLock);
|
|
||||||
|
|
||||||
// check this thread actually had the lock..
|
|
||||||
bassert (numWriters > 0 && writerThreadId == Thread::getCurrentThreadId());
|
|
||||||
|
|
||||||
if (--numWriters == 0)
|
|
||||||
{
|
|
||||||
writerThreadId = 0;
|
|
||||||
waitEvent.signal();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,145 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Portions of this file are from JUCE.
|
|
||||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
|
||||||
Please visit http://www.juce.com
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_READWRITELOCK_H_INCLUDED
|
|
||||||
#define BEAST_READWRITELOCK_H_INCLUDED
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
/**
|
|
||||||
A critical section that allows multiple simultaneous readers.
|
|
||||||
|
|
||||||
Features of this type of lock are:
|
|
||||||
|
|
||||||
- Multiple readers can hold the lock at the same time, but only one writer
|
|
||||||
can hold it at once.
|
|
||||||
- Writers trying to gain the lock will be blocked until all readers and writers
|
|
||||||
have released it
|
|
||||||
- Readers trying to gain the lock while a writer is waiting to acquire it will be
|
|
||||||
blocked until the writer has obtained and released it
|
|
||||||
- If a thread already has a read lock and tries to obtain a write lock, it will succeed if
|
|
||||||
there are no other readers
|
|
||||||
- If a thread already has the write lock and tries to obtain a read lock, this will succeed.
|
|
||||||
- Recursive locking is supported.
|
|
||||||
|
|
||||||
@see ScopedReadLock, ScopedWriteLock, CriticalSection
|
|
||||||
*/
|
|
||||||
class BEAST_API ReadWriteLock : public Uncopyable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
//==============================================================================
|
|
||||||
/**
|
|
||||||
Creates a ReadWriteLock object.
|
|
||||||
*/
|
|
||||||
ReadWriteLock() noexcept;
|
|
||||||
|
|
||||||
/** Destructor.
|
|
||||||
|
|
||||||
If the object is deleted whilst locked, any subsequent behaviour
|
|
||||||
is unpredictable.
|
|
||||||
*/
|
|
||||||
~ReadWriteLock() noexcept;
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
/** Locks this object for reading.
|
|
||||||
|
|
||||||
Multiple threads can simulaneously lock the object for reading, but if another
|
|
||||||
thread has it locked for writing, then this will block until it releases the
|
|
||||||
lock.
|
|
||||||
|
|
||||||
@see exitRead, ScopedReadLock
|
|
||||||
*/
|
|
||||||
void enterRead() const noexcept;
|
|
||||||
|
|
||||||
/** Tries to lock this object for reading.
|
|
||||||
|
|
||||||
Multiple threads can simulaneously lock the object for reading, but if another
|
|
||||||
thread has it locked for writing, then this will fail and return false.
|
|
||||||
|
|
||||||
@returns true if the lock is successfully gained.
|
|
||||||
@see exitRead, ScopedReadLock
|
|
||||||
*/
|
|
||||||
bool tryEnterRead() const noexcept;
|
|
||||||
|
|
||||||
/** Releases the read-lock.
|
|
||||||
|
|
||||||
If the caller thread hasn't got the lock, this can have unpredictable results.
|
|
||||||
|
|
||||||
If the enterRead() method has been called multiple times by the thread, each
|
|
||||||
call must be matched by a call to exitRead() before other threads will be allowed
|
|
||||||
to take over the lock.
|
|
||||||
|
|
||||||
@see enterRead, ScopedReadLock
|
|
||||||
*/
|
|
||||||
void exitRead() const noexcept;
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
/** Locks this object for writing.
|
|
||||||
|
|
||||||
This will block until any other threads that have it locked for reading or
|
|
||||||
writing have released their lock.
|
|
||||||
|
|
||||||
@see exitWrite, ScopedWriteLock
|
|
||||||
*/
|
|
||||||
void enterWrite() const noexcept;
|
|
||||||
|
|
||||||
/** Tries to lock this object for writing.
|
|
||||||
|
|
||||||
This is like enterWrite(), but doesn't block - it returns true if it manages
|
|
||||||
to obtain the lock.
|
|
||||||
|
|
||||||
@returns true if the lock is successfully gained.
|
|
||||||
@see enterWrite
|
|
||||||
*/
|
|
||||||
bool tryEnterWrite() const noexcept;
|
|
||||||
|
|
||||||
/** Releases the write-lock.
|
|
||||||
|
|
||||||
If the caller thread hasn't got the lock, this can have unpredictable results.
|
|
||||||
|
|
||||||
If the enterWrite() method has been called multiple times by the thread, each
|
|
||||||
call must be matched by a call to exit() before other threads will be allowed
|
|
||||||
to take over the lock.
|
|
||||||
|
|
||||||
@see enterWrite, ScopedWriteLock
|
|
||||||
*/
|
|
||||||
void exitWrite() const noexcept;
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
//==============================================================================
|
|
||||||
SpinLock accessLock;
|
|
||||||
WaitableEvent waitEvent;
|
|
||||||
mutable int numWaitingWriters, numWriters;
|
|
||||||
mutable Thread::ThreadID writerThreadId;
|
|
||||||
|
|
||||||
struct ThreadRecursionCount
|
|
||||||
{
|
|
||||||
Thread::ThreadID threadID;
|
|
||||||
int count;
|
|
||||||
};
|
|
||||||
|
|
||||||
mutable Array <ThreadRecursionCount> readerThreads;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif // BEAST_READWRITELOCK_H_INCLUDED
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Portions of this file are from JUCE.
|
|
||||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
|
||||||
Please visit http://www.juce.com
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_SCOPEDREADLOCK_H_INCLUDED
|
|
||||||
#define BEAST_SCOPEDREADLOCK_H_INCLUDED
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
/**
|
|
||||||
Automatically locks and unlocks a ReadWriteLock object.
|
|
||||||
|
|
||||||
Use one of these as a local variable to control access to a ReadWriteLock.
|
|
||||||
|
|
||||||
e.g. @code
|
|
||||||
|
|
||||||
ReadWriteLock myLock;
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
const ScopedReadLock myScopedLock (myLock);
|
|
||||||
// myLock is now locked
|
|
||||||
|
|
||||||
...do some stuff...
|
|
||||||
|
|
||||||
// myLock gets unlocked here.
|
|
||||||
}
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
@see ReadWriteLock, ScopedWriteLock
|
|
||||||
*/
|
|
||||||
class BEAST_API ScopedReadLock : public Uncopyable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
//==============================================================================
|
|
||||||
/** Creates a ScopedReadLock.
|
|
||||||
|
|
||||||
As soon as it is created, this will call ReadWriteLock::enterRead(), and
|
|
||||||
when the ScopedReadLock object is deleted, the ReadWriteLock will
|
|
||||||
be unlocked.
|
|
||||||
|
|
||||||
Make sure this object is created and deleted by the same thread,
|
|
||||||
otherwise there are no guarantees what will happen! Best just to use it
|
|
||||||
as a local stack object, rather than creating one with the new() operator.
|
|
||||||
*/
|
|
||||||
inline explicit ScopedReadLock (const ReadWriteLock& lock) noexcept : lock_ (lock) { lock.enterRead(); }
|
|
||||||
|
|
||||||
/** Destructor.
|
|
||||||
|
|
||||||
The ReadWriteLock's exitRead() method will be called when the destructor is called.
|
|
||||||
|
|
||||||
Make sure this object is created and deleted by the same thread,
|
|
||||||
otherwise there are no guarantees what will happen!
|
|
||||||
*/
|
|
||||||
inline ~ScopedReadLock() noexcept { lock_.exitRead(); }
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
//==============================================================================
|
|
||||||
const ReadWriteLock& lock_;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif // BEAST_SCOPEDREADLOCK_H_INCLUDED
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
Portions of this file are from JUCE.
|
|
||||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
|
||||||
Please visit http://www.juce.com
|
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
|
||||||
copyright notice and this permission notice appear in all copies.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
//==============================================================================
|
|
||||||
|
|
||||||
#ifndef BEAST_SCOPEDWRITELOCK_H_INCLUDED
|
|
||||||
#define BEAST_SCOPEDWRITELOCK_H_INCLUDED
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
/**
|
|
||||||
Automatically locks and unlocks a ReadWriteLock object.
|
|
||||||
|
|
||||||
Use one of these as a local variable to control access to a ReadWriteLock.
|
|
||||||
|
|
||||||
e.g. @code
|
|
||||||
|
|
||||||
ReadWriteLock myLock;
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
const ScopedWriteLock myScopedLock (myLock);
|
|
||||||
// myLock is now locked
|
|
||||||
|
|
||||||
...do some stuff...
|
|
||||||
|
|
||||||
// myLock gets unlocked here.
|
|
||||||
}
|
|
||||||
@endcode
|
|
||||||
|
|
||||||
@see ReadWriteLock, ScopedReadLock
|
|
||||||
*/
|
|
||||||
class BEAST_API ScopedWriteLock : public Uncopyable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
//==============================================================================
|
|
||||||
/** Creates a ScopedWriteLock.
|
|
||||||
|
|
||||||
As soon as it is created, this will call ReadWriteLock::enterWrite(), and
|
|
||||||
when the ScopedWriteLock object is deleted, the ReadWriteLock will
|
|
||||||
be unlocked.
|
|
||||||
|
|
||||||
Make sure this object is created and deleted by the same thread,
|
|
||||||
otherwise there are no guarantees what will happen! Best just to use it
|
|
||||||
as a local stack object, rather than creating one with the new() operator.
|
|
||||||
*/
|
|
||||||
inline explicit ScopedWriteLock (const ReadWriteLock& lock) noexcept : lock_ (lock) { lock.enterWrite(); }
|
|
||||||
|
|
||||||
/** Destructor.
|
|
||||||
|
|
||||||
The ReadWriteLock's exitWrite() method will be called when the destructor is called.
|
|
||||||
|
|
||||||
Make sure this object is created and deleted by the same thread,
|
|
||||||
otherwise there are no guarantees what will happen!
|
|
||||||
*/
|
|
||||||
inline ~ScopedWriteLock() noexcept { lock_.exitWrite(); }
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
//==============================================================================
|
|
||||||
const ReadWriteLock& lock_;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif // BEAST_SCOPEDWRITELOCK_H_INCLUDED
|
|
||||||
Reference in New Issue
Block a user