mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-02 00:45:58 +00:00
New beast Socket, SharedHandler, ComposedAsyncOperation APIs
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
<PreprocessorDefinitions>_CRTDBG_MAP_ALLOC;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup />
|
||||
|
||||
@@ -142,4 +142,16 @@
|
||||
#define BEAST_DISABLE_CONTRACT_CHECKS 0
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Config: BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES
|
||||
|
||||
Setting this option makes Socket-derived classes generate compile errors if
|
||||
they forget any of the virtual overrides As some Socket-derived classes
|
||||
intentionally omit member functions that are not applicable, this macro
|
||||
should only be enabled temporarily when writing your own Socket-derived class,
|
||||
to make sure that the function signatures match as expected.
|
||||
*/
|
||||
#define BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES 0
|
||||
|
||||
#endif
|
||||
|
||||
@@ -69,7 +69,11 @@
|
||||
<None Include="..\..\README.md" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\modules\beast_asio\basics\beast_HandlerCall.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\async\beast_ComposedAsyncOperation.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\async\beast_SharedHandler.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\async\beast_SharedHandlerAllocator.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\async\beast_SharedHandlerPtr.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\async\beast_SharedHandlerType.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\basics\beast_BufferType.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\basics\beast_FixedInputBuffer.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\basics\beast_PeerRole.h" />
|
||||
@@ -78,13 +82,13 @@
|
||||
<ClInclude Include="..\..\modules\beast_asio\handshake\beast_HandshakeDetectLogicPROXY.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\handshake\beast_HandshakeDetectLogicSSL2.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\handshake\beast_HandshakeDetectLogicSSL3.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\handshake\beast_HandshakeDetectStream.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\handshake\beast_HandshakeDetector.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\handshake\beast_InputParser.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\handshake\beast_PrefilledReadStream.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\sockets\beast_Socket.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\sockets\beast_SocketBase.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\sockets\beast_SocketWrapper.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\sockets\beast_SslContext.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\streams\beast_PrefilledReadStream.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\system\beast_BoostIncludes.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\system\beast_OpenSSLIncludes.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\tests\beast_TestPeer.h" />
|
||||
@@ -303,7 +307,7 @@
|
||||
<ClInclude Include="BeastConfig.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\modules\beast_asio\basics\beast_HandlerCall.cpp">
|
||||
<ClCompile Include="..\..\modules\beast_asio\async\beast_SharedHandler.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>
|
||||
@@ -340,6 +344,12 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\system\beast_BoostUnitTests.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="..\..\modules\beast_asio\tests\beast_TestPeerLogic.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
@@ -361,6 +371,8 @@
|
||||
<ClCompile Include="..\..\modules\beast_asio\tests\beast_TestPeerLogicProxyClient.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_asio\tests\beast_TestPeerLogicSyncClient.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
|
||||
@@ -155,12 +155,12 @@
|
||||
<Filter Include="beast_asio\basics">
|
||||
<UniqueIdentifier>{ccdc0c8e-f77a-486e-ba2f-29c10ec97f18}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast_asio\streams">
|
||||
<UniqueIdentifier>{dfa79046-33ef-4653-a6f9-83954b76a10f}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast_asio\handshake">
|
||||
<UniqueIdentifier>{4856837a-fa72-4252-8e8f-a112c1dbb3d2}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast_asio\async">
|
||||
<UniqueIdentifier>{beb81776-4aad-401d-8826-81478dbbf30b}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\modules\beast_core\beast_core.h">
|
||||
@@ -824,9 +824,6 @@
|
||||
<ClInclude Include="..\..\modules\beast_core\memory\beast_ByteSwap.h">
|
||||
<Filter>beast_core\memory</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\streams\beast_PrefilledReadStream.h">
|
||||
<Filter>beast_asio\streams</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\handshake\beast_HandshakeDetectLogic.h">
|
||||
<Filter>beast_asio\handshake</Filter>
|
||||
</ClInclude>
|
||||
@@ -839,24 +836,39 @@
|
||||
<ClInclude Include="..\..\modules\beast_asio\handshake\beast_HandshakeDetectLogicSSL3.h">
|
||||
<Filter>beast_asio\handshake</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\handshake\beast_HandshakeDetectStream.h">
|
||||
<Filter>beast_asio\handshake</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\handshake\beast_HandshakeDetectLogicPROXY.h">
|
||||
<Filter>beast_asio\handshake</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\basics\beast_HandlerCall.h">
|
||||
<Filter>beast_asio\basics</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_core\memory\beast_ContainerDeletePolicy.h">
|
||||
<Filter>beast_core\memory</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\handshake\beast_InputParser.h">
|
||||
<Filter>beast_asio\sockets</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\system\beast_OpenSSLIncludes.h">
|
||||
<Filter>beast_asio\system</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\handshake\beast_HandshakeDetector.h">
|
||||
<Filter>beast_asio\handshake</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\handshake\beast_PrefilledReadStream.h">
|
||||
<Filter>beast_asio\handshake</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\async\beast_ComposedAsyncOperation.h">
|
||||
<Filter>beast_asio\async</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\async\beast_SharedHandler.h">
|
||||
<Filter>beast_asio\async</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\async\beast_SharedHandlerAllocator.h">
|
||||
<Filter>beast_asio\async</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\async\beast_SharedHandlerPtr.h">
|
||||
<Filter>beast_asio\async</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\async\beast_SharedHandlerType.h">
|
||||
<Filter>beast_asio\async</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\handshake\beast_InputParser.h">
|
||||
<Filter>beast_asio\handshake</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\modules\beast_core\beast_core.cpp">
|
||||
@@ -1318,8 +1330,11 @@
|
||||
<ClCompile Include="..\..\modules\beast_asio\handshake\beast_HandshakeDetectLogicPROXY.cpp">
|
||||
<Filter>beast_asio\handshake</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\basics\beast_HandlerCall.cpp">
|
||||
<Filter>beast_asio\basics</Filter>
|
||||
<ClCompile Include="..\..\modules\beast_asio\system\beast_BoostUnitTests.cpp">
|
||||
<Filter>beast_asio\system</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\async\beast_SharedHandler.cpp">
|
||||
<Filter>beast_asio\async</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
100
modules/beast_asio/async/beast_ComposedAsyncOperation.h
Normal file
100
modules/beast_asio/async/beast_ComposedAsyncOperation.h
Normal file
@@ -0,0 +1,100 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_COMPOSEDASYNCOPERATION_H_INCLUDED
|
||||
#define BEAST_COMPOSEDASYNCOPERATION_H_INCLUDED
|
||||
|
||||
/** Base class for creating composed asynchronous operations.
|
||||
The composed operation will have its operator() overloads called with
|
||||
the same context and execution safety guarantees as the original
|
||||
SharedHandler.
|
||||
*/
|
||||
class ComposedAsyncOperation : public SharedHandler
|
||||
{
|
||||
protected:
|
||||
/** Construct the composed operation.
|
||||
The composed operation will execute in the context of the
|
||||
SharedHandler. A reference to the SharedHandler is maintained
|
||||
for the lifetime of the composed operation.
|
||||
*/
|
||||
ComposedAsyncOperation (std::size_t size, SharedHandlerPtr const& ptr)
|
||||
: m_size (size)
|
||||
, m_ptr (ptr)
|
||||
{
|
||||
// Illegal to do anything with handler here, because
|
||||
// usually it hasn't been assigned by the derived class yet.
|
||||
}
|
||||
|
||||
~ComposedAsyncOperation ()
|
||||
{
|
||||
}
|
||||
|
||||
void invoke (invoked_type& invoked)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::
|
||||
invoke (invoked, *m_ptr);
|
||||
}
|
||||
|
||||
void* allocate (std::size_t size)
|
||||
{
|
||||
return boost_asio_handler_alloc_helpers::
|
||||
allocate (size, *m_ptr);
|
||||
}
|
||||
|
||||
void deallocate (void* p, std::size_t size)
|
||||
{
|
||||
boost_asio_handler_alloc_helpers::
|
||||
deallocate (p, size, *m_ptr);
|
||||
}
|
||||
|
||||
/** Override this function as needed.
|
||||
Usually you will logical-and your own continuation condition. In
|
||||
the following example, isContinuing is a derived class member:
|
||||
|
||||
@code
|
||||
|
||||
bool derived::is_continuation ()
|
||||
{
|
||||
bool const ourResult = this->isContinuing ()
|
||||
return ourResult || ComposedAsyncOperation <Handler>::is_contiation ();
|
||||
}
|
||||
|
||||
@endcode
|
||||
*/
|
||||
bool is_continuation ()
|
||||
{
|
||||
#if BEAST_ASIO_HAS_CONTINUATION_HOOKS
|
||||
return boost_asio_handler_cont_helpers::
|
||||
is_continuation (*m_ptr);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void destroy ()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
private:
|
||||
std::size_t const m_size;
|
||||
SharedHandlerPtr const m_ptr;
|
||||
};
|
||||
|
||||
#endif
|
||||
47
modules/beast_asio/async/beast_SharedHandler.cpp
Normal file
47
modules/beast_asio/async/beast_SharedHandler.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
void SharedHandler::operator() ()
|
||||
{
|
||||
pure_virtual_called (__FILE__, __LINE__);
|
||||
}
|
||||
|
||||
void SharedHandler::operator() (error_code const&)
|
||||
{
|
||||
pure_virtual_called (__FILE__, __LINE__);
|
||||
}
|
||||
|
||||
void SharedHandler::operator() (error_code const&, std::size_t)
|
||||
{
|
||||
pure_virtual_called (__FILE__, __LINE__);
|
||||
}
|
||||
|
||||
void SharedHandler::pure_virtual_called (char const* fileName, int lineNumber)
|
||||
{
|
||||
// These shouldn't be getting called. But since the object returned
|
||||
// by most implementations of bind have operator() up to high arity
|
||||
// levels, it is not generally possible to write a traits test that
|
||||
// works in all scenarios for detecting a particular signature of a
|
||||
// handler.
|
||||
//
|
||||
// We use Throw here so beast has a chance to dump the stack BEFORE
|
||||
// the stack is unwound.
|
||||
//
|
||||
Throw (std::runtime_error ("pure virtual called"), fileName, lineNumber);
|
||||
}
|
||||
134
modules/beast_asio/async/beast_SharedHandler.h
Normal file
134
modules/beast_asio/async/beast_SharedHandler.h
Normal file
@@ -0,0 +1,134 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_SHAREDHANDLER_H_INCLUDED
|
||||
#define BEAST_SHAREDHANDLER_H_INCLUDED
|
||||
|
||||
template <typename T>
|
||||
struct SharedHandlerAllocator;
|
||||
|
||||
/** Reference counted wrapper that can hold any other boost::asio handler.
|
||||
|
||||
This object will match these signatures:
|
||||
|
||||
@code
|
||||
|
||||
void (void)
|
||||
void (system::error_code)
|
||||
void (system::error_code, std::size_t)
|
||||
|
||||
@endcode
|
||||
|
||||
If the underlying implementation does not support the signature,
|
||||
undefined behavior will result.
|
||||
|
||||
Supports these concepts:
|
||||
Destructible
|
||||
*/
|
||||
class SharedHandler : public SharedObject
|
||||
{
|
||||
protected:
|
||||
typedef boost::system::error_code error_code;
|
||||
typedef boost::function <void(void)> invoked_type;
|
||||
|
||||
SharedHandler () noexcept { }
|
||||
|
||||
public:
|
||||
// For asio::async_result<>
|
||||
typedef void result_type;
|
||||
|
||||
typedef SharedObjectPtr <SharedHandler> Ptr;
|
||||
|
||||
virtual void operator() ();
|
||||
virtual void operator() (error_code const&);
|
||||
virtual void operator() (error_code const&, std::size_t);
|
||||
|
||||
/** Dispatch the Function on our context. */
|
||||
/*
|
||||
template <typename Dispatcher, typename Function>
|
||||
void dispatch (Dispatcher& dispatcher, BOOST_ASIO_MOVE_ARG(Function) function)
|
||||
{
|
||||
dispatcher.dispatch (boost::bind (
|
||||
&SharedHandler::invoke <Function>, this,
|
||||
BOOST_ASIO_MOVE_CAST(Function)(function)));
|
||||
}
|
||||
*/
|
||||
|
||||
template <typename Function>
|
||||
void invoke (BOOST_ASIO_MOVE_ARG(Function) f);
|
||||
|
||||
virtual void invoke (invoked_type& invoked) = 0;
|
||||
virtual void* allocate (std::size_t size) = 0;
|
||||
virtual void deallocate (void* p, std::size_t size) = 0;
|
||||
virtual bool is_continuation () = 0;
|
||||
virtual void destroy () = 0;
|
||||
|
||||
static void pure_virtual_called (char const* fileName, int lineNumber);
|
||||
|
||||
private:
|
||||
template <typename Function>
|
||||
friend void asio_handler_invoke (BOOST_ASIO_MOVE_ARG(Function) f, SharedHandler*);
|
||||
friend void* asio_handler_allocate (std::size_t, SharedHandler*);
|
||||
friend void asio_handler_deallocate (void*, std::size_t, SharedHandler*);
|
||||
friend bool asio_handler_is_continuation (SharedHandler*);
|
||||
friend struct ContainerDeletePolicy <SharedHandler>;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
// For SharedObjectPtr <SharedHandler>
|
||||
template <>
|
||||
struct ContainerDeletePolicy <SharedHandler>
|
||||
{
|
||||
// SharedObjectPtr will use this when
|
||||
// the reference count drops to zero.
|
||||
//
|
||||
inline static void destroy (SharedHandler* handler)
|
||||
{
|
||||
handler->destroy ();
|
||||
}
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// Context execution guarantees
|
||||
//
|
||||
|
||||
template <class Function>
|
||||
void asio_handler_invoke (BOOST_ASIO_MOVE_ARG(Function) f, SharedHandler* handler)
|
||||
{
|
||||
handler->invoke (BOOST_ASIO_MOVE_CAST(Function)(f));
|
||||
}
|
||||
|
||||
inline void* asio_handler_allocate (std::size_t size, SharedHandler* handler)
|
||||
{
|
||||
return handler->allocate (size);
|
||||
}
|
||||
|
||||
inline void asio_handler_deallocate (void* p, std::size_t size, SharedHandler* handler)
|
||||
{
|
||||
handler->deallocate (p, size);
|
||||
}
|
||||
|
||||
inline bool asio_handler_is_continuation (SharedHandler* handler)
|
||||
{
|
||||
return handler->is_continuation ();
|
||||
}
|
||||
|
||||
#endif
|
||||
129
modules/beast_asio/async/beast_SharedHandlerAllocator.h
Normal file
129
modules/beast_asio/async/beast_SharedHandlerAllocator.h
Normal file
@@ -0,0 +1,129 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_SHAREDHANDLERALLOCATOR_H_INCLUDED
|
||||
#define BEAST_SHAREDHANDLERALLOCATOR_H_INCLUDED
|
||||
|
||||
/** Custom Allocator using the allocation hooks from the Handler.
|
||||
|
||||
This class is compatible with std::allocator and can be used in any
|
||||
boost interface which takes a template parameter of type Allocator.
|
||||
This includes boost::function and especially boost::asio::streambuf
|
||||
and relatives. This is vastly more efficient in a variety of situations
|
||||
especially during an upcall and when using stackful coroutines.
|
||||
|
||||
The Allocator holds a reference to the underlying SharedHandler. The
|
||||
SharedHandler will not be destroyed as long as any Allocator is still
|
||||
using it.
|
||||
*/
|
||||
template <typename T>
|
||||
struct SharedHandlerAllocator
|
||||
{
|
||||
typedef T value_type;
|
||||
typedef T* pointer;
|
||||
typedef T& reference;
|
||||
typedef T const* const_pointer;
|
||||
typedef T const& const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
SharedHandlerAllocator (SharedHandler* handler) noexcept
|
||||
: m_ptr (handler)
|
||||
{
|
||||
}
|
||||
|
||||
SharedHandlerAllocator (SharedHandlerPtr const& handler) noexcept
|
||||
: m_ptr (handler)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
SharedHandlerAllocator (SharedHandlerAllocator <U> const& other)
|
||||
: m_ptr (other.m_ptr)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
struct rebind
|
||||
{
|
||||
typedef SharedHandlerAllocator <U> other;
|
||||
};
|
||||
|
||||
pointer address (reference x) const
|
||||
{
|
||||
return &x;
|
||||
}
|
||||
|
||||
const_pointer address (const_reference x) const
|
||||
{
|
||||
return &x;
|
||||
}
|
||||
|
||||
pointer allocate (size_type n) const
|
||||
{
|
||||
size_type const bytes = n * sizeof (value_type);
|
||||
return static_cast <pointer> (m_ptr->allocate (bytes));
|
||||
}
|
||||
|
||||
void deallocate (pointer p, size_type n) const
|
||||
{
|
||||
size_type const bytes = n * sizeof (value_type);
|
||||
m_ptr->deallocate (p, bytes);
|
||||
}
|
||||
|
||||
size_type max_size () const noexcept
|
||||
{
|
||||
return std::numeric_limits <size_type>::max () / sizeof (value_type);
|
||||
}
|
||||
|
||||
void construct (pointer p, const_reference val) const
|
||||
{
|
||||
::new ((void *)p) value_type (val);
|
||||
}
|
||||
|
||||
void destroy (pointer p) const
|
||||
{
|
||||
p->~value_type ();
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename>
|
||||
friend struct SharedHandlerAllocator;
|
||||
friend class SharedHandler;
|
||||
|
||||
SharedHandlerPtr m_ptr;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <typename Function>
|
||||
void SharedHandler::invoke (BOOST_ASIO_MOVE_ARG(Function) f)
|
||||
{
|
||||
#if BEAST_USE_HANDLER_ALLOCATIONS
|
||||
// The allocator will hold a reference to the SharedHandler
|
||||
// so that we can safely destroy the function object.
|
||||
invoked_type invoked (BOOST_ASIO_MOVE_CAST(Function)(f),
|
||||
SharedHandlerAllocator <char> (this));
|
||||
#else
|
||||
invoked_type invoked (BOOST_ASIO_MOVE_CAST(Function)(f));
|
||||
#endif
|
||||
invoke (invoked);
|
||||
}
|
||||
|
||||
#endif
|
||||
307
modules/beast_asio/async/beast_SharedHandlerPtr.h
Normal file
307
modules/beast_asio/async/beast_SharedHandlerPtr.h
Normal file
@@ -0,0 +1,307 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_SHAREDHANDLERPTR_H_INCLUDED
|
||||
#define BEAST_SHAREDHANDLERPTR_H_INCLUDED
|
||||
|
||||
/** RAII container for a SharedHandler.
|
||||
|
||||
This object behaves exactly like a SharedHandler except that it
|
||||
merely contains a shared pointer to the underlying SharedHandler.
|
||||
All calls are forwarded to the underlying SharedHandler, and all
|
||||
of the execution safety guarantees are met by forwarding them through
|
||||
to the underlying SharedHandler.
|
||||
*/
|
||||
class SharedHandlerPtr
|
||||
{
|
||||
protected:
|
||||
typedef boost::system::error_code error_code;
|
||||
|
||||
public:
|
||||
// For asio::async_result<>
|
||||
typedef void result_type;
|
||||
|
||||
/** Construct a null handler.
|
||||
A null handler cannot be called. It can, however, be checked
|
||||
for validity by calling isNull, and later assigned.
|
||||
|
||||
@see isNull, isNotNull
|
||||
*/
|
||||
inline SharedHandlerPtr () noexcept
|
||||
{
|
||||
}
|
||||
|
||||
/** Construct from an existing SharedHandler.
|
||||
Ownership of the handler is transferred to the container.
|
||||
*/
|
||||
inline SharedHandlerPtr (SharedHandler* handler)
|
||||
: m_ptr (handler)
|
||||
{
|
||||
}
|
||||
|
||||
/** Construct a reference from an existing container.
|
||||
*/
|
||||
inline SharedHandlerPtr (SharedHandlerPtr const& other) noexcept
|
||||
: m_ptr (other.m_ptr)
|
||||
{
|
||||
}
|
||||
|
||||
/** Assign a reference from an existing container. */
|
||||
inline SharedHandlerPtr& operator= (SharedHandlerPtr const& other) noexcept
|
||||
{
|
||||
m_ptr = other.m_ptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
|
||||
/** Move-construct a reference from an existing container.
|
||||
The other container is set to a null handler.
|
||||
*/
|
||||
inline SharedHandlerPtr (SharedHandlerPtr&& other) noexcept
|
||||
: m_ptr (other.m_ptr)
|
||||
{
|
||||
other.m_ptr = nullptr;
|
||||
}
|
||||
|
||||
/** Move-assign a reference from an existing container.
|
||||
The other container is set to a null handler.
|
||||
*/
|
||||
inline SharedHandlerPtr& operator= (SharedHandlerPtr&& other) noexcept
|
||||
{
|
||||
m_ptr = other.m_ptr;
|
||||
other.m_ptr = nullptr;
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Returns true if the handler is a null handler. */
|
||||
inline bool isNull () const noexcept
|
||||
{
|
||||
return m_ptr == nullptr;
|
||||
}
|
||||
|
||||
/** Returns true if the handler is not a null handler. */
|
||||
inline bool isNotNull () const noexcept
|
||||
{
|
||||
return m_ptr != nullptr;
|
||||
}
|
||||
|
||||
/** Dereference the container.
|
||||
This returns a reference to the underlying SharedHandler object.
|
||||
*/
|
||||
inline SharedHandler& operator* () const noexcept
|
||||
{
|
||||
return *m_ptr;
|
||||
}
|
||||
|
||||
/** SharedHandler member access.
|
||||
This lets you call functions directly on the SharedHandler.
|
||||
*/
|
||||
inline SharedHandler* operator-> () const noexcept
|
||||
{
|
||||
return m_ptr.get ();
|
||||
}
|
||||
|
||||
/** Retrieve the SharedHandler as a Context.
|
||||
|
||||
This can be used for invoking functions in the context:
|
||||
|
||||
@code
|
||||
|
||||
template <Function>
|
||||
void callOnHandler (Function f, SharedHandlerPtr ptr)
|
||||
{
|
||||
boost::asio_handler_invoke (f, ptr.get ());
|
||||
}
|
||||
|
||||
@endcode
|
||||
*/
|
||||
inline SharedHandler* get () const noexcept
|
||||
{
|
||||
return m_ptr.get ();
|
||||
}
|
||||
|
||||
/** Invoke the SharedHandler with signature void(void)
|
||||
Normally this is called by a dispatcher, you shouldn't call it directly.
|
||||
*/
|
||||
inline void operator() () const
|
||||
{
|
||||
(*m_ptr)();
|
||||
}
|
||||
|
||||
/** Invoke the SharedHandler with signature void(error_code)
|
||||
Normally this is called by a dispatcher, you shouldn't call it directly.
|
||||
*/
|
||||
inline void operator() (error_code const& ec) const
|
||||
{
|
||||
(*m_ptr)(ec);
|
||||
}
|
||||
|
||||
/** Invoke the SharedHandler with signature void(error_code, size_t)
|
||||
Normally this is called by a dispatcher, you shouldn't call it directly.
|
||||
*/
|
||||
inline void operator() (error_code const& ec, std::size_t bytes_transferred) const
|
||||
{
|
||||
(*m_ptr)(ec, bytes_transferred);
|
||||
}
|
||||
|
||||
private:
|
||||
// These ensure that SharedHandlerPtr invocations adhere to
|
||||
// the asio::io_service execution guarantees of the underlying SharedHandler.
|
||||
//
|
||||
template <typename Function>
|
||||
friend void asio_handler_invoke (BOOST_ASIO_MOVE_ARG(Function) f, SharedHandlerPtr*);
|
||||
friend void* asio_handler_allocate (std::size_t, SharedHandlerPtr*);
|
||||
friend void asio_handler_deallocate (void*, std::size_t, SharedHandlerPtr*);
|
||||
friend bool asio_handler_is_continuation (SharedHandlerPtr*);
|
||||
|
||||
SharedHandler::Ptr m_ptr;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// Context execution guarantees
|
||||
//
|
||||
|
||||
template <class Function>
|
||||
inline void asio_handler_invoke (BOOST_ASIO_MOVE_ARG(Function) f, SharedHandlerPtr* ptr)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::
|
||||
invoke <Function, SharedHandler>
|
||||
(BOOST_ASIO_MOVE_CAST(Function)(f), *ptr->get ());
|
||||
}
|
||||
|
||||
inline void* asio_handler_allocate (std::size_t size, SharedHandlerPtr* ptr)
|
||||
{
|
||||
return boost_asio_handler_alloc_helpers::
|
||||
allocate <SharedHandler> (size, *ptr->get ());
|
||||
}
|
||||
|
||||
inline void asio_handler_deallocate (void* p, std::size_t size, SharedHandlerPtr* ptr)
|
||||
{
|
||||
boost_asio_handler_alloc_helpers::
|
||||
deallocate <SharedHandler> (p, size, *ptr->get ());
|
||||
}
|
||||
|
||||
inline bool asio_handler_is_continuation (SharedHandlerPtr* ptr)
|
||||
{
|
||||
#if BEAST_ASIO_HAS_CONTINUATION_HOOKS
|
||||
return boost_asio_handler_cont_helpers::
|
||||
is_continuation <SharedHandler> (*ptr->get ());
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// Helpers
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
// CompletionHandler
|
||||
//
|
||||
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/CompletionHandler.html
|
||||
//
|
||||
template <typename CompletionHandler>
|
||||
SharedHandlerPtr newCompletionHandler (
|
||||
BOOST_ASIO_MOVE_ARG(CompletionHandler) handler)
|
||||
{
|
||||
return newSharedHandlerContainer <PostSharedHandlerType> (
|
||||
BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler));
|
||||
}
|
||||
|
||||
// AcceptHandler
|
||||
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/AcceptHandler.html
|
||||
//
|
||||
template <typename AcceptHandler>
|
||||
SharedHandlerPtr newAcceptHandler (
|
||||
BOOST_ASIO_MOVE_ARG(AcceptHandler) handler)
|
||||
{
|
||||
return newSharedHandlerContainer <ErrorSharedHandlerType> (
|
||||
BOOST_ASIO_MOVE_CAST(AcceptHandler)(handler));
|
||||
}
|
||||
|
||||
// ConnectHandler
|
||||
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ConnectHandler.html
|
||||
//
|
||||
template <typename ConnectHandler>
|
||||
SharedHandlerPtr newConnectHandler (
|
||||
BOOST_ASIO_MOVE_ARG(ConnectHandler) handler)
|
||||
{
|
||||
return newSharedHandlerContainer <ErrorSharedHandlerType> (
|
||||
BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler));
|
||||
}
|
||||
|
||||
// ShutdownHandler
|
||||
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ShutdownHandler.html
|
||||
//
|
||||
template <typename ShutdownHandler>
|
||||
SharedHandlerPtr newShutdownHandler(
|
||||
BOOST_ASIO_MOVE_ARG(ShutdownHandler) handler)
|
||||
{
|
||||
return newSharedHandlerContainer <ErrorSharedHandlerType> (
|
||||
BOOST_ASIO_MOVE_CAST(ShutdownHandler)(handler));
|
||||
}
|
||||
|
||||
// HandshakeHandler
|
||||
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/HandshakeHandler.html
|
||||
//
|
||||
template <typename HandshakeHandler>
|
||||
SharedHandlerPtr newHandshakeHandler(
|
||||
BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler)
|
||||
{
|
||||
return newSharedHandlerContainer <ErrorSharedHandlerType> (
|
||||
BOOST_ASIO_MOVE_CAST(HandshakeHandler)(handler));
|
||||
}
|
||||
|
||||
// ReadHandler
|
||||
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ReadHandler.html
|
||||
//
|
||||
template <typename ReadHandler>
|
||||
SharedHandlerPtr newReadHandler(
|
||||
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
|
||||
{
|
||||
return newSharedHandlerContainer <TransferSharedHandlerType> (
|
||||
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
|
||||
}
|
||||
|
||||
// WriteHandler
|
||||
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/WriteHandler.html
|
||||
//
|
||||
template <typename WriteHandler>
|
||||
SharedHandlerPtr newWriteHandler(
|
||||
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
|
||||
{
|
||||
return newSharedHandlerContainer <TransferSharedHandlerType> (
|
||||
BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
|
||||
}
|
||||
|
||||
// BufferedHandshakeHandler
|
||||
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/BufferedHandshakeHandler.html
|
||||
//
|
||||
template <typename BufferedHandshakeHandler>
|
||||
SharedHandlerPtr newBufferedHandshakeHandler(
|
||||
BOOST_ASIO_MOVE_ARG(BufferedHandshakeHandler) handler)
|
||||
{
|
||||
return newSharedHandlerContainer <TransferSharedHandlerType> (
|
||||
BOOST_ASIO_MOVE_CAST(BufferedHandshakeHandler)(handler));
|
||||
}
|
||||
|
||||
#endif
|
||||
233
modules/beast_asio/async/beast_SharedHandlerType.h
Normal file
233
modules/beast_asio/async/beast_SharedHandlerType.h
Normal file
@@ -0,0 +1,233 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_SHAREDHANDLERTYPE_H_INCLUDED
|
||||
#define BEAST_SHAREDHANDLERTYPE_H_INCLUDED
|
||||
|
||||
/** An instance of SharedHandler that wraps an existing Handler.
|
||||
|
||||
The wrapped handler will meet all the execution guarantees of
|
||||
the original Handler object.
|
||||
*/
|
||||
template <typename Handler>
|
||||
class SharedHandlerType : public SharedHandler
|
||||
{
|
||||
protected:
|
||||
SharedHandlerType (std::size_t size,
|
||||
BOOST_ASIO_MOVE_ARG(Handler) handler)
|
||||
: m_size (size)
|
||||
, m_handler (BOOST_ASIO_MOVE_CAST(Handler)(handler))
|
||||
{
|
||||
}
|
||||
|
||||
~SharedHandlerType ()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void invoke (invoked_type& invoked)
|
||||
{
|
||||
boost_asio_handler_invoke_helpers::
|
||||
invoke <invoked_type, Handler> (invoked, m_handler);
|
||||
}
|
||||
|
||||
void* allocate (std::size_t size)
|
||||
{
|
||||
return boost_asio_handler_alloc_helpers::
|
||||
allocate <Handler> (size, m_handler);
|
||||
}
|
||||
|
||||
void deallocate (void* p, std::size_t size)
|
||||
{
|
||||
boost_asio_handler_alloc_helpers::
|
||||
deallocate <Handler> (p, size, m_handler);
|
||||
}
|
||||
|
||||
bool is_continuation ()
|
||||
{
|
||||
#if BEAST_ASIO_HAS_CONTINUATION_HOOKS
|
||||
return boost_asio_handler_cont_helpers::
|
||||
is_continuation <Handler> (m_handler);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Called by our ContainerDeletePolicy hook to destroy the
|
||||
// object. We need this because we allocated it using a custom
|
||||
// allocator. Destruction is tricky, the algorithm is as follows:
|
||||
//
|
||||
// First we move-assign the handler to our stack. If the build
|
||||
// doesn't support move-assignment it will be a copy, still ok.
|
||||
// We convert 'this' to a pointer to the polymorphic base, to
|
||||
// ensure that the following direct destructor call will reach
|
||||
// the most derived class. Finally, we deallocate the memory
|
||||
// using the handler that is local to the stack.
|
||||
//
|
||||
// For this to work we need to make sure regular operator delete
|
||||
// is never called for our object (it's private). We also need
|
||||
// the size from the original allocation, which we saved at
|
||||
// the time of construction.
|
||||
//
|
||||
void destroy ()
|
||||
{
|
||||
#if BEAST_USE_HANDLER_ALLOCATIONS
|
||||
Handler local (BOOST_ASIO_MOVE_CAST(Handler)(m_handler));
|
||||
std::size_t const size (m_size);
|
||||
SharedHandler* const shared (static_cast <SharedHandler*>(this));
|
||||
shared->~SharedHandler ();
|
||||
boost_asio_handler_alloc_helpers::
|
||||
deallocate <Handler> (shared, size, local);
|
||||
#else
|
||||
delete this;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if BEAST_USE_HANDLER_ALLOCATIONS
|
||||
// If these somehow get called, bad things will happen
|
||||
//
|
||||
void* operator new (std::size_t)
|
||||
{
|
||||
return pure_virtual_called (__FILE__, __LINE__);
|
||||
}
|
||||
|
||||
void operator delete (void*)
|
||||
{
|
||||
return pure_virtual_called (__FILE__, __LINE__);
|
||||
}
|
||||
#endif
|
||||
|
||||
protected:
|
||||
std::size_t const m_size;
|
||||
Handler m_handler;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// A SharedHandlerType for this signature:
|
||||
// void(void)
|
||||
//
|
||||
template <typename Handler>
|
||||
class PostSharedHandlerType : public SharedHandlerType <Handler>
|
||||
{
|
||||
public:
|
||||
PostSharedHandlerType (std::size_t size,
|
||||
BOOST_ASIO_MOVE_ARG(Handler) handler)
|
||||
: SharedHandlerType <Handler> (size,
|
||||
BOOST_ASIO_MOVE_CAST(Handler)(handler))
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
void operator() ()
|
||||
{
|
||||
this->m_handler ();
|
||||
}
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// A SharedHandlerType for this signature:
|
||||
// void(error_code)
|
||||
//
|
||||
template <typename Handler>
|
||||
class ErrorSharedHandlerType : public SharedHandlerType <Handler>
|
||||
{
|
||||
public:
|
||||
ErrorSharedHandlerType (std::size_t size,
|
||||
BOOST_ASIO_MOVE_ARG(Handler) handler)
|
||||
: SharedHandlerType <Handler> (size,
|
||||
BOOST_ASIO_MOVE_CAST(Handler)(handler))
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
void operator() (boost::system::error_code const& ec)
|
||||
{
|
||||
this->m_handler (ec);
|
||||
}
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// A SharedHandlerType for this signature:
|
||||
// void(error_code, size_t)
|
||||
//
|
||||
template <typename Handler>
|
||||
class TransferSharedHandlerType : public SharedHandlerType <Handler>
|
||||
{
|
||||
public:
|
||||
TransferSharedHandlerType (std::size_t size,
|
||||
BOOST_ASIO_MOVE_ARG(Handler) handler)
|
||||
: SharedHandlerType <Handler> (size,
|
||||
BOOST_ASIO_MOVE_CAST(Handler)(handler))
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
void operator() (boost::system::error_code const& ec,
|
||||
std::size_t bytes_transferred)
|
||||
{
|
||||
this->m_handler (ec, bytes_transferred);
|
||||
}
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// These specializations will make sure we don't do
|
||||
// anything silly like wrap ourselves in our own wrapper...
|
||||
//
|
||||
#if 1
|
||||
template <>
|
||||
class PostSharedHandlerType <SharedHandler>
|
||||
{
|
||||
};
|
||||
|
||||
template <>
|
||||
class ErrorSharedHandlerType <SharedHandler>
|
||||
{
|
||||
};
|
||||
template <>
|
||||
class TransferSharedHandlerType <SharedHandler>
|
||||
{
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** Construct a wrapped handler using the context's allocation hooks.
|
||||
*/
|
||||
template <template <typename> class Container, typename Handler>
|
||||
Container <Handler>* newSharedHandlerContainer (BOOST_ASIO_MOVE_ARG(Handler) handler)
|
||||
{
|
||||
typedef Container <Handler> ContainerType;
|
||||
std::size_t const size (sizeof (ContainerType));
|
||||
#if BEAST_USE_HANDLER_ALLOCATIONS
|
||||
Handler local (BOOST_ASIO_MOVE_CAST(Handler)(handler));
|
||||
void* const p (boost_asio_handler_alloc_helpers::
|
||||
allocate <Handler> (size, local));
|
||||
return ::new (p) ContainerType (size, BOOST_ASIO_MOVE_CAST(Handler)(local));
|
||||
#else
|
||||
void* const p = ::operator new (size);
|
||||
return ::new (p) ContainerType (size, BOOST_ASIO_MOVE_CAST(Handler)(handler));
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -34,21 +34,48 @@ public:
|
||||
typedef Buffer value_type;
|
||||
typedef typename std::vector <Buffer>::const_iterator const_iterator;
|
||||
|
||||
/** Construct a null buffer.
|
||||
This is the equivalent of @ref asio::null_buffers.
|
||||
*/
|
||||
BufferType ()
|
||||
: m_size (0)
|
||||
{
|
||||
}
|
||||
|
||||
template <class OtherBuffers>
|
||||
explicit BufferType (OtherBuffers const& buffers)
|
||||
: m_size (0)
|
||||
/** Construct a BufferType from an existing BufferSequence.
|
||||
@see assign
|
||||
*/
|
||||
template <class BufferSequence>
|
||||
BufferType (BufferSequence const& buffers)
|
||||
{
|
||||
assign (buffers);
|
||||
}
|
||||
|
||||
/** Assign a BufferType from an existing BufferSequence.
|
||||
@see assign
|
||||
*/
|
||||
template <class BufferSequence>
|
||||
BufferType <Buffer>& operator= (BufferSequence const& buffers)
|
||||
{
|
||||
return assign (buffers);
|
||||
}
|
||||
|
||||
/** Assign a BufferType from an existing BufferSequence
|
||||
A copy is not made. The data is still owned by the original
|
||||
BufferSequence object. This merely points to that data.
|
||||
*/
|
||||
template <class BufferSequence>
|
||||
BufferType <Buffer>& assign (BufferSequence const& buffers)
|
||||
{
|
||||
m_size = 0;
|
||||
m_buffers.clear ();
|
||||
m_buffers.reserve (std::distance (buffers.begin (), buffers.end ()));
|
||||
BOOST_FOREACH (typename OtherBuffers::value_type buffer, buffers)
|
||||
BOOST_FOREACH (typename BufferSequence::value_type buffer, buffers)
|
||||
{
|
||||
m_size += boost::asio::buffer_size (buffer);
|
||||
m_buffers.push_back (buffer);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** Determine the total size of all buffers.
|
||||
@@ -91,7 +118,10 @@ private:
|
||||
std::vector <Buffer> m_buffers;
|
||||
};
|
||||
|
||||
/** A single linear read-only buffer. */
|
||||
typedef boost::asio::const_buffer ConstBuffer;
|
||||
|
||||
/** A single linear writable buffer. */
|
||||
typedef boost::asio::mutable_buffer MutableBuffer;
|
||||
|
||||
/** Meets the requirements of ConstBufferSequence */
|
||||
|
||||
@@ -1,345 +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.
|
||||
*/
|
||||
//==============================================================================
|
||||
//
|
||||
// Context
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
HandlerCall::Context::Context (Call* call) noexcept
|
||||
: m_call (call)
|
||||
{
|
||||
bassert (m_call != nullptr);
|
||||
}
|
||||
|
||||
HandlerCall::Context::Context () noexcept
|
||||
: m_call (nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
HandlerCall::Context::Context (Context const& other) noexcept
|
||||
: m_call (other.m_call)
|
||||
{
|
||||
}
|
||||
|
||||
HandlerCall::Context::Context (HandlerCall const& handler) noexcept
|
||||
: m_call (handler.m_call.get ())
|
||||
{
|
||||
}
|
||||
|
||||
HandlerCall::Context& HandlerCall::Context::operator= (Context other) noexcept
|
||||
{
|
||||
m_call = other.m_call;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool HandlerCall::Context::operator== (Call const* call) const noexcept
|
||||
{
|
||||
return m_call == call;
|
||||
}
|
||||
|
||||
bool HandlerCall::Context::operator!= (Call const* call) const noexcept
|
||||
{
|
||||
return m_call != call;
|
||||
}
|
||||
|
||||
bool HandlerCall::Context::isComposed () const noexcept
|
||||
{
|
||||
return m_call->is_continuation ();
|
||||
}
|
||||
|
||||
bool HandlerCall::Context::isNull () const noexcept
|
||||
{
|
||||
return m_call == nullptr;
|
||||
}
|
||||
|
||||
bool HandlerCall::Context::isNotNull () const noexcept
|
||||
{
|
||||
return m_call != nullptr;
|
||||
}
|
||||
|
||||
bool HandlerCall::Context::operator== (Context other) const noexcept
|
||||
{
|
||||
return m_call == other.m_call;
|
||||
}
|
||||
|
||||
bool HandlerCall::Context::operator!= (Context other) const noexcept
|
||||
{
|
||||
return m_call != other.m_call;
|
||||
}
|
||||
|
||||
void* HandlerCall::Context::allocate (std::size_t size) const
|
||||
{
|
||||
return m_call->allocate (size);
|
||||
}
|
||||
|
||||
void HandlerCall::Context::deallocate (void* p, std::size_t size) const
|
||||
{
|
||||
m_call->deallocate (p, size);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Call
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
HandlerCall::Call::Call (Context context) noexcept
|
||||
: m_context (context.isNull () ? Context (this) : context)
|
||||
, m_is_continuation (false)
|
||||
, m_is_final_continuation (false)
|
||||
{
|
||||
}
|
||||
|
||||
HandlerCall::Call::~Call ()
|
||||
{
|
||||
}
|
||||
|
||||
HandlerCall::Context HandlerCall::Call::getContext () const noexcept
|
||||
{
|
||||
return m_context;
|
||||
}
|
||||
|
||||
bool HandlerCall::Call::is_continuation () const noexcept
|
||||
{
|
||||
// If this goes off it means someone isn't calling getContext()!
|
||||
bassert (m_context == this);
|
||||
return m_is_continuation;
|
||||
}
|
||||
|
||||
void HandlerCall::Call::set_continuation () noexcept
|
||||
{
|
||||
// Setting it twice means some code is sloppy!
|
||||
bassert (! m_is_continuation);
|
||||
|
||||
m_is_continuation = true;
|
||||
}
|
||||
|
||||
void HandlerCall::Call::set_final_continuation () noexcept
|
||||
{
|
||||
// Soemone called endComposed without calling beginComposed!
|
||||
bassert (m_is_continuation);
|
||||
// When true, we will clear
|
||||
// m_is_continuation on our next completion
|
||||
m_is_final_continuation = true;
|
||||
}
|
||||
|
||||
void HandlerCall::Call::check_continuation () noexcept
|
||||
{
|
||||
if (m_is_final_continuation)
|
||||
{
|
||||
bassert (m_is_continuation);
|
||||
|
||||
m_is_continuation = false;
|
||||
m_is_final_continuation = false;
|
||||
}
|
||||
}
|
||||
|
||||
void HandlerCall::Call::operator() ()
|
||||
{
|
||||
check_continuation ();
|
||||
dispatch ();
|
||||
}
|
||||
|
||||
void HandlerCall::Call::operator() (error_code const& ec)
|
||||
{
|
||||
check_continuation ();
|
||||
dispatch (ec);
|
||||
}
|
||||
|
||||
void HandlerCall::Call::operator() (error_code const& ec, std::size_t bytes_transferred)
|
||||
{
|
||||
check_continuation ();
|
||||
dispatch (ec, bytes_transferred);
|
||||
}
|
||||
|
||||
void HandlerCall::Call::dispatch ()
|
||||
{
|
||||
pure_virtual_called ();
|
||||
}
|
||||
|
||||
void HandlerCall::Call::dispatch (error_code const&)
|
||||
{
|
||||
pure_virtual_called ();
|
||||
}
|
||||
|
||||
void HandlerCall::Call::dispatch (error_code const&, std::size_t)
|
||||
{
|
||||
pure_virtual_called ();
|
||||
}
|
||||
|
||||
void* HandlerCall::Call::pure_virtual_called ()
|
||||
{
|
||||
// These shouldn't be getting called. But since the object returned
|
||||
// by most implementations of bind have operator() up to high arity
|
||||
// levels, it is not generally possible to write a traits test that
|
||||
// works in all scenarios for detecting a particular signature of a
|
||||
// handler.
|
||||
//
|
||||
fatal_error ("pure virtual called");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// HandlerCall
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
HandlerCall::HandlerCall () noexcept
|
||||
{
|
||||
}
|
||||
|
||||
HandlerCall::HandlerCall (HandlerCall const& other) noexcept
|
||||
: m_call (other.m_call)
|
||||
{
|
||||
}
|
||||
|
||||
HandlerCall& HandlerCall::operator= (HandlerCall const& other) noexcept
|
||||
{
|
||||
m_call = other.m_call;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool HandlerCall::isNull () const noexcept
|
||||
{
|
||||
return m_call == nullptr;
|
||||
}
|
||||
|
||||
bool HandlerCall::isNotNull () const noexcept
|
||||
{
|
||||
return m_call != nullptr;
|
||||
}
|
||||
|
||||
HandlerCall::Context HandlerCall::getContext () const noexcept
|
||||
{
|
||||
bassert (m_call != nullptr);
|
||||
return m_call->getContext ();
|
||||
}
|
||||
|
||||
bool HandlerCall::isFinal () const noexcept
|
||||
{
|
||||
return m_call->getContext () == m_call.get ();
|
||||
}
|
||||
|
||||
HandlerCall const& HandlerCall::beginComposed () const noexcept
|
||||
{
|
||||
// If this goes off it means that your handler is
|
||||
// already sharing a context with another handler!
|
||||
// You have to call beginComposed on the original handler.
|
||||
//
|
||||
bassert (isFinal ());
|
||||
m_call->set_continuation ();
|
||||
return *this;
|
||||
}
|
||||
|
||||
HandlerCall const& HandlerCall::endComposed () const noexcept
|
||||
{
|
||||
// If this goes off it means that your handler is
|
||||
// already sharing a context with another handler!
|
||||
// You have to call beginComposed on the original handler.
|
||||
//
|
||||
bassert (isFinal ());
|
||||
m_call->set_final_continuation ();
|
||||
return *this;
|
||||
}
|
||||
|
||||
void HandlerCall::operator() () const
|
||||
{
|
||||
(*m_call)();
|
||||
}
|
||||
|
||||
void HandlerCall::operator() (error_code const& ec) const
|
||||
{
|
||||
(*m_call)(ec);
|
||||
}
|
||||
|
||||
void HandlerCall::operator() (error_code const& ec, std::size_t bytes_transferred) const
|
||||
{
|
||||
(*m_call)(ec, bytes_transferred);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Specializations
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void ContainerDeletePolicy <HandlerCall::Call>::destroy (HandlerCall::Call* call)
|
||||
{
|
||||
call->destroy ();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void* asio_handler_allocate (std::size_t size, HandlerCall* call)
|
||||
{
|
||||
// Always go through the call's context.
|
||||
return call->getContext ().allocate (size);
|
||||
}
|
||||
|
||||
void* asio_handler_allocate (std::size_t size, HandlerCall::Call* call)
|
||||
{
|
||||
// Always go through the call's context.
|
||||
return call->getContext ().allocate (size);
|
||||
}
|
||||
|
||||
void* asio_handler_allocate (std::size_t size, HandlerCall::Context* context)
|
||||
{
|
||||
return context->allocate (size);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void asio_handler_deallocate (void* p, std::size_t size, HandlerCall* call)
|
||||
{
|
||||
// Always go through the call's context.
|
||||
call->getContext ().deallocate (p, size);
|
||||
}
|
||||
|
||||
void asio_handler_deallocate (void* p, std::size_t size, HandlerCall::Call* call)
|
||||
{
|
||||
// Always go through the call's context.
|
||||
call->getContext ().deallocate (p, size);
|
||||
}
|
||||
|
||||
void asio_handler_deallocate (void* p, std::size_t size, HandlerCall::Context* context)
|
||||
{
|
||||
context->deallocate (p, size);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool asio_handler_is_continuation (HandlerCall* call)
|
||||
{
|
||||
return call->getContext().isComposed ();
|
||||
}
|
||||
|
||||
bool asio_handler_is_continuation (HandlerCall::Call* call)
|
||||
{
|
||||
return call->getContext().isComposed ();
|
||||
}
|
||||
|
||||
bool asio_handler_is_continuation (HandlerCall::Context*)
|
||||
{
|
||||
// Something is horribly wrong if we're trying to
|
||||
// use a Context as a completion handler?
|
||||
//
|
||||
fatal_error ("A function was unexpectedly called.");
|
||||
return false;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -26,7 +26,8 @@
|
||||
namespace beast
|
||||
{
|
||||
|
||||
#include "basics/beast_HandlerCall.cpp"
|
||||
#include "async/beast_SharedHandler.cpp"
|
||||
|
||||
#include "basics/beast_PeerRole.cpp"
|
||||
|
||||
#include "sockets/beast_SocketBase.cpp"
|
||||
@@ -35,6 +36,7 @@ namespace beast
|
||||
|
||||
#include "handshake/beast_HandshakeDetectLogicPROXY.cpp"
|
||||
|
||||
#include "tests/beast_PeerTest.cpp"
|
||||
#include "tests/beast_TestPeerBasics.cpp"
|
||||
#include "tests/beast_TestPeerLogic.cpp"
|
||||
#include "tests/beast_TestPeerLogicProxyClient.cpp"
|
||||
@@ -42,8 +44,8 @@ namespace beast
|
||||
#include "tests/beast_TestPeerLogicSyncClient.cpp"
|
||||
#include "tests/beast_TestPeerLogicAsyncServer.cpp"
|
||||
#include "tests/beast_TestPeerLogicAsyncClient.cpp"
|
||||
|
||||
#include "tests/beast_PeerTest.cpp"
|
||||
#include "tests/beast_TestPeerUnitTests.cpp"
|
||||
|
||||
#include "system/beast_BoostUnitTests.cpp"
|
||||
|
||||
}
|
||||
|
||||
@@ -40,15 +40,36 @@
|
||||
// Must come before boost includes to fix the bost placeholders.
|
||||
#include "../beast_core/beast_core.h"
|
||||
|
||||
/* This module requires boost and possibly OpenSSL */
|
||||
// This module requires boost and possibly OpenSSL
|
||||
#include "system/beast_BoostIncludes.h"
|
||||
|
||||
// Checking overrides replaces unimplemented stubs with pure virtuals
|
||||
#ifndef BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES
|
||||
# define BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES 0
|
||||
#endif
|
||||
#if BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES
|
||||
# define BEAST_SOCKET_VIRTUAL = 0
|
||||
#else
|
||||
# define BEAST_SOCKET_VIRTUAL
|
||||
#endif
|
||||
|
||||
// A potentially dangerous but powerful feature which
|
||||
// might need to be turned off to see if it fixes anything.
|
||||
//
|
||||
#ifndef BEAST_USE_HANDLER_ALLOCATIONS
|
||||
# define BEAST_USE_HANDLER_ALLOCATIONS 1
|
||||
#endif
|
||||
|
||||
namespace beast
|
||||
{
|
||||
|
||||
// Order matters
|
||||
#include "async/beast_SharedHandler.h"
|
||||
#include "async/beast_SharedHandlerType.h"
|
||||
#include "async/beast_SharedHandlerPtr.h"
|
||||
#include "async/beast_ComposedAsyncOperation.h"
|
||||
#include "async/beast_SharedHandlerAllocator.h"
|
||||
|
||||
#include "basics/beast_HandlerCall.h"
|
||||
#include "basics/beast_BufferType.h"
|
||||
#include "basics/beast_FixedInputBuffer.h"
|
||||
#include "basics/beast_PeerRole.h"
|
||||
@@ -63,9 +84,8 @@ namespace beast
|
||||
#include "handshake/beast_HandshakeDetectLogicPROXY.h"
|
||||
#include "handshake/beast_HandshakeDetectLogicSSL2.h"
|
||||
#include "handshake/beast_HandshakeDetectLogicSSL3.h"
|
||||
#include "handshake/beast_HandshakeDetectStream.h"
|
||||
|
||||
#include "streams/beast_PrefilledReadStream.h"
|
||||
#include "handshake/beast_HandshakeDetector.h"
|
||||
#include "handshake/beast_PrefilledReadStream.h"
|
||||
|
||||
#include "tests/beast_TestPeerBasics.h"
|
||||
#include "tests/beast_TestPeer.h"
|
||||
|
||||
@@ -1,293 +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_HANDSHAKEDETECTSTREAM_H_INCLUDED
|
||||
#define BEAST_HANDSHAKEDETECTSTREAM_H_INCLUDED
|
||||
|
||||
/** A stream that can detect a handshake.
|
||||
*/
|
||||
/** @{ */
|
||||
template <class Logic>
|
||||
class HandshakeDetectStream
|
||||
{
|
||||
protected:
|
||||
typedef boost::system::error_code error_code;
|
||||
|
||||
public:
|
||||
typedef Logic LogicType;
|
||||
|
||||
/** Called when the state is known.
|
||||
|
||||
This could be called from any thread, most likely an io_service
|
||||
thread but don't rely on that.
|
||||
|
||||
The Callback must be allocated via operator new.
|
||||
*/
|
||||
struct Callback
|
||||
{
|
||||
virtual ~Callback () { }
|
||||
|
||||
/** Called for synchronous ssl detection.
|
||||
|
||||
Note that the storage for the buffers passed to the
|
||||
callback is owned by the detector class and becomes
|
||||
invalid when the detector class is destroyed, which is
|
||||
a common thing to do from inside your callback.
|
||||
|
||||
@param ec A modifiable error code that becomes the return
|
||||
value of handshake.
|
||||
@param buffers The bytes that were read in.
|
||||
@param is_ssl True if the sequence is an ssl handshake.
|
||||
*/
|
||||
virtual void on_detect (Logic& logic,
|
||||
error_code& ec, ConstBuffers const& buffers) = 0;
|
||||
|
||||
virtual void on_async_detect (Logic& logic,
|
||||
error_code const& ec, ConstBuffers const& buffers,
|
||||
HandlerCall const& origHandler) = 0;
|
||||
};
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <typename Stream, typename Logic>
|
||||
class HandshakeDetectStreamType
|
||||
: public HandshakeDetectStream <Logic>
|
||||
, public boost::asio::ssl::stream_base
|
||||
, public boost::asio::socket_base
|
||||
{
|
||||
private:
|
||||
typedef boost::system::error_code error_code;
|
||||
|
||||
typedef HandshakeDetectStreamType <Stream, Logic> this_type;
|
||||
typedef boost::asio::streambuf buffer_type;
|
||||
typedef typename boost::remove_reference <Stream>::type stream_type;
|
||||
|
||||
public:
|
||||
typedef typename HandshakeDetectStream <Logic>::Callback CallbackType;
|
||||
|
||||
/** This takes ownership of the callback.
|
||||
The callback must be allocated with operator new.
|
||||
*/
|
||||
template <typename Arg>
|
||||
HandshakeDetectStreamType (CallbackType* callback, Arg& arg)
|
||||
: m_callback (callback)
|
||||
, m_next_layer (arg)
|
||||
, m_stream (m_next_layer)
|
||||
{
|
||||
}
|
||||
|
||||
// This puts bytes that you already have into the detector buffer
|
||||
// Any leftovers will be given to the callback.
|
||||
// A copy of the data is made.
|
||||
//
|
||||
template <typename ConstBufferSequence>
|
||||
void fill (ConstBufferSequence const& buffers)
|
||||
{
|
||||
m_buffer.commit (boost::asio::buffer_copy (
|
||||
m_buffer.prepare (boost::asio::buffer_size (buffers)),
|
||||
buffers));
|
||||
}
|
||||
|
||||
// basic_io_object
|
||||
|
||||
boost::asio::io_service& get_io_service ()
|
||||
{
|
||||
return m_next_layer.get_io_service ();
|
||||
}
|
||||
|
||||
// basic_socket
|
||||
|
||||
typedef typename stream_type::protocol_type protocol_type;
|
||||
typedef typename stream_type::lowest_layer_type lowest_layer_type;
|
||||
|
||||
lowest_layer_type& lowest_layer ()
|
||||
{
|
||||
return m_next_layer.lowest_layer ();
|
||||
}
|
||||
|
||||
lowest_layer_type const& lowest_layer () const
|
||||
{
|
||||
return m_next_layer.lowest_layer ();
|
||||
}
|
||||
|
||||
// ssl::stream
|
||||
|
||||
error_code handshake (handshake_type type, error_code& ec)
|
||||
{
|
||||
return do_handshake (type, ec, ConstBuffers ());
|
||||
}
|
||||
|
||||
template <typename HandshakeHandler>
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE(HandshakeHandler, void (error_code))
|
||||
async_handshake (handshake_type type, BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler)
|
||||
{
|
||||
#if BEAST_ASIO_HAS_FUTURE_RETURNS
|
||||
boost::asio::detail::async_result_init<
|
||||
HandshakeHandler, void (error_code)> init(
|
||||
BOOST_ASIO_MOVE_CAST(HandshakeHandler)(handler));
|
||||
// init.handler is copied
|
||||
m_origHandler = HandlerCall (
|
||||
BOOST_ASIO_MOVE_CAST(HandshakeHandler)
|
||||
(HandshakeHandler(init.handler)));
|
||||
async_do_handshake (type, ConstBuffers ());
|
||||
return init.result.get();
|
||||
#else
|
||||
m_origHandler = HandlerCall (
|
||||
BOOST_ASIO_MOVE_CAST(HandshakeHandler)(handler));
|
||||
async_do_handshake (type, ConstBuffers ());
|
||||
#endif
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
error_code do_handshake (handshake_type, error_code& ec, ConstBuffers const& buffers)
|
||||
{
|
||||
ec = error_code ();
|
||||
|
||||
// Transfer caller data to our buffer.
|
||||
m_buffer.commit (boost::asio::buffer_copy (m_buffer.prepare (
|
||||
boost::asio::buffer_size (buffers)), buffers));
|
||||
|
||||
do
|
||||
{
|
||||
std::size_t const available = m_buffer.size ();
|
||||
std::size_t const needed = m_logic.max_needed ();
|
||||
if (available < needed)
|
||||
{
|
||||
buffer_type::mutable_buffers_type buffers (
|
||||
m_buffer.prepare (needed - available));
|
||||
m_buffer.commit (m_next_layer.read_some (buffers, ec));
|
||||
}
|
||||
|
||||
if (! ec)
|
||||
{
|
||||
m_logic.analyze (m_buffer.data ());
|
||||
|
||||
if (m_logic.finished ())
|
||||
{
|
||||
// consume what we used (for SSL its 0)
|
||||
std::size_t const consumed = m_logic.bytes_consumed ();
|
||||
bassert (consumed <= m_buffer.size ());
|
||||
m_buffer.consume (consumed);
|
||||
m_callback->on_detect (m_logic.get (), ec,
|
||||
ConstBuffers (m_buffer.data ()));
|
||||
break;
|
||||
}
|
||||
|
||||
// If this fails it means we will never finish
|
||||
check_postcondition (available < needed);
|
||||
}
|
||||
}
|
||||
while (! ec);
|
||||
|
||||
return ec;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void async_do_handshake (handshake_type type, ConstBuffers const& buffers)
|
||||
{
|
||||
// Get the execution context from the original handler
|
||||
// and signal the beginning of our composed operation.
|
||||
//
|
||||
//m_origHandler.beginComposed ();
|
||||
m_context = m_origHandler.getContext ();
|
||||
|
||||
bassert (m_context.isNotNull ());
|
||||
|
||||
// Transfer caller data to our buffer.
|
||||
// We commit the bytes in on_async_read_some.
|
||||
//
|
||||
std::size_t const bytes_transferred (boost::asio::buffer_copy (
|
||||
m_buffer.prepare (boost::asio::buffer_size (buffers)), buffers));
|
||||
|
||||
// bootstrap the asynchronous loop
|
||||
on_async_read_some (error_code (), bytes_transferred);
|
||||
}
|
||||
|
||||
// asynchronous version of the synchronous loop found in handshake ()
|
||||
//
|
||||
void on_async_read_some (error_code const& ec, std::size_t bytes_transferred)
|
||||
{
|
||||
if (! ec)
|
||||
{
|
||||
m_buffer.commit (bytes_transferred);
|
||||
|
||||
std::size_t const available = m_buffer.size ();
|
||||
std::size_t const needed = m_logic.max_needed ();
|
||||
|
||||
if (bytes_transferred > 0)
|
||||
m_logic.analyze (m_buffer.data ());
|
||||
|
||||
if (m_logic.finished ())
|
||||
{
|
||||
// consume what we used (for SSL its 0)
|
||||
std::size_t const consumed = m_logic.bytes_consumed ();
|
||||
bassert (consumed <= m_buffer.size ());
|
||||
m_buffer.consume (consumed);
|
||||
|
||||
// The composed operation has completed and
|
||||
// the original handler will eventually get called.
|
||||
//
|
||||
//m_origHandler.endComposed ();
|
||||
m_callback->on_async_detect (m_logic.get (), ec,
|
||||
ConstBuffers (m_buffer.data ()), m_origHandler);
|
||||
return;
|
||||
}
|
||||
|
||||
// If this fails it means we will never finish
|
||||
check_postcondition (available < needed);
|
||||
|
||||
buffer_type::mutable_buffers_type buffers (m_buffer.prepare (
|
||||
needed - available));
|
||||
|
||||
// Perform the asynchronous operation using the context
|
||||
// of the original handler. This ensures that we meet the
|
||||
// execution safety requirements of the handler.
|
||||
//
|
||||
HandlerCall handler (HandlerCall::Read (), m_context,
|
||||
boost::bind (&this_type::on_async_read_some, this,
|
||||
boost::asio::placeholders::error,
|
||||
boost::asio::placeholders::bytes_transferred));
|
||||
m_next_layer.async_read_some (buffers, handler);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Error condition
|
||||
|
||||
//m_origHandler.endComposed ();
|
||||
m_callback->on_async_detect (m_logic.get (), ec,
|
||||
ConstBuffers (m_buffer.data ()), m_origHandler);
|
||||
}
|
||||
|
||||
private:
|
||||
ScopedPointer <CallbackType> m_callback;
|
||||
Stream m_next_layer;
|
||||
buffer_type m_buffer;
|
||||
boost::asio::buffered_read_stream <stream_type&> m_stream;
|
||||
HandshakeDetectLogicType <Logic> m_logic;
|
||||
HandlerCall m_origHandler;
|
||||
HandlerCall m_origBufferedHandler;
|
||||
HandlerCall::Context m_context;
|
||||
};
|
||||
/** @} */
|
||||
|
||||
#endif
|
||||
206
modules/beast_asio/handshake/beast_HandshakeDetector.h
Normal file
206
modules/beast_asio/handshake/beast_HandshakeDetector.h
Normal file
@@ -0,0 +1,206 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_HANDSHAKEDETECTOR_H_INCLUDED
|
||||
#define BEAST_HANDSHAKEDETECTOR_H_INCLUDED
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** A wrapper to decode the handshake data on a Stream.
|
||||
|
||||
Stream must meet these requirements
|
||||
|
||||
For detect:
|
||||
SyncReadStream
|
||||
|
||||
For async_detect:
|
||||
AsyncReadStream
|
||||
|
||||
Logic must meet this requirement:
|
||||
HandshakeDetectLogic
|
||||
*/
|
||||
template <typename Stream, typename Logic>
|
||||
class HandshakeDetectorType
|
||||
{
|
||||
protected:
|
||||
typedef boost::system::error_code error_code;
|
||||
|
||||
public:
|
||||
Logic& getLogic ()
|
||||
{
|
||||
return m_logic.get ();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** Synchronous handshake detect.
|
||||
The bytes from the input sequence in the specified buffer
|
||||
are used first.
|
||||
*/
|
||||
template <typename Allocator>
|
||||
error_code detect (Stream& stream,
|
||||
boost::asio::basic_streambuf <Allocator>& buffer)
|
||||
{
|
||||
typedef boost::asio::basic_streambuf <Allocator> BufferType;
|
||||
|
||||
error_code ec;
|
||||
|
||||
do
|
||||
{
|
||||
m_logic.analyze (buffer.data ());
|
||||
|
||||
if (m_logic.finished ())
|
||||
{
|
||||
// consume what we used (for SSL its 0)
|
||||
std::size_t const consumed = m_logic.bytes_consumed ();
|
||||
bassert (consumed <= buffer.size ());
|
||||
buffer.consume (consumed);
|
||||
break;
|
||||
}
|
||||
|
||||
std::size_t const available = buffer.size ();
|
||||
std::size_t const needed = m_logic.max_needed ();
|
||||
|
||||
// If postcondition fails, loop will never end
|
||||
if (meets_postcondition (available < needed))
|
||||
{
|
||||
typename BufferType::mutable_buffers_type buffers (
|
||||
buffer.prepare (needed - available));
|
||||
buffer.commit (stream.read_some (buffers, ec));
|
||||
}
|
||||
}
|
||||
while (! ec);
|
||||
|
||||
return ec;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** Asynchronous handshake detect.
|
||||
The bytes from the input sequence in the specified buffer
|
||||
are used first.
|
||||
|
||||
DetectHandler must have this signature:
|
||||
void(error_code)
|
||||
*/
|
||||
template <typename DetectHandler, typename Allocator>
|
||||
void async_detect (Stream& stream,
|
||||
boost::asio::basic_streambuf <Allocator>& buffer,
|
||||
BOOST_ASIO_MOVE_ARG(DetectHandler) handler)
|
||||
{
|
||||
async_detect <Allocator> (stream, buffer, SharedHandlerPtr (
|
||||
new ErrorSharedHandlerType <DetectHandler> (
|
||||
BOOST_ASIO_MOVE_CAST(DetectHandler)(handler))));
|
||||
}
|
||||
|
||||
template <typename Allocator>
|
||||
void async_detect (Stream& stream,
|
||||
boost::asio::basic_streambuf <Allocator>& buffer,
|
||||
SharedHandlerPtr handler)
|
||||
{
|
||||
typedef AsyncOp <Allocator> OpType;
|
||||
OpType* const op = new AsyncOp <Allocator> (
|
||||
m_logic, stream, buffer, handler);
|
||||
stream.get_io_service ().wrap (SharedHandlerPtr (op))
|
||||
(error_code (), 0);
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename Allocator>
|
||||
struct AsyncOp : ComposedAsyncOperation
|
||||
{
|
||||
typedef boost::asio::basic_streambuf <Allocator> BufferType;
|
||||
|
||||
AsyncOp (HandshakeDetectLogicType <Logic>& logic, Stream& stream,
|
||||
BufferType& buffer, SharedHandlerPtr const& handler)
|
||||
: ComposedAsyncOperation (sizeof (*this), handler)
|
||||
, m_logic (logic)
|
||||
, m_stream (stream)
|
||||
, m_buffer (buffer)
|
||||
, m_handler (handler)
|
||||
, m_running (false)
|
||||
{
|
||||
}
|
||||
|
||||
// Set breakpoint to prove it gets destroyed
|
||||
~AsyncOp ()
|
||||
{
|
||||
}
|
||||
|
||||
void operator() (error_code const& ec_, size_t bytes_transferred)
|
||||
{
|
||||
m_running = true;
|
||||
|
||||
error_code ec (ec_);
|
||||
|
||||
if (! ec)
|
||||
{
|
||||
m_buffer.commit (bytes_transferred);
|
||||
|
||||
m_logic.analyze (m_buffer.data ());
|
||||
|
||||
if (!m_logic.finished ())
|
||||
{
|
||||
std::size_t const available = m_buffer.size ();
|
||||
std::size_t const needed = m_logic.max_needed ();
|
||||
|
||||
// If postcondition fails, loop will never end
|
||||
if (meets_postcondition (available < needed))
|
||||
{
|
||||
typename BufferType::mutable_buffers_type buffers (
|
||||
m_buffer.prepare (needed - available));
|
||||
|
||||
m_stream.async_read_some (buffers, SharedHandlerPtr (this));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::size_t const consumed = m_logic.bytes_consumed ();
|
||||
m_buffer.consume (consumed);
|
||||
}
|
||||
|
||||
// Finalize with a call to the original handler.
|
||||
m_stream.get_io_service ().wrap (
|
||||
BOOST_ASIO_MOVE_CAST (SharedHandlerPtr)(m_handler))
|
||||
(ec);
|
||||
}
|
||||
|
||||
bool is_continuation ()
|
||||
{
|
||||
return m_running
|
||||
#if BEAST_ASIO_HAS_CONTINUATION_HOOKS
|
||||
|| boost_asio_handler_cont_helpers::is_continuation (m_handler);
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
private:
|
||||
HandshakeDetectLogicType <Logic>& m_logic;
|
||||
Stream& m_stream;
|
||||
BufferType& m_buffer;
|
||||
SharedHandlerPtr m_handler;
|
||||
bool m_running;
|
||||
};
|
||||
|
||||
private:
|
||||
HandshakeDetectLogicType <Logic> m_logic;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -72,10 +72,10 @@ public:
|
||||
template <typename ConstBufferSequence>
|
||||
void fill (ConstBufferSequence const& buffers)
|
||||
{
|
||||
using namespace boost;
|
||||
// We don't assume the caller's buffers will
|
||||
// remain valid for the lifetime of this object.
|
||||
//
|
||||
using namespace boost;
|
||||
m_buffer.commit (asio::buffer_copy (
|
||||
m_buffer.prepare (asio::buffer_size (buffers)),
|
||||
buffers));
|
||||
@@ -116,76 +116,6 @@ public:
|
||||
return m_next_layer.close(ec);
|
||||
}
|
||||
|
||||
template <typename ConstBufferSequence>
|
||||
std::size_t write_some (ConstBufferSequence const& buffers)
|
||||
{
|
||||
return m_next_layer.write_some (buffers);
|
||||
}
|
||||
|
||||
template <typename ConstBufferSequence>
|
||||
std::size_t write_some (ConstBufferSequence const& buffers, error_code& ec)
|
||||
{
|
||||
return m_next_layer.write_some (buffers, ec);
|
||||
}
|
||||
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t read_some (MutableBufferSequence const& buffers, error_code& ec)
|
||||
{
|
||||
ec = error_code ();
|
||||
if (m_buffer.size () > 0)
|
||||
{
|
||||
std::size_t const bytes_transferred = boost::asio::buffer_copy (
|
||||
buffers, m_buffer.data ());
|
||||
m_buffer.consume (bytes_transferred);
|
||||
return bytes_transferred;
|
||||
}
|
||||
return m_next_layer.read_some (buffers, ec);
|
||||
}
|
||||
|
||||
template <typename MutableBufferSequence, typename ReadHandler>
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE(ReadHandler, void (error_code, std::size_t))
|
||||
async_read_some (MutableBufferSequence const& buffers,
|
||||
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
|
||||
{
|
||||
using namespace boost;
|
||||
if (m_buffer.size () > 0)
|
||||
{
|
||||
std::size_t const bytes_transferred = asio::buffer_copy (
|
||||
buffers, m_buffer.data ());
|
||||
m_buffer.consume (bytes_transferred);
|
||||
|
||||
#if BEAST_ASIO_HAS_FUTURE_RETURNS
|
||||
asio::detail::async_result_init <
|
||||
ReadHandler, void (error_code, std::size_t)> init (
|
||||
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
|
||||
|
||||
get_io_service ().post (HandlerCall (HandlerCall::Post (),
|
||||
ReadHandler(init.handler), // handler is copied
|
||||
error_code (), bytes_transferred));
|
||||
|
||||
return init.result.get();
|
||||
|
||||
#else
|
||||
return get_io_service ().post (HandlerCall (HandlerCall::Post (),
|
||||
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler),
|
||||
error_code (), bytes_transferred));
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
return m_next_layer.async_read_some (buffers,
|
||||
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
|
||||
}
|
||||
|
||||
template <typename ConstBufferSequence, typename WriteHandler>
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE(WriteHandler, void (error_code, std::size_t))
|
||||
async_write_some (ConstBufferSequence const& buffers,
|
||||
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
|
||||
{
|
||||
return m_next_layer.async_write_some (buffers,
|
||||
BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
|
||||
}
|
||||
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t read_some (MutableBufferSequence const& buffers)
|
||||
{
|
||||
@@ -196,6 +126,62 @@ public:
|
||||
return amount;
|
||||
}
|
||||
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t read_some (MutableBufferSequence const& buffers, error_code& ec)
|
||||
{
|
||||
if (m_buffer.size () > 0)
|
||||
{
|
||||
ec = error_code ();
|
||||
std::size_t const bytes_transferred = boost::asio::buffer_copy (
|
||||
buffers, m_buffer.data ());
|
||||
m_buffer.consume (bytes_transferred);
|
||||
return bytes_transferred;
|
||||
}
|
||||
return m_next_layer.read_some (buffers, ec);
|
||||
}
|
||||
|
||||
template <typename ConstBufferSequence>
|
||||
std::size_t write_some (ConstBufferSequence const& buffers)
|
||||
{
|
||||
error_code ec;
|
||||
std::size_t const amount = write_some (buffers, ec);
|
||||
if (ec)
|
||||
throw_error (ec, __FILE__, __LINE__);
|
||||
return amount;
|
||||
}
|
||||
|
||||
template <typename ConstBufferSequence>
|
||||
std::size_t write_some (ConstBufferSequence const& buffers, error_code& ec)
|
||||
{
|
||||
return m_next_layer.write_some (buffers, ec);
|
||||
}
|
||||
|
||||
template <typename MutableBufferSequence, typename ReadHandler>
|
||||
void async_read_some (MutableBufferSequence const& buffers,
|
||||
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
|
||||
{
|
||||
if (m_buffer.size () > 0)
|
||||
{
|
||||
std::size_t const bytes_transferred = boost::asio::buffer_copy (
|
||||
buffers, m_buffer.data ());
|
||||
m_buffer.consume (bytes_transferred);
|
||||
get_io_service ().wrap (
|
||||
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)) (
|
||||
error_code (), bytes_transferred);
|
||||
return;
|
||||
}
|
||||
m_next_layer.async_read_some (buffers,
|
||||
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler));
|
||||
}
|
||||
|
||||
template <typename ConstBufferSequence, typename WriteHandler>
|
||||
void async_write_some (ConstBufferSequence const& buffers,
|
||||
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
|
||||
{
|
||||
m_next_layer.async_write_some (buffers,
|
||||
BOOST_ASIO_MOVE_CAST(WriteHandler)(handler));
|
||||
}
|
||||
|
||||
private:
|
||||
Stream m_next_layer;
|
||||
boost::asio::streambuf m_buffer;
|
||||
@@ -21,6 +21,8 @@ Socket::~Socket ()
|
||||
{
|
||||
}
|
||||
|
||||
#if ! BEAST_COMPILER_CHECKS_SOCKET_OVERRIDES
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// basic_io_object
|
||||
@@ -28,7 +30,7 @@ Socket::~Socket ()
|
||||
|
||||
boost::asio::io_service& Socket::get_io_service ()
|
||||
{
|
||||
pure_virtual ();
|
||||
pure_virtual_called (__FILE__, __LINE__);
|
||||
return *static_cast <boost::asio::io_service*>(nullptr);
|
||||
}
|
||||
|
||||
@@ -39,29 +41,29 @@ boost::asio::io_service& Socket::get_io_service ()
|
||||
|
||||
void* Socket::lowest_layer (char const*) const
|
||||
{
|
||||
pure_virtual ();
|
||||
pure_virtual_called (__FILE__, __LINE__);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void* Socket::native_handle (char const*) const
|
||||
{
|
||||
pure_virtual ();
|
||||
pure_virtual_called (__FILE__, __LINE__);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
boost::system::error_code Socket::cancel (boost::system::error_code& ec)
|
||||
{
|
||||
return pure_virtual (ec);
|
||||
return pure_virtual_error (ec, __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
boost::system::error_code Socket::shutdown (shutdown_type, boost::system::error_code& ec)
|
||||
{
|
||||
return pure_virtual (ec);
|
||||
return pure_virtual_error (ec, __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
boost::system::error_code Socket::close (boost::system::error_code& ec)
|
||||
{
|
||||
return pure_virtual (ec);
|
||||
return pure_virtual_error (ec, __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -71,22 +73,14 @@ boost::system::error_code Socket::close (boost::system::error_code& ec)
|
||||
|
||||
boost::system::error_code Socket::accept (Socket&, boost::system::error_code& ec)
|
||||
{
|
||||
return pure_virtual (ec);
|
||||
return pure_virtual_error (ec, __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(HandlerCall, void (boost::system::error_code))
|
||||
Socket::async_accept (Socket&, HandlerCall const& handler)
|
||||
void Socket::async_accept (Socket&, SharedHandlerPtr handler)
|
||||
{
|
||||
#if BEAST_ASIO_HAS_FUTURE_RETURNS
|
||||
boost::asio::detail::async_result_init<
|
||||
HandlerCall, void (boost::system::error_code)> init( handler);
|
||||
get_io_service ().post (HandlerCall (HandlerCall::Post (),
|
||||
handler, pure_virtual_error ()));
|
||||
return init.result.get();
|
||||
#else
|
||||
get_io_service ().post (HandlerCall (HandlerCall::Post(),
|
||||
handler, pure_virtual_error ()));
|
||||
#endif
|
||||
get_io_service ().wrap (
|
||||
BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler))
|
||||
(pure_virtual_error ());
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -96,44 +90,30 @@ Socket::async_accept (Socket&, HandlerCall const& handler)
|
||||
|
||||
std::size_t Socket::read_some (MutableBuffers const&, boost::system::error_code& ec)
|
||||
{
|
||||
pure_virtual (ec);
|
||||
pure_virtual_called (__FILE__, __LINE__);
|
||||
ec = pure_virtual_error ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::size_t Socket::write_some (ConstBuffers const&, boost::system::error_code& ec)
|
||||
{
|
||||
pure_virtual (ec);
|
||||
pure_virtual_called (__FILE__, __LINE__);
|
||||
ec = pure_virtual_error ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(HandlerCall, void (boost::system::error_code, std::size_t))
|
||||
Socket::async_read_some (MutableBuffers const&, HandlerCall const& handler)
|
||||
void Socket::async_read_some (MutableBuffers const&, SharedHandlerPtr handler)
|
||||
{
|
||||
#if BEAST_ASIO_HAS_FUTURE_RETURNS
|
||||
boost::asio::detail::async_result_init<
|
||||
HandlerCall, void (boost::system::error_code, std::size_t)> init(handler);
|
||||
get_io_service ().post (HandlerCall (HandlerCall::Post (),
|
||||
handler, pure_virtual_error (), 0));
|
||||
return init.result.get();
|
||||
#else
|
||||
get_io_service ().post (HandlerCall (HandlerCall::Post (),
|
||||
handler , pure_virtual_error (), 0));
|
||||
#endif
|
||||
get_io_service ().wrap (
|
||||
BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler))
|
||||
(pure_virtual_error (), 0);
|
||||
}
|
||||
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(HandlerCall, void (boost::system::error_code, std::size_t))
|
||||
Socket::async_write_some (ConstBuffers const&, HandlerCall const& handler)
|
||||
void Socket::async_write_some (ConstBuffers const&, SharedHandlerPtr handler)
|
||||
{
|
||||
#if BEAST_ASIO_HAS_FUTURE_RETURNS
|
||||
boost::asio::detail::async_result_init<
|
||||
HandlerCall, void (boost::system::error_code, std::size_t)> init(handler);
|
||||
get_io_service ().post (HandlerCall (HandlerCall::Post (),
|
||||
handler, pure_virtual_error (), 0));
|
||||
return init.result.get();
|
||||
#else
|
||||
get_io_service ().post (HandlerCall (HandlerCall::Post (),
|
||||
handler, pure_virtual_error (), 0));
|
||||
#endif
|
||||
get_io_service ().wrap (
|
||||
BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler))
|
||||
(pure_virtual_error (), 0);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -148,22 +128,14 @@ bool Socket::needs_handshake ()
|
||||
|
||||
boost::system::error_code Socket::handshake (handshake_type, boost::system::error_code& ec)
|
||||
{
|
||||
return pure_virtual (ec);
|
||||
return pure_virtual_error (ec, __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(HandlerCall, void (boost::system::error_code))
|
||||
Socket::async_handshake (handshake_type, HandlerCall const& handler)
|
||||
void Socket::async_handshake (handshake_type, SharedHandlerPtr handler)
|
||||
{
|
||||
#if BEAST_ASIO_HAS_FUTURE_RETURNS
|
||||
boost::asio::detail::async_result_init<
|
||||
HandlerCall, void (boost::system::error_code)> init( handler);
|
||||
get_io_service ().post (HandlerCall (HandlerCall::Post (),
|
||||
handler, pure_virtual_error ()));
|
||||
return init.result.get();
|
||||
#else
|
||||
get_io_service ().post (HandlerCall (HandlerCall::Post(),
|
||||
handler, pure_virtual_error ()));
|
||||
#endif
|
||||
get_io_service ().wrap (
|
||||
BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler))
|
||||
(pure_virtual_error ());
|
||||
}
|
||||
|
||||
#if BEAST_ASIO_HAS_BUFFEREDHANDSHAKE
|
||||
@@ -171,44 +143,30 @@ Socket::async_handshake (handshake_type, HandlerCall const& handler)
|
||||
boost::system::error_code Socket::handshake (handshake_type,
|
||||
ConstBuffers const&, boost::system::error_code& ec)
|
||||
{
|
||||
return pure_virtual (ec);
|
||||
return pure_virtual_error (ec, __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(HandlerCall, void (boost::system::error_code, std::size_t))
|
||||
Socket::async_handshake (handshake_type, ConstBuffers const&, HandlerCall const& handler)
|
||||
void Socket::async_handshake (handshake_type, ConstBuffers const&, SharedHandlerPtr handler)
|
||||
{
|
||||
#if BEAST_ASIO_HAS_FUTURE_RETURNS
|
||||
boost::asio::detail::async_result_init<
|
||||
HandlerCall, void (boost::system::error_code, std::size_t)> init(handler);
|
||||
get_io_service ().post (HandlerCall (HandlerCall::Post (),
|
||||
handler, pure_virtual_error (), 0));
|
||||
return init.result.get();
|
||||
#else
|
||||
get_io_service ().post (HandlerCall (HandlerCall::Post (),
|
||||
handler , pure_virtual_error (), 0));
|
||||
#endif
|
||||
get_io_service ().wrap (
|
||||
BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler))
|
||||
(pure_virtual_error (), 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
boost::system::error_code Socket::shutdown (boost::system::error_code& ec)
|
||||
{
|
||||
return pure_virtual (ec);
|
||||
return pure_virtual_error (ec, __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(HandlerCall, void (boost::system::error_code))
|
||||
Socket::async_shutdown (HandlerCall const& handler)
|
||||
void Socket::async_shutdown (SharedHandlerPtr handler)
|
||||
{
|
||||
#if BEAST_ASIO_HAS_FUTURE_RETURNS
|
||||
boost::asio::detail::async_result_init<
|
||||
HandlerCall, void (boost::system::error_code, std::size_t)> init (handler);
|
||||
get_io_service ().post (HandlerCall (HandlerCall::Post (),
|
||||
handler, pure_virtual_error ()));
|
||||
return init.result.get();
|
||||
#else
|
||||
get_io_service ().post (HandlerCall (HandlerCall::Post (),
|
||||
handler , pure_virtual_error ()));
|
||||
#endif
|
||||
get_io_service ().wrap (
|
||||
BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler))
|
||||
(pure_virtual_error ());
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#endif
|
||||
|
||||
@@ -34,9 +34,6 @@ class Socket
|
||||
, public boost::asio::ssl::stream_base
|
||||
, public boost::asio::socket_base
|
||||
{
|
||||
protected:
|
||||
typedef boost::system::error_code error_code;
|
||||
|
||||
public:
|
||||
virtual ~Socket ();
|
||||
|
||||
@@ -45,7 +42,8 @@ public:
|
||||
// basic_io_object
|
||||
//
|
||||
|
||||
virtual boost::asio::io_service& get_io_service ();
|
||||
virtual boost::asio::io_service& get_io_service ()
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
@@ -57,7 +55,7 @@ public:
|
||||
else a fatal error will occur.
|
||||
*/
|
||||
/** @{ */
|
||||
template <class Object>
|
||||
template <typename Object>
|
||||
Object& lowest_layer ()
|
||||
{
|
||||
Object* object (this->lowest_layer_ptr <Object> ());
|
||||
@@ -66,7 +64,7 @@ public:
|
||||
return *object;
|
||||
}
|
||||
|
||||
template <class Object>
|
||||
template <typename Object>
|
||||
Object const& lowest_layer () const
|
||||
{
|
||||
Object const* object (this->lowest_layer_ptr <Object> ());
|
||||
@@ -75,14 +73,14 @@ public:
|
||||
return *object;
|
||||
}
|
||||
|
||||
template <class Object>
|
||||
template <typename Object>
|
||||
Object* lowest_layer_ptr ()
|
||||
{
|
||||
return static_cast <Object*> (
|
||||
this->lowest_layer (typeid (Object).name ()));
|
||||
}
|
||||
|
||||
template <class Object>
|
||||
template <typename Object>
|
||||
Object const* lowest_layer_ptr () const
|
||||
{
|
||||
return static_cast <Object const*> (
|
||||
@@ -90,14 +88,15 @@ public:
|
||||
}
|
||||
/** @} */
|
||||
|
||||
virtual void* lowest_layer (char const* type_name) const;
|
||||
virtual void* lowest_layer (char const* type_name) const
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
/** Retrieve the underlying object.
|
||||
Note that you must know the type name for this to work, or
|
||||
else a fatal error will occur.
|
||||
*/
|
||||
/** @{ */
|
||||
template <class Object>
|
||||
template <typename Object>
|
||||
Object& native_handle ()
|
||||
{
|
||||
Object* object (this->native_handle_ptr <Object> ());
|
||||
@@ -106,7 +105,7 @@ public:
|
||||
return *object;
|
||||
}
|
||||
|
||||
template <class Object>
|
||||
template <typename Object>
|
||||
Object const& native_handle () const
|
||||
{
|
||||
Object const* object (this->native_handle_ptr <Object> ());
|
||||
@@ -115,14 +114,14 @@ public:
|
||||
return *object;
|
||||
}
|
||||
|
||||
template <class Object>
|
||||
template <typename Object>
|
||||
Object* native_handle_ptr ()
|
||||
{
|
||||
return static_cast <Object*> (
|
||||
this->native_handle (typeid (Object).name ()));
|
||||
}
|
||||
|
||||
template <class Object>
|
||||
template <typename Object>
|
||||
Object const* native_handle_ptr () const
|
||||
{
|
||||
return static_cast <Object const*> (
|
||||
@@ -130,51 +129,54 @@ public:
|
||||
}
|
||||
/** @} */
|
||||
|
||||
virtual void* native_handle (char const* type_name) const;
|
||||
virtual void* native_handle (char const* type_name) const
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
void cancel ()
|
||||
{
|
||||
error_code ec;
|
||||
throw_error (cancel (ec));
|
||||
throw_error (cancel (ec), __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
virtual error_code cancel (error_code& ec);
|
||||
virtual error_code cancel (error_code& ec)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
void shutdown (shutdown_type what)
|
||||
{
|
||||
error_code ec;
|
||||
throw_error (shutdown (what, ec));
|
||||
throw_error (shutdown (what, ec), __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
virtual error_code shutdown (shutdown_type what,
|
||||
error_code& ec);
|
||||
error_code& ec)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
void close ()
|
||||
{
|
||||
error_code ec;
|
||||
throw_error (close (ec));
|
||||
throw_error (close (ec), __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
virtual error_code close (error_code& ec);
|
||||
virtual error_code close (error_code& ec)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// basic_socket_acceptor
|
||||
//
|
||||
|
||||
virtual error_code accept (Socket& peer, error_code& ec);
|
||||
virtual error_code accept (Socket& peer, error_code& ec)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
template <class AcceptHandler>
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE(AcceptHandler, void (error_code))
|
||||
async_accept (Socket& peer, BOOST_ASIO_MOVE_ARG(AcceptHandler) handler)
|
||||
template <typename AcceptHandler>
|
||||
void async_accept (Socket& peer, BOOST_ASIO_MOVE_ARG(AcceptHandler) handler)
|
||||
{
|
||||
return async_accept (peer, HandlerCall (HandlerCall::Accept (),
|
||||
BOOST_ASIO_MOVE_CAST(AcceptHandler)(handler)));
|
||||
return async_accept (peer,
|
||||
newAcceptHandler (BOOST_ASIO_MOVE_CAST(AcceptHandler)(handler)));
|
||||
}
|
||||
|
||||
virtual
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(HandlerCall, void (error_code))
|
||||
async_accept (Socket& peer, HandlerCall const& handler);
|
||||
virtual void async_accept (Socket& peer, SharedHandlerPtr handler)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
@@ -183,54 +185,56 @@ public:
|
||||
|
||||
// SyncReadStream
|
||||
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/SyncReadStream.html
|
||||
template <class MutableBufferSequence>
|
||||
//
|
||||
template <typename MutableBufferSequence>
|
||||
std::size_t read_some (MutableBufferSequence const& buffers,
|
||||
error_code& ec)
|
||||
{
|
||||
return read_some (MutableBuffers (buffers), ec);
|
||||
}
|
||||
|
||||
virtual std::size_t read_some (MutableBuffers const& buffers, error_code& ec);
|
||||
virtual std::size_t read_some (MutableBuffers const& buffers, error_code& ec)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
// SyncWriteStream
|
||||
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/SyncWriteStream.html
|
||||
template <class ConstBufferSequence>
|
||||
//
|
||||
template <typename ConstBufferSequence>
|
||||
std::size_t write_some (ConstBufferSequence const& buffers, error_code &ec)
|
||||
{
|
||||
return write_some (ConstBuffers (buffers), ec);
|
||||
}
|
||||
|
||||
virtual std::size_t write_some (ConstBuffers const& buffers, error_code& ec);
|
||||
virtual std::size_t write_some (ConstBuffers const& buffers, error_code& ec)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
// AsyncReadStream
|
||||
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/AsyncReadStream.html
|
||||
template <class MutableBufferSequence, class ReadHandler>
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE(ReadHandler, void (error_code, std::size_t))
|
||||
async_read_some (MutableBufferSequence const& buffers, BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
|
||||
//
|
||||
template <typename MutableBufferSequence, typename ReadHandler>
|
||||
void async_read_some (MutableBufferSequence const& buffers,
|
||||
BOOST_ASIO_MOVE_ARG(ReadHandler) handler)
|
||||
{
|
||||
return async_read_some (MutableBuffers (buffers),
|
||||
HandlerCall (HandlerCall::Transfer (),
|
||||
BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)));
|
||||
newReadHandler (BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)));
|
||||
}
|
||||
|
||||
virtual
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(HandlerCall, void (error_code, std::size_t))
|
||||
async_read_some (MutableBuffers const& buffers, HandlerCall const& handler);
|
||||
virtual void async_read_some (MutableBuffers const& buffers, SharedHandlerPtr handler)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
// AsyncWriteStream
|
||||
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/AsyncWriteStream.html
|
||||
template <class ConstBufferSequence, class WriteHandler>
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE(WriteHandler, void (error_code, std::size_t))
|
||||
async_write_some (ConstBufferSequence const& buffers, BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
|
||||
//
|
||||
template <typename ConstBufferSequence, typename WriteHandler>
|
||||
void async_write_some (ConstBufferSequence const& buffers,
|
||||
BOOST_ASIO_MOVE_ARG(WriteHandler) handler)
|
||||
{
|
||||
return async_write_some (ConstBuffers (buffers),
|
||||
HandlerCall (HandlerCall::Transfer (),
|
||||
BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)));
|
||||
newWriteHandler (BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)));
|
||||
}
|
||||
|
||||
virtual
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(HandlerCall, void (error_code, std::size_t))
|
||||
async_write_some (ConstBuffers const& buffers, HandlerCall const& handler);
|
||||
virtual void async_write_some (ConstBuffers const& buffers, SharedHandlerPtr handler)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
@@ -249,7 +253,8 @@ public:
|
||||
|
||||
The default version returns false.
|
||||
*/
|
||||
virtual bool needs_handshake ();
|
||||
virtual bool needs_handshake ()
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
// ssl::stream::handshake (1 of 4)
|
||||
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ssl__stream/handshake/overload1.html
|
||||
@@ -257,29 +262,27 @@ public:
|
||||
void handshake (handshake_type type)
|
||||
{
|
||||
error_code ec;
|
||||
throw_error (handshake (type, ec));
|
||||
throw_error (handshake (type, ec), __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
// ssl::stream::handshake (2 of 4)
|
||||
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ssl__stream/handshake/overload2.html
|
||||
//
|
||||
virtual error_code handshake (handshake_type type,
|
||||
error_code& ec);
|
||||
virtual error_code handshake (handshake_type type, error_code& ec)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
// ssl::stream::async_handshake (1 of 2)
|
||||
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ssl__stream/async_handshake/overload1.html
|
||||
//
|
||||
template <typename HandshakeHandler>
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE(HandshakeHandler, void (error_code))
|
||||
async_handshake (handshake_type type, BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler)
|
||||
void async_handshake (handshake_type type, BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler)
|
||||
{
|
||||
return async_handshake (type, HandlerCall (HandlerCall::Error (),
|
||||
BOOST_ASIO_MOVE_CAST(HandshakeHandler)(handler)));
|
||||
return async_handshake (type,
|
||||
newHandshakeHandler (BOOST_ASIO_MOVE_CAST(HandshakeHandler)(handler)));
|
||||
}
|
||||
|
||||
virtual
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(HandlerCall, void (error_code))
|
||||
async_handshake (handshake_type type, HandlerCall const& handler);
|
||||
virtual void async_handshake (handshake_type type, SharedHandlerPtr handler)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
@@ -287,17 +290,17 @@ public:
|
||||
// ssl::stream::handshake (3 of 4)
|
||||
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ssl__stream/handshake/overload3.html
|
||||
//
|
||||
template <class ConstBufferSequence>
|
||||
template <typename ConstBufferSequence>
|
||||
void handshake (handshake_type type, ConstBufferSequence const& buffers)
|
||||
{
|
||||
error_code ec;
|
||||
throw_error (handshake (type, buffers, ec));
|
||||
throw_error (handshake (type, buffers, ec), __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
// ssl::stream::handshake (4 of 4)
|
||||
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ssl__stream/handshake/overload4.html
|
||||
//
|
||||
template <class ConstBufferSequence>
|
||||
template <typename ConstBufferSequence>
|
||||
error_code handshake (handshake_type type,
|
||||
ConstBufferSequence const& buffers, error_code& ec)
|
||||
{
|
||||
@@ -305,24 +308,23 @@ public:
|
||||
}
|
||||
|
||||
virtual error_code handshake (handshake_type type,
|
||||
ConstBuffers const& buffers, error_code& ec);
|
||||
ConstBuffers const& buffers, error_code& ec)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
// ssl::stream::async_handshake (2 of 2)
|
||||
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ssl__stream/async_handshake/overload2.html
|
||||
//
|
||||
template <class ConstBufferSequence, class BufferedHandshakeHandler>
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE(BufferedHandshakeHandler, void (error_code, std::size_t))
|
||||
async_handshake (handshake_type type, ConstBufferSequence const& buffers,
|
||||
template <typename ConstBufferSequence, typename BufferedHandshakeHandler>
|
||||
void async_handshake (handshake_type type, ConstBufferSequence const& buffers,
|
||||
BOOST_ASIO_MOVE_ARG(BufferedHandshakeHandler) handler)
|
||||
{
|
||||
return async_handshake (type, ConstBuffers (buffers),
|
||||
HandlerCall (HandlerCall::Transfer (),
|
||||
BOOST_ASIO_MOVE_CAST(BufferedHandshakeHandler)(handler)));
|
||||
newBufferedHandshakeHandler (BOOST_ASIO_MOVE_CAST(BufferedHandshakeHandler)(handler)));
|
||||
}
|
||||
|
||||
virtual
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(HandlerCall, void (error_code, std::size_t))
|
||||
async_handshake (handshake_type type, ConstBuffers const& buffers, HandlerCall const& handler);
|
||||
virtual void async_handshake (handshake_type type, ConstBuffers const& buffers,
|
||||
SharedHandlerPtr handler)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -333,24 +335,24 @@ public:
|
||||
void shutdown ()
|
||||
{
|
||||
error_code ec;
|
||||
throw_error (shutdown (ec));
|
||||
throw_error (shutdown (ec), __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
virtual error_code shutdown (error_code& ec);
|
||||
virtual error_code shutdown (error_code& ec)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
|
||||
// ssl::stream::async_shutdown
|
||||
// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ssl__stream/async_shutdown.html
|
||||
//
|
||||
template <class ShutdownHandler>
|
||||
template <typename ShutdownHandler>
|
||||
void async_shutdown (BOOST_ASIO_MOVE_ARG(ShutdownHandler) handler)
|
||||
{
|
||||
return async_shutdown (HandlerCall (HandlerCall::Error (),
|
||||
BOOST_ASIO_MOVE_CAST(ShutdownHandler)(handler)));
|
||||
return async_shutdown (
|
||||
newShutdownHandler (BOOST_ASIO_MOVE_CAST(ShutdownHandler)(handler)));
|
||||
}
|
||||
|
||||
virtual
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(HandlerCall, void (error_code))
|
||||
async_shutdown (HandlerCall const& handler);
|
||||
virtual void async_shutdown (SharedHandlerPtr handler)
|
||||
BEAST_SOCKET_VIRTUAL;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -23,14 +23,20 @@ boost::system::error_code SocketBase::pure_virtual_error ()
|
||||
boost::system::errc::function_not_supported);
|
||||
}
|
||||
|
||||
void SocketBase::pure_virtual ()
|
||||
boost::system::error_code SocketBase::pure_virtual_error (error_code& ec,
|
||||
char const* fileName, int lineNumber)
|
||||
{
|
||||
fatal_error ("A beast::Socket function was called on an object that doesn't support the interface");
|
||||
pure_virtual_called (fileName, lineNumber);
|
||||
return ec = pure_virtual_error ();
|
||||
}
|
||||
|
||||
boost::system::error_code SocketBase::pure_virtual (boost::system::error_code& ec)
|
||||
void SocketBase::pure_virtual_called (char const* fileName, int lineNumber)
|
||||
{
|
||||
pure_virtual ();
|
||||
ec = pure_virtual_error ();
|
||||
return ec;
|
||||
Throw (std::runtime_error ("pure virtual called"), fileName, lineNumber);
|
||||
}
|
||||
|
||||
void SocketBase::throw_error (error_code const& ec, char const* fileName, int lineNumber)
|
||||
{
|
||||
if (ec)
|
||||
Throw (boost::system::system_error (ec), fileName, lineNumber);
|
||||
}
|
||||
|
||||
@@ -20,21 +20,30 @@
|
||||
#ifndef BEAST_SOCKETBASE_H_INCLUDED
|
||||
#define BEAST_SOCKETBASE_H_INCLUDED
|
||||
|
||||
/** Implementation details for Socket.
|
||||
/** Common implementation details for Socket and related classes.
|
||||
Normally you wont need to use this.
|
||||
*/
|
||||
struct SocketBase
|
||||
{
|
||||
static boost::system::error_code pure_virtual_error ();
|
||||
static boost::system::error_code pure_virtual (boost::system::error_code& ec);
|
||||
static void pure_virtual ();
|
||||
protected:
|
||||
typedef boost::system::error_code error_code;
|
||||
|
||||
/** Called when the underlying object does not support the interface. */
|
||||
void throw_error (boost::system::error_code const& ec)
|
||||
{
|
||||
if (ec)
|
||||
Throw (boost::system::system_error (ec), __FILE__, __LINE__);
|
||||
}
|
||||
/** The error returned when a pure virtual is called.
|
||||
This is mostly academic since a pure virtual call generates
|
||||
a fatal error but in case that gets disabled, this will at
|
||||
least return a suitable error code.
|
||||
*/
|
||||
static error_code pure_virtual_error ();
|
||||
|
||||
/** Convenience for taking a reference and returning the error_code. */
|
||||
static error_code pure_virtual_error (error_code& ec,
|
||||
char const* fileName, int lineNumber);
|
||||
|
||||
/** Called when a function doesn't support the interface. */
|
||||
static void pure_virtual_called (char const* fileName, int lineNumber);
|
||||
|
||||
/** Called when synchronous functions without error parameters get an error. */
|
||||
static void throw_error (error_code const& ec, char const* fileName, int lineNumber);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -96,8 +96,16 @@ namespace SocketWrapperMemberChecks
|
||||
struct native_socket
|
||||
{
|
||||
typedef void* socket_type;
|
||||
inline native_socket (Socket&) : m_socket (nullptr) { SocketBase::pure_virtual (); }
|
||||
inline socket_type& get () { SocketBase::pure_virtual (); return m_socket; }
|
||||
inline native_socket (Socket&)
|
||||
: m_socket (nullptr)
|
||||
{
|
||||
SocketBase::pure_virtual_called (__FILE__, __LINE__);
|
||||
}
|
||||
inline socket_type& get ()
|
||||
{
|
||||
SocketBase::pure_virtual_called (__FILE__, __LINE__);
|
||||
return m_socket;
|
||||
}
|
||||
inline socket_type& operator-> () { return get (); }
|
||||
private:
|
||||
socket_type m_socket;
|
||||
@@ -109,7 +117,8 @@ namespace SocketWrapperMemberChecks
|
||||
typename T::protocol_type::socket> >::type>
|
||||
{
|
||||
typedef typename T::protocol_type::socket socket_type;
|
||||
inline native_socket (Socket& peer) : m_socket_ptr (&peer.native_handle <socket_type> ()) { }
|
||||
inline native_socket (Socket& peer)
|
||||
: m_socket_ptr (&peer.native_handle <socket_type> ()) { }
|
||||
inline socket_type& get () noexcept { return *m_socket_ptr; }
|
||||
inline socket_type& operator-> () noexcept { return get (); }
|
||||
private:
|
||||
@@ -178,11 +187,13 @@ public:
|
||||
{
|
||||
using namespace SocketWrapperMemberChecks;
|
||||
#if 0
|
||||
// This is the one that doesn't work, (void) arg lists
|
||||
return get_io_service (
|
||||
Type <HandshakeHandler> ( (
|
||||
EnableIf <has_get_io_service <this_layer_type,
|
||||
io_service ()>::value> ());
|
||||
#else
|
||||
// BEAST_DEFINE_IS_CALL_POSSIBLE doesn't seem to
|
||||
// match (void) argument lists so this is a workaround.
|
||||
//
|
||||
return get_io_service (boost::true_type ());
|
||||
#endif
|
||||
}
|
||||
@@ -196,7 +207,7 @@ public:
|
||||
boost::asio::io_service& get_io_service (
|
||||
boost::false_type)
|
||||
{
|
||||
pure_virtual ();
|
||||
pure_virtual_called (__FILE__, __LINE__);
|
||||
return *static_cast <boost::asio::io_service*>(nullptr);
|
||||
}
|
||||
|
||||
@@ -252,7 +263,7 @@ public:
|
||||
void* lowest_layer (char const*,
|
||||
boost::false_type) const
|
||||
{
|
||||
pure_virtual ();
|
||||
pure_virtual_called (__FILE__, __LINE__);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -285,7 +296,7 @@ public:
|
||||
error_code cancel (error_code& ec,
|
||||
boost::false_type)
|
||||
{
|
||||
return pure_virtual (ec);
|
||||
return pure_virtual_error (ec, __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -308,7 +319,7 @@ public:
|
||||
error_code shutdown (shutdown_type, error_code& ec,
|
||||
boost::false_type)
|
||||
{
|
||||
return pure_virtual (ec);
|
||||
return pure_virtual_error (ec, __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -330,7 +341,7 @@ public:
|
||||
error_code close (error_code& ec,
|
||||
boost::false_type)
|
||||
{
|
||||
return pure_virtual (ec);
|
||||
return pure_virtual_error (ec, __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -358,47 +369,35 @@ public:
|
||||
error_code accept (Socket&, error_code& ec,
|
||||
boost::false_type)
|
||||
{
|
||||
return pure_virtual (ec);
|
||||
return pure_virtual_error (ec, __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(HandlerCall, void (error_code))
|
||||
async_accept (Socket& peer, HandlerCall const& handler)
|
||||
void async_accept (Socket& peer, SharedHandlerPtr handler)
|
||||
{
|
||||
using namespace SocketWrapperMemberChecks;
|
||||
typedef typename native_socket <this_layer_type>::socket_type socket_type;
|
||||
return async_accept (peer, handler,
|
||||
async_accept (peer, BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler),
|
||||
EnableIf <has_async_accept <this_layer_type,
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(HandlerCall, void (error_code))
|
||||
(socket_type&, BOOST_ASIO_MOVE_ARG(HandlerCall))>::value> ());
|
||||
void (socket_type&, BOOST_ASIO_MOVE_ARG(SharedHandlerPtr))>::value> ());
|
||||
}
|
||||
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(HandlerCall, void (error_code))
|
||||
async_accept (Socket& peer, HandlerCall const& handler,
|
||||
void async_accept (Socket& peer, BOOST_ASIO_MOVE_ARG(SharedHandlerPtr) handler,
|
||||
boost::true_type)
|
||||
{
|
||||
using namespace SocketWrapperMemberChecks;
|
||||
return m_object.async_accept (
|
||||
native_socket <this_layer_type> (peer).get (), handler);
|
||||
m_object.async_accept (
|
||||
native_socket <this_layer_type> (peer).get (),
|
||||
BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler));
|
||||
}
|
||||
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(HandlerCall, void (error_code))
|
||||
async_accept (Socket&, HandlerCall const& handler,
|
||||
void async_accept (Socket&, BOOST_ASIO_MOVE_ARG(SharedHandlerPtr) handler,
|
||||
boost::false_type)
|
||||
{
|
||||
#if BEAST_ASIO_HAS_FUTURE_RETURNS
|
||||
boost::asio::detail::async_result_init<
|
||||
HandlerCall, void (error_code)> init(handler);
|
||||
get_io_service ().post (HandlerCall (HandlerCall::Post (),
|
||||
init.handler, pure_virtual_error ()));
|
||||
return init.result.get();
|
||||
|
||||
#else
|
||||
get_io_service ().post (HandlerCall (HandlerCall::Post (),
|
||||
handler, pure_virtual_error ()));
|
||||
|
||||
#endif
|
||||
get_io_service ().wrap (
|
||||
BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler))
|
||||
(pure_virtual_error ());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -425,7 +424,8 @@ public:
|
||||
std::size_t read_some (MutableBufferSequence const&, error_code& ec,
|
||||
boost::false_type)
|
||||
{
|
||||
pure_virtual (ec);
|
||||
pure_virtual_called (__FILE__, __LINE__);
|
||||
ec = pure_virtual_error ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -450,82 +450,63 @@ public:
|
||||
std::size_t write_some (ConstBufferSequence const&, error_code& ec,
|
||||
boost::false_type)
|
||||
{
|
||||
pure_virtual (ec);
|
||||
pure_virtual_called (__FILE__, __LINE__);
|
||||
ec = pure_virtual_error ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(HandlerCall, void (error_code, std::size_t))
|
||||
async_read_some (MutableBuffers const& buffers, BOOST_ASIO_MOVE_ARG(HandlerCall) handler)
|
||||
void async_read_some (MutableBuffers const& buffers, SharedHandlerPtr handler)
|
||||
{
|
||||
using namespace SocketWrapperMemberChecks;
|
||||
return async_read_some (buffers, BOOST_ASIO_MOVE_CAST(HandlerCall)(handler),
|
||||
async_read_some (buffers, BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler),
|
||||
EnableIf <has_async_read_some <this_layer_type,
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(HandlerCall, void (error_code, std::size_t))
|
||||
(MutableBuffers const&, BOOST_ASIO_MOVE_ARG(HandlerCall))>::value> ());
|
||||
void (MutableBuffers const&, BOOST_ASIO_MOVE_ARG(SharedHandlerPtr))>::value> ());
|
||||
}
|
||||
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(HandlerCall, void (error_code, std::size_t))
|
||||
async_read_some (MutableBuffers const& buffers, HandlerCall const& handler,
|
||||
void async_read_some (MutableBuffers const& buffers,
|
||||
BOOST_ASIO_MOVE_ARG(SharedHandlerPtr) handler,
|
||||
boost::true_type)
|
||||
{
|
||||
return m_object.async_read_some (buffers, handler);
|
||||
m_object.async_read_some (buffers,
|
||||
BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler));
|
||||
}
|
||||
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(HandlerCall, void (error_code, std::size_t))
|
||||
async_read_some (MutableBuffers const&, HandlerCall const& handler,
|
||||
void async_read_some (MutableBuffers const&,
|
||||
BOOST_ASIO_MOVE_ARG(SharedHandlerPtr) handler,
|
||||
boost::false_type)
|
||||
{
|
||||
#if BEAST_ASIO_HAS_FUTURE_RETURNS
|
||||
boost::asio::detail::async_result_init<
|
||||
HandlerCall, void (error_code, std::size_t)> init(handler);
|
||||
get_io_service ().post (HandlerCall (HandlerCall::Post (),
|
||||
init.handler, pure_virtual_error (), 0));
|
||||
return init.result.get();
|
||||
|
||||
#else
|
||||
get_io_service ().post (HandlerCall (HandlerCall::Post (),
|
||||
handler, pure_virtual_error (), 0));
|
||||
|
||||
#endif
|
||||
get_io_service ().wrap (
|
||||
BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler))
|
||||
(pure_virtual_error (), 0);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(HandlerCall, void (error_code, std::size_t))
|
||||
async_write_some (ConstBuffers const& buffers, HandlerCall const& handler)
|
||||
void async_write_some (ConstBuffers const& buffers, SharedHandlerPtr handler)
|
||||
{
|
||||
using namespace SocketWrapperMemberChecks;
|
||||
return async_write_some (buffers, handler,
|
||||
async_write_some (buffers, BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler),
|
||||
EnableIf <has_async_write_some <this_layer_type,
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(HandlerCall, void (error_code, std::size_t))
|
||||
(ConstBuffers const&, HandlerCall const&)>::value> ());
|
||||
void (ConstBuffers const&, BOOST_ASIO_MOVE_ARG(SharedHandlerPtr))>::value> ());
|
||||
}
|
||||
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(HandlerCall, void (error_code, std::size_t))
|
||||
async_write_some (ConstBuffers const& buffers, HandlerCall const& handler,
|
||||
void async_write_some (ConstBuffers const& buffers,
|
||||
BOOST_ASIO_MOVE_ARG(SharedHandlerPtr) handler,
|
||||
boost::true_type)
|
||||
{
|
||||
return m_object.async_write_some (buffers, handler);
|
||||
m_object.async_write_some (buffers,
|
||||
BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler));
|
||||
}
|
||||
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(HandlerCall, void (error_code, std::size_t))
|
||||
async_write_some (ConstBuffers const&, HandlerCall const& handler,
|
||||
void async_write_some (ConstBuffers const&,
|
||||
BOOST_ASIO_MOVE_ARG(SharedHandlerPtr) handler,
|
||||
boost::false_type)
|
||||
{
|
||||
#if BEAST_ASIO_HAS_FUTURE_RETURNS
|
||||
boost::asio::detail::async_result_init<
|
||||
HandlerCall, void (error_code, std::size_t)> init(handler);
|
||||
get_io_service ().post (HandlerCall (HandlerCall::Post (),
|
||||
init.handler, pure_virtual_error (), 0));
|
||||
return init.result.get();
|
||||
|
||||
#else
|
||||
get_io_service ().post (HandlerCall (HandlerCall::Post (),
|
||||
handler, pure_virtual_error (), 0));
|
||||
|
||||
#endif
|
||||
get_io_service ().wrap (
|
||||
BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler))
|
||||
(pure_virtual_error (), 0);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -540,8 +521,7 @@ public:
|
||||
has_handshake <this_layer_type,
|
||||
error_code (handshake_type, error_code&)>::value ||
|
||||
has_async_handshake <this_layer_type,
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(HandlerCall, void (error_code))
|
||||
(handshake_type, BOOST_ASIO_MOVE_ARG(HandlerCall))>::value;
|
||||
void (handshake_type, BOOST_ASIO_MOVE_ARG(SharedHandlerPtr))>::value;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -563,49 +543,41 @@ public:
|
||||
error_code handshake (handshake_type, error_code& ec,
|
||||
boost::false_type)
|
||||
{
|
||||
return pure_virtual (ec);
|
||||
return pure_virtual_error (ec, __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(HandlerCall, void (error_code))
|
||||
async_handshake (handshake_type type, HandlerCall const& handler)
|
||||
void async_handshake (handshake_type type, SharedHandlerPtr handler)
|
||||
{
|
||||
using namespace SocketWrapperMemberChecks;
|
||||
return async_handshake (type, handler,
|
||||
async_handshake (type, BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler),
|
||||
EnableIf <has_async_handshake <this_layer_type,
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(HandlerCall, void (error_code))
|
||||
(handshake_type, HandlerCall const& handler)>::value> ());
|
||||
void (handshake_type, BOOST_ASIO_MOVE_ARG(SharedHandlerPtr))>::value> ());
|
||||
}
|
||||
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(HandlerCall, void (error_code))
|
||||
async_handshake (handshake_type type, HandlerCall const& handler,
|
||||
void async_handshake (handshake_type type,
|
||||
BOOST_ASIO_MOVE_ARG(SharedHandlerPtr) handler,
|
||||
boost::true_type)
|
||||
{
|
||||
return m_object.async_handshake (type, handler);
|
||||
m_object.async_handshake (type,
|
||||
BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler));
|
||||
}
|
||||
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(HandlerCall, void (error_code))
|
||||
async_handshake (handshake_type, HandlerCall const& handler,
|
||||
void async_handshake (handshake_type, BOOST_ASIO_MOVE_ARG(SharedHandlerPtr) handler,
|
||||
boost::false_type)
|
||||
{
|
||||
#if BEAST_ASIO_HAS_FUTURE_RETURNS
|
||||
boost::asio::detail::async_result_init<
|
||||
HandlerCall, void (error_code)> init(handler);
|
||||
get_io_service ().post (HandlerCall (HandlerCall::Post (),
|
||||
init.handler, pure_virtual_error ()));
|
||||
return init.result.get();
|
||||
#else
|
||||
get_io_service ().post (HandlerCall (HandlerCall::Post (),
|
||||
handler, pure_virtual_error ()));
|
||||
#endif
|
||||
get_io_service ().wrap (
|
||||
BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler))
|
||||
(pure_virtual_error ());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
#if BEAST_ASIO_HAS_BUFFEREDHANDSHAKE
|
||||
|
||||
error_code handshake (handshake_type type, ConstBuffers const& buffers, error_code& ec)
|
||||
error_code handshake (handshake_type type,
|
||||
ConstBuffers const& buffers, error_code& ec)
|
||||
{
|
||||
using namespace SocketWrapperMemberChecks;
|
||||
return handshake (type, buffers, ec,
|
||||
@@ -613,7 +585,8 @@ public:
|
||||
error_code (handshake_type, ConstBuffers const&, error_code&)>::value> ());
|
||||
}
|
||||
|
||||
error_code handshake (handshake_type type, ConstBuffers const& buffers, error_code& ec,
|
||||
error_code handshake (handshake_type type,
|
||||
ConstBuffers const& buffers, error_code& ec,
|
||||
boost::true_type)
|
||||
{
|
||||
return m_object.handshake (type, buffers, ec);
|
||||
@@ -622,45 +595,37 @@ public:
|
||||
error_code handshake (handshake_type, ConstBuffers const&, error_code& ec,
|
||||
boost::false_type)
|
||||
{
|
||||
return pure_virtual (ec);
|
||||
return pure_virtual_error (ec, __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(HandlerCall, void (error_code, std::size_t))
|
||||
async_handshake (handshake_type type, ConstBuffers const& buffers,
|
||||
HandlerCall const& handler)
|
||||
void async_handshake (handshake_type type,
|
||||
ConstBuffers const& buffers, SharedHandlerPtr handler)
|
||||
{
|
||||
using namespace SocketWrapperMemberChecks;
|
||||
return async_handshake (type, buffers, handler,
|
||||
async_handshake (type, buffers,
|
||||
BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler),
|
||||
EnableIf <has_async_handshake <this_layer_type,
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(HandlerCall, void (error_code, std::size_t))
|
||||
(handshake_type, ConstBuffers const&, error_code&)>::value> ());
|
||||
void (handshake_type, ConstBuffers const&,
|
||||
BOOST_ASIO_MOVE_ARG(SharedHandlerPtr))>::value> ());
|
||||
}
|
||||
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(HandlerCall, void (error_code, std::size_t))
|
||||
async_handshake (handshake_type type, ConstBuffers const& buffers, HandlerCall const& handler,
|
||||
void async_handshake (handshake_type type, ConstBuffers const& buffers,
|
||||
BOOST_ASIO_MOVE_ARG(SharedHandlerPtr) handler,
|
||||
boost::true_type)
|
||||
{
|
||||
return m_object.async_handshake (type, buffers, handler);
|
||||
m_object.async_handshake (type, buffers,
|
||||
BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler));
|
||||
}
|
||||
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(HandlerCall, void (error_code, std::size_t))
|
||||
async_handshake (handshake_type, ConstBuffers const&, HandlerCall const& handler,
|
||||
void async_handshake (handshake_type, ConstBuffers const&,
|
||||
BOOST_ASIO_MOVE_ARG(SharedHandlerPtr) handler,
|
||||
boost::false_type)
|
||||
{
|
||||
#if BEAST_ASIO_HAS_FUTURE_RETURNS
|
||||
boost::asio::detail::async_result_init<
|
||||
HandlerCall, void (error_code, std::size_t)> init(handler);
|
||||
get_io_service ().post (HandlerCall (HandlerCall::Post (),
|
||||
init.handler, pure_virtual_error (), 0));
|
||||
return init.result.get();
|
||||
|
||||
#else
|
||||
get_io_service ().post (HandlerCall (HandlerCall::Post (),
|
||||
handler, pure_virtual_error (), 0));
|
||||
|
||||
#endif
|
||||
get_io_service ().wrap (
|
||||
BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler))
|
||||
(pure_virtual_error (), 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -684,43 +649,32 @@ public:
|
||||
error_code shutdown (error_code& ec,
|
||||
boost::false_type)
|
||||
{
|
||||
return pure_virtual (ec);
|
||||
return pure_virtual_error (ec, __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void async_shutdown (HandlerCall const& handler)
|
||||
void async_shutdown (SharedHandlerPtr handler)
|
||||
{
|
||||
using namespace SocketWrapperMemberChecks;
|
||||
return async_shutdown (handler,
|
||||
async_shutdown (BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler),
|
||||
EnableIf <has_async_shutdown <this_layer_type,
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(HandlerCall, void (error_code))
|
||||
(HandlerCall const& handler)>::value> ());
|
||||
void (BOOST_ASIO_MOVE_ARG(SharedHandlerPtr))>::value> ());
|
||||
}
|
||||
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(HandlerCall, void (error_code))
|
||||
async_shutdown (HandlerCall const& handler,
|
||||
void async_shutdown (BOOST_ASIO_MOVE_ARG(SharedHandlerPtr) handler,
|
||||
boost::true_type)
|
||||
{
|
||||
return m_object.async_shutdown (handler);
|
||||
m_object.async_shutdown (
|
||||
BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler));
|
||||
}
|
||||
|
||||
BEAST_ASIO_INITFN_RESULT_TYPE_MEMBER(HandlerCall, void (error_code))
|
||||
async_shutdown (HandlerCall const& handler,
|
||||
void async_shutdown (BOOST_ASIO_MOVE_ARG(SharedHandlerPtr) handler,
|
||||
boost::false_type)
|
||||
{
|
||||
#if BEAST_ASIO_HAS_FUTURE_RETURNS
|
||||
boost::asio::detail::async_result_init<
|
||||
HandlerCall, void (error_code, std::size_t)> init(handler);
|
||||
get_io_service ().post (HandlerCall (HandlerCall::Post (),
|
||||
init.handler, pure_virtual_error ()));
|
||||
return init.result.get();
|
||||
|
||||
#else
|
||||
get_io_service ().post (HandlerCall (HandlerCall::Post (),
|
||||
handler, pure_virtual_error ()));
|
||||
|
||||
#endif
|
||||
get_io_service ().wrap (
|
||||
BOOST_ASIO_MOVE_CAST(SharedHandlerPtr)(handler))
|
||||
(pure_virtual_error ());
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -38,6 +38,8 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <boost/version.hpp>
|
||||
|
||||
#include <boost/array.hpp>
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/asio/ssl.hpp>
|
||||
@@ -46,11 +48,44 @@
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/type_traits.hpp>
|
||||
|
||||
// Unfortunately, we need to use some boost detail
|
||||
//
|
||||
// https://svn.boost.org/trac/boost/ticket/9024
|
||||
//
|
||||
#include <boost/asio/detail/handler_alloc_helpers.hpp>
|
||||
#include <boost/asio/detail/handler_invoke_helpers.hpp>
|
||||
|
||||
// Not sure when handler_type was added but it's not in 1.48
|
||||
#ifndef BEAST_ASIO_HAS_HANDLER_TYPE
|
||||
# if BOOST_VERSION >= 105400
|
||||
# define BEAST_ASIO_HAS_HANDLER_TYPE 1
|
||||
# else
|
||||
# define BEAST_ASIO_HAS_HANDLER_TYPE 0
|
||||
# endif
|
||||
#endif
|
||||
#if BEAST_ASIO_HAS_HANDLER_TYPE
|
||||
# include <boost/asio/handler_type.hpp>
|
||||
# define BEAST_ASIO_HANDLER_TYPE(h, sig) BOOST_ASIO_HANDLER_TYPE(h, sig)
|
||||
#else
|
||||
# define BEAST_ASIO_HANDLER_TYPE(h, sig) h
|
||||
#endif
|
||||
|
||||
// Continuation hooks added in 1.54.0
|
||||
#ifndef BEAST_ASIO_HAS_CONTINUATION_HOOKS
|
||||
# if BOOST_VERSION >= 105400
|
||||
# define BEAST_ASIO_HAS_CONTINUATION_HOOKS 1
|
||||
# else
|
||||
# define BEAST_ASIO_HAS_CONTINUATION_HOOKS 0
|
||||
# endif
|
||||
#endif
|
||||
#if BEAST_ASIO_HAS_CONTINUATION_HOOKS
|
||||
# include <boost/asio/detail/handler_cont_helpers.hpp>
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Configure some options based on the version of boost
|
||||
#include <boost/version.hpp>
|
||||
#if (BOOST_VERSION / 100) >= 1054
|
||||
#if BOOST_VERSION >= 105400
|
||||
# ifndef BEAST_ASIO_HAS_BUFFEREDHANDSHAKE
|
||||
# define BEAST_ASIO_HAS_BUFFEREDHANDSHAKE 1
|
||||
# endif
|
||||
|
||||
82
modules/beast_asio/system/beast_BoostUnitTests.cpp
Normal file
82
modules/beast_asio/system/beast_BoostUnitTests.cpp
Normal file
@@ -0,0 +1,82 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
/** Test for showing information about the build of boost.
|
||||
*/
|
||||
class BoostUnitTests : public UnitTest
|
||||
{
|
||||
public:
|
||||
struct BoostVersion
|
||||
{
|
||||
explicit BoostVersion (int value)
|
||||
: vmajor (value / 100000)
|
||||
, vminor ((value / 100) % 100)
|
||||
, vpatch (value % 100)
|
||||
{
|
||||
}
|
||||
|
||||
String toString () const noexcept
|
||||
{
|
||||
return String (vmajor) + "." +
|
||||
String (vminor).paddedLeft ('0', 2) + "." +
|
||||
String (vpatch).paddedLeft ('0', 2);
|
||||
}
|
||||
|
||||
int vmajor;
|
||||
int vminor;
|
||||
int vpatch;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
minimumVersion = 104700
|
||||
};
|
||||
|
||||
// To prevent constant conditional expression warning
|
||||
static int getMinimumVersion ()
|
||||
{
|
||||
return minimumVersion;
|
||||
}
|
||||
|
||||
void runTest ()
|
||||
{
|
||||
beginTestCase ("version");
|
||||
|
||||
BoostVersion version (BOOST_VERSION);
|
||||
|
||||
logMessage (String ("BOOST_VERSION = " + version.toString ()));
|
||||
logMessage (String ("BOOST_LIB_VERSION = '") + BOOST_LIB_VERSION + "'");
|
||||
|
||||
if (BOOST_VERSION >= getMinimumVersion ())
|
||||
{
|
||||
pass ();
|
||||
}
|
||||
else
|
||||
{
|
||||
fail (String ("Boost version is below ") +
|
||||
BoostVersion (minimumVersion).toString ());
|
||||
}
|
||||
}
|
||||
|
||||
BoostUnitTests () : UnitTest ("boost", "beast")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
static BoostUnitTests boostUnitTests;
|
||||
@@ -104,7 +104,10 @@ bool TestPeerBasics::success (boost::system::error_code const& ec, bool eofIsOka
|
||||
{
|
||||
if (eofIsOkay && ec == boost::asio::error::eof)
|
||||
return true;
|
||||
return ! ec;
|
||||
if (! ec)
|
||||
return true;
|
||||
breakpoint (ec);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TestPeerBasics::failure (boost::system::error_code const& ec, bool eofIsOkay) noexcept
|
||||
@@ -115,9 +118,14 @@ bool TestPeerBasics::failure (boost::system::error_code const& ec, bool eofIsOka
|
||||
bool TestPeerBasics::expected (bool condition, boost::system::error_code& ec) noexcept
|
||||
{
|
||||
if (condition)
|
||||
{
|
||||
ec = boost::system::error_code ();
|
||||
}
|
||||
else
|
||||
{
|
||||
make_error (errc::unexpected, ec);
|
||||
breakpoint (ec);
|
||||
}
|
||||
return condition;
|
||||
}
|
||||
|
||||
@@ -133,3 +141,15 @@ bool TestPeerBasics::aborted (boost::system::error_code const& ec) noexcept
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void TestPeerBasics::breakpoint (boost::system::error_code const& ec)
|
||||
{
|
||||
// Set a breakpoint here to catch a failure
|
||||
std::string const& message = ec.message ();
|
||||
char const* const c_str = message.c_str ();
|
||||
|
||||
breakpoint (c_str);
|
||||
}
|
||||
|
||||
void TestPeerBasics::breakpoint (char const* const)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -95,6 +95,12 @@ public:
|
||||
|
||||
/** Returns true if the error condition indicates an aborted I/O. */
|
||||
static bool aborted (boost::system::error_code const& ec) noexcept;
|
||||
|
||||
/** Provides a place to set a breakpoint to catch a failed condition. */
|
||||
static void breakpoint (boost::system::error_code const& ec);
|
||||
|
||||
/** Forces the variable to exist in the debugger. */
|
||||
static void breakpoint (char const* const message);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user