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