From c8cedfc06effc0cd77e398b39c9d5dff7cb6e346 Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Fri, 6 Sep 2013 13:11:05 -0700 Subject: [PATCH] Add SharedFunction to replace boost::function --- .../Builds/VisualStudio2012/beast.vcxproj | 1 + .../VisualStudio2012/beast.vcxproj.filters | 3 + .../modules/beast_asio/async/SharedHandler.h | 28 +++--- .../beast_asio/async/SharedHandlerAllocator.h | 6 +- .../beast_asio/async/SharedHandlerPtr.h | 20 ++++ .../beast_asio/async/SharedHandlerType.h | 11 --- .../beast/modules/beast_asio/beast_asio.h | 7 -- .../beast/modules/beast_core/beast_core.h | 1 + .../beast_core/functional/SharedFunction.h | 97 +++++++++++++++++++ 9 files changed, 140 insertions(+), 34 deletions(-) create mode 100644 Subtrees/beast/modules/beast_core/functional/SharedFunction.h diff --git a/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj b/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj index 456c4ac56..1001acc0e 100644 --- a/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj +++ b/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj @@ -163,6 +163,7 @@ + diff --git a/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj.filters b/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj.filters index 786c00da6..7c2f61e5d 100644 --- a/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj.filters +++ b/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj.filters @@ -992,6 +992,9 @@ beast_asio\protocol + + beast_core\functional + diff --git a/Subtrees/beast/modules/beast_asio/async/SharedHandler.h b/Subtrees/beast/modules/beast_asio/async/SharedHandler.h index 756b036d5..cd6543c9f 100644 --- a/Subtrees/beast/modules/beast_asio/async/SharedHandler.h +++ b/Subtrees/beast/modules/beast_asio/async/SharedHandler.h @@ -45,7 +45,11 @@ class SharedHandler : public SharedObject { protected: typedef boost::system::error_code error_code; +#if 0 typedef boost::function invoked_type; +#else + typedef SharedFunction > invoked_type; +#endif SharedHandler () noexcept { } @@ -59,19 +63,19 @@ public: 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); + void invoke (BOOST_ASIO_MOVE_ARG(Function) f) +#if 0 + ; +#else + { + // The allocator will hold a reference to the SharedHandler + // so that we can safely destroy the function object. + invoked_type invoked (f, + SharedHandlerAllocator (this)); + invoke (invoked); + } +#endif virtual void invoke (invoked_type& invoked) = 0; virtual void* allocate (std::size_t size) = 0; diff --git a/Subtrees/beast/modules/beast_asio/async/SharedHandlerAllocator.h b/Subtrees/beast/modules/beast_asio/async/SharedHandlerAllocator.h index 1a262a8c3..86d894e95 100644 --- a/Subtrees/beast/modules/beast_asio/async/SharedHandlerAllocator.h +++ b/Subtrees/beast/modules/beast_asio/async/SharedHandlerAllocator.h @@ -112,18 +112,16 @@ private: //------------------------------------------------------------------------------ +#if 0 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 #endif diff --git a/Subtrees/beast/modules/beast_asio/async/SharedHandlerPtr.h b/Subtrees/beast/modules/beast_asio/async/SharedHandlerPtr.h index 5672fd976..d864ca8cc 100644 --- a/Subtrees/beast/modules/beast_asio/async/SharedHandlerPtr.h +++ b/Subtrees/beast/modules/beast_asio/async/SharedHandlerPtr.h @@ -215,6 +215,26 @@ inline bool asio_handler_is_continuation (SharedHandlerPtr* ptr) // //-------------------------------------------------------------------------- +// void(error_code) +template +SharedHandlerPtr newErrorHandler ( + BOOST_ASIO_MOVE_ARG(Handler) handler) +{ + return newSharedHandlerContainer ( + BOOST_ASIO_MOVE_CAST(Handler)(handler)); +} + +// void(error_code, size_t) +template +SharedHandlerPtr newTransferHandler ( + BOOST_ASIO_MOVE_ARG(Handler) handler) +{ + return newSharedHandlerContainer ( + BOOST_ASIO_MOVE_CAST(Handler)(handler)); +} + +//-------------------------------------------------------------------------- + // CompletionHandler // // http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/CompletionHandler.html diff --git a/Subtrees/beast/modules/beast_asio/async/SharedHandlerType.h b/Subtrees/beast/modules/beast_asio/async/SharedHandlerType.h index 5e993ca14..40de9f326 100644 --- a/Subtrees/beast/modules/beast_asio/async/SharedHandlerType.h +++ b/Subtrees/beast/modules/beast_asio/async/SharedHandlerType.h @@ -87,19 +87,14 @@ protected: // 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) @@ -111,7 +106,6 @@ protected: { return pure_virtual_called (__FILE__, __LINE__); } -#endif protected: std::size_t const m_size; @@ -219,15 +213,10 @@ Container * newSharedHandlerContainer (BOOST_ASIO_MOVE_ARG(Handler) han { typedef Container 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 (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 diff --git a/Subtrees/beast/modules/beast_asio/beast_asio.h b/Subtrees/beast/modules/beast_asio/beast_asio.h index 28c016078..5ce86e8cb 100644 --- a/Subtrees/beast/modules/beast_asio/beast_asio.h +++ b/Subtrees/beast/modules/beast_asio/beast_asio.h @@ -53,13 +53,6 @@ # 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 { diff --git a/Subtrees/beast/modules/beast_core/beast_core.h b/Subtrees/beast/modules/beast_core/beast_core.h index 63401e3db..a6bc27dea 100644 --- a/Subtrees/beast/modules/beast_core/beast_core.h +++ b/Subtrees/beast/modules/beast_core/beast_core.h @@ -408,6 +408,7 @@ extern BEAST_API void BEAST_CALLTYPE logAssertion (char const* file, int line) n #include "diagnostic/MeasureFunctionCallTime.h" #include "functional/beast_Function.h" +#include "functional/SharedFunction.h" #include "thread/beast_DeadlineTimer.h" diff --git a/Subtrees/beast/modules/beast_core/functional/SharedFunction.h b/Subtrees/beast/modules/beast_core/functional/SharedFunction.h new file mode 100644 index 000000000..fcb31e5d9 --- /dev/null +++ b/Subtrees/beast/modules/beast_core/functional/SharedFunction.h @@ -0,0 +1,97 @@ +//------------------------------------------------------------------------------ +/* + 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_CORE_SHAREDFUNCTION_H_INCLUDED +#define BEAST_CORE_SHAREDFUNCTION_H_INCLUDED + +/** A reference counted, abstract function object. +*/ +template > +class SharedFunction; + +// nullary function +// +template +class SharedFunction +{ +public: + template + SharedFunction (F f, A a = A ()) + : m_ptr (::new ( + typename CallType ::Allocator (a) + .allocate (sizeof (CallType ))) + CallType (BEAST_MOVE_CAST(F)(f), a)) + { + } + + SharedFunction (SharedFunction const& other) + : m_ptr (other.m_ptr) + { + } + + SharedFunction (SharedFunction const& other, A) + : m_ptr (other.m_ptr) + { + } + + SharedFunction& operator= (SharedFunction const& other) + { + m_ptr = other.m_ptr; + return *this; + } + + R operator() () + { + return (*m_ptr)(); + } + +private: + class Call : public SharedObject + { + public: + virtual R operator() () = 0; + }; + + template + class CallType : public Call + { + public: + typedef typename A:: template rebind >::other Allocator; + + CallType (BEAST_MOVE_ARG(F) f, A const& a) + : m_f (BEAST_MOVE_CAST(F)(f)) + , m_a (a) + { + } + + R operator() () + { + return m_f (); + } + + private: + F m_f; + Allocator m_a; + }; + + SharedPtr m_ptr; +}; + + +#endif