diff --git a/Subtrees/beast/Builds/VisualStudio2012/Beast.props b/Subtrees/beast/Builds/VisualStudio2012/Beast.props index f6d2951a8e..2428672bea 100644 --- a/Subtrees/beast/Builds/VisualStudio2012/Beast.props +++ b/Subtrees/beast/Builds/VisualStudio2012/Beast.props @@ -9,6 +9,7 @@ _CRTDBG_MAP_ALLOC;_WIN32_WINNT=0x0600;%(PreprocessorDefinitions) true false + %(AdditionalIncludeDirectories) diff --git a/Subtrees/beast/Builds/VisualStudio2012/BeastConfig.h b/Subtrees/beast/Builds/VisualStudio2012/BeastConfig.h index db09b0f7be..b21ea0df16 100644 --- a/Subtrees/beast/Builds/VisualStudio2012/BeastConfig.h +++ b/Subtrees/beast/Builds/VisualStudio2012/BeastConfig.h @@ -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 diff --git a/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj b/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj index 0df23244e3..fd50844f96 100644 --- a/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj +++ b/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj @@ -69,7 +69,11 @@ - + + + + + @@ -78,13 +82,13 @@ - + + - @@ -303,7 +307,7 @@ - + true true true @@ -340,6 +344,12 @@ true true + + true + true + true + true + true true @@ -361,6 +371,8 @@ true true + true + true true diff --git a/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj.filters b/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj.filters index 440982c122..3218fb0428 100644 --- a/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj.filters +++ b/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj.filters @@ -155,12 +155,12 @@ {ccdc0c8e-f77a-486e-ba2f-29c10ec97f18} - - {dfa79046-33ef-4653-a6f9-83954b76a10f} - {4856837a-fa72-4252-8e8f-a112c1dbb3d2} + + {beb81776-4aad-401d-8826-81478dbbf30b} + @@ -824,9 +824,6 @@ beast_core\memory - - beast_asio\streams - beast_asio\handshake @@ -839,24 +836,39 @@ beast_asio\handshake - - beast_asio\handshake - beast_asio\handshake - - beast_asio\basics - beast_core\memory - - beast_asio\sockets - beast_asio\system + + beast_asio\handshake + + + beast_asio\handshake + + + beast_asio\async + + + beast_asio\async + + + beast_asio\async + + + beast_asio\async + + + beast_asio\async + + + beast_asio\handshake + @@ -1318,8 +1330,11 @@ beast_asio\handshake - - beast_asio\basics + + beast_asio\system + + + beast_asio\async diff --git a/Subtrees/beast/modules/beast_asio/async/beast_ComposedAsyncOperation.h b/Subtrees/beast/modules/beast_asio/async/beast_ComposedAsyncOperation.h new file mode 100644 index 0000000000..ca109ebd96 --- /dev/null +++ b/Subtrees/beast/modules/beast_asio/async/beast_ComposedAsyncOperation.h @@ -0,0 +1,100 @@ +//------------------------------------------------------------------------------ +/* + This file is part of Beast: https://github.com/vinniefalco/Beast + Copyright 2013, Vinnie Falco + + 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 ::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 diff --git a/Subtrees/beast/modules/beast_asio/async/beast_SharedHandler.cpp b/Subtrees/beast/modules/beast_asio/async/beast_SharedHandler.cpp new file mode 100644 index 0000000000..cf4cea5ca7 --- /dev/null +++ b/Subtrees/beast/modules/beast_asio/async/beast_SharedHandler.cpp @@ -0,0 +1,47 @@ +//------------------------------------------------------------------------------ +/* + This file is part of Beast: https://github.com/vinniefalco/Beast + Copyright 2013, Vinnie Falco + + 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); +} diff --git a/Subtrees/beast/modules/beast_asio/async/beast_SharedHandler.h b/Subtrees/beast/modules/beast_asio/async/beast_SharedHandler.h new file mode 100644 index 0000000000..6e2d4f2f8b --- /dev/null +++ b/Subtrees/beast/modules/beast_asio/async/beast_SharedHandler.h @@ -0,0 +1,134 @@ +//------------------------------------------------------------------------------ +/* + This file is part of Beast: https://github.com/vinniefalco/Beast + Copyright 2013, Vinnie Falco + + 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 +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 invoked_type; + + SharedHandler () noexcept { } + +public: + // For asio::async_result<> + typedef void result_type; + + typedef SharedObjectPtr 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 + void dispatch (Dispatcher& dispatcher, BOOST_ASIO_MOVE_ARG(Function) function) + { + dispatcher.dispatch (boost::bind ( + &SharedHandler::invoke , this, + BOOST_ASIO_MOVE_CAST(Function)(function))); + } + */ + + template + 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 + 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 ; +}; + +//-------------------------------------------------------------------------- + +// For SharedObjectPtr +template <> +struct ContainerDeletePolicy +{ + // SharedObjectPtr will use this when + // the reference count drops to zero. + // + inline static void destroy (SharedHandler* handler) + { + handler->destroy (); + } +}; + +//-------------------------------------------------------------------------- +// +// Context execution guarantees +// + +template +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 diff --git a/Subtrees/beast/modules/beast_asio/async/beast_SharedHandlerAllocator.h b/Subtrees/beast/modules/beast_asio/async/beast_SharedHandlerAllocator.h new file mode 100644 index 0000000000..404d12a9b2 --- /dev/null +++ b/Subtrees/beast/modules/beast_asio/async/beast_SharedHandlerAllocator.h @@ -0,0 +1,129 @@ +//------------------------------------------------------------------------------ +/* + This file is part of Beast: https://github.com/vinniefalco/Beast + Copyright 2013, Vinnie Falco + + 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 +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 + SharedHandlerAllocator (SharedHandlerAllocator const& other) + : m_ptr (other.m_ptr) + { + } + + template + struct rebind + { + typedef SharedHandlerAllocator 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 (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 ::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 + friend struct SharedHandlerAllocator; + friend class SharedHandler; + + SharedHandlerPtr m_ptr; +}; + +//------------------------------------------------------------------------------ + +template +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 (this)); +#else + invoked_type invoked (BOOST_ASIO_MOVE_CAST(Function)(f)); +#endif + invoke (invoked); +} + +#endif diff --git a/Subtrees/beast/modules/beast_asio/async/beast_SharedHandlerPtr.h b/Subtrees/beast/modules/beast_asio/async/beast_SharedHandlerPtr.h new file mode 100644 index 0000000000..b6a6ef4fe0 --- /dev/null +++ b/Subtrees/beast/modules/beast_asio/async/beast_SharedHandlerPtr.h @@ -0,0 +1,307 @@ +//------------------------------------------------------------------------------ +/* + This file is part of Beast: https://github.com/vinniefalco/Beast + Copyright 2013, Vinnie Falco + + 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 + 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 + 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 +inline void asio_handler_invoke (BOOST_ASIO_MOVE_ARG(Function) f, SharedHandlerPtr* ptr) +{ + boost_asio_handler_invoke_helpers:: + invoke + (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 (size, *ptr->get ()); +} + +inline void asio_handler_deallocate (void* p, std::size_t size, SharedHandlerPtr* ptr) +{ + boost_asio_handler_alloc_helpers:: + deallocate (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 (*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 +SharedHandlerPtr newCompletionHandler ( + BOOST_ASIO_MOVE_ARG(CompletionHandler) handler) +{ + return newSharedHandlerContainer ( + BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler)); +} + +// AcceptHandler +// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/AcceptHandler.html +// +template +SharedHandlerPtr newAcceptHandler ( + BOOST_ASIO_MOVE_ARG(AcceptHandler) handler) +{ + return newSharedHandlerContainer ( + BOOST_ASIO_MOVE_CAST(AcceptHandler)(handler)); +} + +// ConnectHandler +// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ConnectHandler.html +// +template +SharedHandlerPtr newConnectHandler ( + BOOST_ASIO_MOVE_ARG(ConnectHandler) handler) +{ + return newSharedHandlerContainer ( + BOOST_ASIO_MOVE_CAST(ConnectHandler)(handler)); +} + +// ShutdownHandler +// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ShutdownHandler.html +// +template +SharedHandlerPtr newShutdownHandler( + BOOST_ASIO_MOVE_ARG(ShutdownHandler) handler) +{ + return newSharedHandlerContainer ( + BOOST_ASIO_MOVE_CAST(ShutdownHandler)(handler)); +} + +// HandshakeHandler +// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/HandshakeHandler.html +// +template +SharedHandlerPtr newHandshakeHandler( + BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler) +{ + return newSharedHandlerContainer ( + BOOST_ASIO_MOVE_CAST(HandshakeHandler)(handler)); +} + +// ReadHandler +// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ReadHandler.html +// +template +SharedHandlerPtr newReadHandler( + BOOST_ASIO_MOVE_ARG(ReadHandler) handler) +{ + return newSharedHandlerContainer ( + BOOST_ASIO_MOVE_CAST(ReadHandler)(handler)); +} + +// WriteHandler +// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/WriteHandler.html +// +template +SharedHandlerPtr newWriteHandler( + BOOST_ASIO_MOVE_ARG(WriteHandler) handler) +{ + return newSharedHandlerContainer ( + BOOST_ASIO_MOVE_CAST(WriteHandler)(handler)); +} + +// BufferedHandshakeHandler +// http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/BufferedHandshakeHandler.html +// +template +SharedHandlerPtr newBufferedHandshakeHandler( + BOOST_ASIO_MOVE_ARG(BufferedHandshakeHandler) handler) +{ + return newSharedHandlerContainer ( + BOOST_ASIO_MOVE_CAST(BufferedHandshakeHandler)(handler)); +} + +#endif diff --git a/Subtrees/beast/modules/beast_asio/async/beast_SharedHandlerType.h b/Subtrees/beast/modules/beast_asio/async/beast_SharedHandlerType.h new file mode 100644 index 0000000000..bb7bca2a0f --- /dev/null +++ b/Subtrees/beast/modules/beast_asio/async/beast_SharedHandlerType.h @@ -0,0 +1,233 @@ +//------------------------------------------------------------------------------ +/* + This file is part of Beast: https://github.com/vinniefalco/Beast + Copyright 2013, Vinnie Falco + + 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 +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, m_handler); + } + + void* allocate (std::size_t size) + { + return boost_asio_handler_alloc_helpers:: + allocate (size, m_handler); + } + + void deallocate (void* p, std::size_t size) + { + boost_asio_handler_alloc_helpers:: + deallocate (p, size, m_handler); + } + + bool is_continuation () + { +#if BEAST_ASIO_HAS_CONTINUATION_HOOKS + return boost_asio_handler_cont_helpers:: + is_continuation (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 (this)); + shared->~SharedHandler (); + boost_asio_handler_alloc_helpers:: + deallocate (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 +class PostSharedHandlerType : public SharedHandlerType +{ +public: + PostSharedHandlerType (std::size_t size, + BOOST_ASIO_MOVE_ARG(Handler) handler) + : SharedHandlerType (size, + BOOST_ASIO_MOVE_CAST(Handler)(handler)) + { + } + +protected: + void operator() () + { + this->m_handler (); + } +}; + +//-------------------------------------------------------------------------- +// +// A SharedHandlerType for this signature: +// void(error_code) +// +template +class ErrorSharedHandlerType : public SharedHandlerType +{ +public: + ErrorSharedHandlerType (std::size_t size, + BOOST_ASIO_MOVE_ARG(Handler) handler) + : SharedHandlerType (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 +class TransferSharedHandlerType : public SharedHandlerType +{ +public: + TransferSharedHandlerType (std::size_t size, + BOOST_ASIO_MOVE_ARG(Handler) handler) + : SharedHandlerType (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 +{ +}; + +template <> +class ErrorSharedHandlerType +{ +}; +template <> +class TransferSharedHandlerType +{ +}; +#endif + + +//-------------------------------------------------------------------------- + +/** Construct a wrapped handler using the context's allocation hooks. +*/ +template