From 2c3ead339eb118d56bffc259eae1258d26967293 Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Fri, 4 Oct 2013 19:02:33 -0700 Subject: [PATCH] Add ServiceQueue::wrap --- Builds/VisualStudio2012/beast.vcxproj | 2 + Builds/VisualStudio2012/beast.vcxproj.filters | 12 +- beast/threads/ServiceQueue.h | 11 + beast/threads/detail/BindHandler.h | 276 ++++++++++++++++++ beast/threads/detail/DispatchedHandler.h | 173 +++++++++++ 5 files changed, 471 insertions(+), 3 deletions(-) create mode 100644 beast/threads/detail/BindHandler.h create mode 100644 beast/threads/detail/DispatchedHandler.h diff --git a/Builds/VisualStudio2012/beast.vcxproj b/Builds/VisualStudio2012/beast.vcxproj index 19fbebb492..59ea617207 100644 --- a/Builds/VisualStudio2012/beast.vcxproj +++ b/Builds/VisualStudio2012/beast.vcxproj @@ -155,6 +155,8 @@ + + diff --git a/Builds/VisualStudio2012/beast.vcxproj.filters b/Builds/VisualStudio2012/beast.vcxproj.filters index 5a0913d2e3..8775b85938 100644 --- a/Builds/VisualStudio2012/beast.vcxproj.filters +++ b/Builds/VisualStudio2012/beast.vcxproj.filters @@ -282,9 +282,6 @@ {7243e5e5-ad7e-4d81-8444-d545919e850c} - - {549430fc-36f6-450e-9d8d-38f4b9e72fb5} - {4e9c54da-1581-41d7-ac75-48140e4a13d4} @@ -294,6 +291,9 @@ {386a8cd8-6be3-4cac-9bca-7a01fdb5327a} + + {b116764e-1ad5-4854-a549-73c5beb5ae37} + @@ -1230,6 +1230,12 @@ beast\threads + + beast\threads\detail + + + beast\threads\detail + diff --git a/beast/threads/ServiceQueue.h b/beast/threads/ServiceQueue.h index 2199615e7b..8d9c199a55 100644 --- a/beast/threads/ServiceQueue.h +++ b/beast/threads/ServiceQueue.h @@ -27,6 +27,8 @@ #include "ThreadLocalValue.h" #include "WaitableEvent.h" +#include "detail/DispatchedHandler.h" + namespace beast { namespace detail { @@ -518,6 +520,15 @@ public: ItemType (BEAST_MOVE_CAST(Handler)(handler))); } + /** Return a new handler that dispatches the wrapped handler on the queue. */ + template + detail::DispatchedHandler wrap ( + BEAST_MOVE_ARG(Handler) handler) + { + return detail::DispatchedHandler ( + *this, BEAST_MOVE_CAST(Handler)(handler)); + } + /** Run the event loop to execute ready handlers. This runs handlers that are ready to run, without blocking, until there are no more handlers ready or the service queue has been stopped. diff --git a/beast/threads/detail/BindHandler.h b/beast/threads/detail/BindHandler.h new file mode 100644 index 0000000000..32199b73fd --- /dev/null +++ b/beast/threads/detail/BindHandler.h @@ -0,0 +1,276 @@ +//------------------------------------------------------------------------------ +/* + 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_THREADS_BINDHANDLER_H_INCLUDED +#define BEAST_THREADS_BINDHANDLER_H_INCLUDED + +namespace beast { +namespace detail { + +/** Overloaded function that re-binds arguments to a handler. */ +/** @{ */ +template +class BindHandler1 +{ +private: + Handler handler; + P1 p1; + +public: + BindHandler1 (Handler const& handler_, P1 const& p1_) + : handler (handler_) + , p1 (p1_) + { } + + BindHandler1 (Handler& handler_, P1 const& p1_) + : handler (BEAST_MOVE_CAST(Handler)(handler_)) + , p1 (p1_) + { } + + void operator()() + { + handler ( + static_cast (p1) + ); + } + + void operator()() const + { + handler (p1); + } +}; + +template +BindHandler1 bindHandler (Handler handler, P1 const& p1) +{ + return BindHandler1 (handler, p1); +} + +//------------------------------------------------------------------------------ + +template +class BindHandler2 +{ +private: + Handler handler; + P1 p1; P2 p2; + +public: + BindHandler2 (Handler const& handler_, + P1 const& p1_, P2 const& p2_) + : handler (handler_) + , p1 (p1_), p2 (p2_) + { } + + BindHandler2 (Handler& handler_, + P1 const& p1_, P2 const& p2_) + : handler (BEAST_MOVE_CAST(Handler)(handler_)) + , p1 (p1_), p2 (p2_) + { } + + void operator()() + { + handler ( + static_cast (p1), static_cast (p2)); + } + + void operator()() const + { handler (p1, p2); } +}; + +template +BindHandler2 bindHandler (Handler handler, + P1 const& p1, P2 const& p2) +{ + return BindHandler2 ( + handler, p1, p2); +} + +//------------------------------------------------------------------------------ + +template +class BindHandler3 +{ +private: + Handler handler; + P1 p1; P2 p2; P3 p3; + +public: + BindHandler3 (Handler const& handler_, + P1 const& p1_, P2 const& p2_, P3 const& p3_) + : handler (handler_) + , p1 (p1_), p2 (p2_), p3 (p3_) + { } + + BindHandler3 (Handler& handler_, + P1 const& p1_, P2 const& p2_, P3 const& p3_) + : handler (BEAST_MOVE_CAST(Handler)(handler_)) + , p1 (p1_), p2 (p2_), p3 (p3_) + { } + + void operator()() + { + handler ( + static_cast (p1), static_cast (p2), static_cast (p3)); + } + + void operator()() const + { handler (p1, p2, p3); } +}; + +template +BindHandler3 bindHandler (Handler handler, + P1 const& p1, P2 const& p2, P3 const& p3) +{ + return BindHandler3 ( + handler, p1, p2, p3); +} + +//------------------------------------------------------------------------------ + +template +class BindHandler4 +{ +private: + Handler handler; + P1 p1; P2 p2; P3 p3; P4 p4; + +public: + BindHandler4 (Handler const& handler_, + P1 const& p1_, P2 const& p2_, P3 const& p3_, P4 const& p4_) + : handler (handler_) + , p1 (p1_), p2 (p2_), p3 (p3_), p4 (p4_) + { } + + BindHandler4 (Handler& handler_, + P1 const& p1_, P2 const& p2_, P3 const& p3_, P4 const& p4_) + : handler (BEAST_MOVE_CAST(Handler)(handler_)) + , p1 (p1_), p2 (p2_), p3 (p3_), p4 (p4_) + { } + + void operator()() + { + handler ( + static_cast (p1), static_cast (p2), static_cast (p3), + static_cast (p4) + ); + } + + void operator()() const + { handler (p1, p2, p3, p4); } +}; + +template +BindHandler4 bindHandler (Handler handler, + P1 const& p1, P2 const& p2, P3 const& p3, P4 const& p4) +{ + return BindHandler4 ( + handler, p1, p2, p3, p4); +} + +//------------------------------------------------------------------------------ + +template +class BindHandler5 +{ +private: + Handler handler; + P1 p1; P2 p2; P3 p3; P4 p4; P5 p5; + +public: + BindHandler5 (Handler const& handler_, + P1 const& p1_, P2 const& p2_, P3 const& p3_, P4 const& p4_, P5 const& p5_) + : handler (handler_) + , p1 (p1_), p2 (p2_), p3 (p3_), p4 (p4_), p5 (p5_) + { } + + BindHandler5 (Handler& handler_, + P1 const& p1_, P2 const& p2_, P3 const& p3_, P4 const& p4_, P5 const& p5_) + : handler (BEAST_MOVE_CAST(Handler)(handler_)) + , p1 (p1_), p2 (p2_), p3 (p3_), p4 (p4_), p5 (p5_) + { } + + void operator()() + { + handler ( + static_cast (p1), static_cast (p2), static_cast (p3), + static_cast (p4), static_cast (p5) + ); + } + + void operator()() const + { handler (p1, p2, p3, p4, p5); } +}; + +template +BindHandler5 bindHandler (Handler handler, + P1 const& p1, P2 const& p2, P3 const& p3, P4 const& p4, P5 const& p5) +{ + return BindHandler5 ( + handler, p1, p2, p3, p4, p5); +} + +//------------------------------------------------------------------------------ + +template +class BindHandler6 +{ +private: + Handler handler; + P1 p1; P2 p2; P3 p3; P4 p4; P5 p5; P6 p6; + +public: + BindHandler6 (Handler const& handler_, + P1 const& p1_, P2 const& p2_, P3 const& p3_, P4 const& p4_, P5 const& p5_, P6 const& p6_) + : handler (handler_) + , p1 (p1_), p2 (p2_), p3 (p3_), p4 (p4_), p5 (p5_), p6 (p6_) + { } + + BindHandler6 (Handler& handler_, + P1 const& p1_, P2 const& p2_, P3 const& p3_, P4 const& p4_, P5 const& p5_, P6 const& p6_) + : handler (BEAST_MOVE_CAST(Handler)(handler_)) + , p1 (p1_), p2 (p2_), p3 (p3_), p4 (p4_), p5 (p5_), p6 (p6_) + { } + + void operator()() + { + handler ( + static_cast (p1), static_cast (p2), static_cast (p3), + static_cast (p4), static_cast (p5), static_cast (p6) + ); + } + + void operator()() const + { handler (p1, p2, p3, p4, p5, p6); } +}; + +template +BindHandler6 bindHandler (Handler handler, + P1 const& p1, P2 const& p2, P3 const& p3, P4 const& p4, P5 const& p5, P6 const& p6) +{ + return BindHandler6 ( + handler, p1, p2, p3, p4, p5, p6); +} + +/** @} */ + +} +} + +#endif diff --git a/beast/threads/detail/DispatchedHandler.h b/beast/threads/detail/DispatchedHandler.h new file mode 100644 index 0000000000..8cd1897e49 --- /dev/null +++ b/beast/threads/detail/DispatchedHandler.h @@ -0,0 +1,173 @@ +//------------------------------------------------------------------------------ +/* + 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_THREADS_DISPATCHEDHANDLER_H_INCLUDED +#define BEAST_THREADS_DISPATCHEDHANDLER_H_INCLUDED + +#include "BindHandler.h" + +namespace beast { +namespace detail { + +/** A wrapper that packages function call arguments into a dispatch. */ +template +class DispatchedHandler +{ +private: + Dispatcher m_dispatcher; + Handler m_handler; + +public: + typedef void result_type; + + DispatchedHandler (Dispatcher dispatcher, Handler& handler) + : m_dispatcher (dispatcher) + , m_handler (BEAST_MOVE_CAST(Handler)(handler)) + { + } + +#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS + DispatchedHandler (DispatchedHandler const& other) + : m_dispatcher (other.m_dispatcher) + , m_handler (other.m_handler) + { + } + + DispatchedHandler (DispatchedHandler&& other) + : m_dispatcher (other.m_dispatcher) + , m_handler (BEAST_MOVE_CAST(Handler)(other.m_handler)) + { + } +#endif + + void operator()() + { + m_dispatcher.dispatch (m_handler); + } + + void operator()() const + { + m_dispatcher.dispatch (m_handler); + } + + template + void operator() (P1 const& p1) + { + m_dispatcher.dispatch ( + detail::bindHandler (m_handler, + p1)); + } + + template + void operator() (P1 const& p1) const + { + m_dispatcher.dispatch ( + detail::bindHandler (m_handler, + p1)); + } + + template + void operator() (P1 const& p1, P2 const& p2) + { + m_dispatcher.dispatch ( + detail::bindHandler (m_handler, + p1, p2)); + } + + template + void operator() (P1 const& p1, P2 const& p2) const + { + m_dispatcher.dispatch ( + detail::bindHandler (m_handler, + p1, p2)); + } + + template + void operator() (P1 const& p1, P2 const& p2, P3 const& p3) + { + m_dispatcher.dispatch ( + detail::bindHandler (m_handler, + p1, p2, p3)); + } + + template + void operator() (P1 const& p1, P2 const& p2, P3 const& p3) const + { + m_dispatcher.dispatch ( + detail::bindHandler (m_handler, + p1, p2, p3)); + } + + template + void operator() (P1 const& p1, P2 const& p2, P3 const& p3, P4 const& p4) + { + m_dispatcher.dispatch ( + detail::bindHandler (m_handler, + p1, p2, p3, p4)); + } + + template + void operator() (P1 const& p1, P2 const& p2, P3 const& p3, P4 const& p4) const + { + m_dispatcher.dispatch ( + detail::bindHandler (m_handler, + p1, p2, p3, p4)); + } + + template + void operator() (P1 const& p1, P2 const& p2, P3 const& p3, + P4 const& p4, P5 const& p5) + { + m_dispatcher.dispatch ( + detail::bindHandler (m_handler, + p1, p2, p3, p4, p5)); + } + + template + void operator() (P1 const& p1, P2 const& p2, P3 const& p3, + P4 const& p4, P5 const& p5) const + { + m_dispatcher.dispatch ( + detail::bindHandler (m_handler, + p1, p2, p3, p4, p5)); + } + + template + void operator() (P1 const& p1, P2 const& p2, P3 const& p3, + P4 const& p4, P5 const& p5, P6 const& p6) + { + m_dispatcher.dispatch ( + detail::bindHandler (m_handler, + p1, p2, p3, p4, p5, p6)); + } + + template + void operator() (P1 const& p1, P2 const& p2, P3 const& p3, + P4 const& p4, P5 const& p5, P6 const& p6) const + { + m_dispatcher.dispatch ( + detail::bindHandler (m_handler, + p1, p2, p3, p4, p5, p6)); + } +}; + +} +} + +#endif