diff --git a/Builds/VisualStudio2012/beast.vcxproj b/Builds/VisualStudio2012/beast.vcxproj index b6bb096537..31214704cd 100644 --- a/Builds/VisualStudio2012/beast.vcxproj +++ b/Builds/VisualStudio2012/beast.vcxproj @@ -99,6 +99,7 @@ + @@ -109,6 +110,7 @@ + diff --git a/Builds/VisualStudio2012/beast.vcxproj.filters b/Builds/VisualStudio2012/beast.vcxproj.filters index d6e3aa81e5..bfbc9c0938 100644 --- a/Builds/VisualStudio2012/beast.vcxproj.filters +++ b/Builds/VisualStudio2012/beast.vcxproj.filters @@ -1098,6 +1098,12 @@ beast_asio\http + + beast_asio\async + + + beast_asio\basics + diff --git a/modules/beast_asio/async/AsyncObject.h b/modules/beast_asio/async/AsyncObject.h new file mode 100644 index 0000000000..12606ffaf5 --- /dev/null +++ b/modules/beast_asio/async/AsyncObject.h @@ -0,0 +1,72 @@ +//------------------------------------------------------------------------------ +/* + 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_ASIO_ASYNCOBJECT_H_INCLUDED +#define BEAST_ASIO_ASYNCOBJECT_H_INCLUDED + +/** Mix-in to track when all pending I/O is complete. + Derived classes must be callable with this signature: + void asyncHandlersComplete() +*/ +template +class AsyncObject +{ +public: + ~AsyncObject () + { + // Destroying the object with I/O pending? Not a clean exit! + bassert (m_pending.get() == 0); + } + + /** RAII container that maintains the count of pending I/O. + Bind this into the argument list of every handler passed + to an initiating function. + */ + class CompletionCounter + { + public: + explicit CompletionCounter (Derived* owner) + : m_owner (owner) + { + ++m_owner->m_pending; + } + + CompletionCounter (CompletionCounter const& other) + : m_owner (other.m_owner) + { + ++m_owner->m_pending; + } + + ~CompletionCounter () + { + if (--m_owner->m_pending == 0) + m_owner->asyncHandlersComplete (); + } + + private: + CompletionCounter& operator= (CompletionCounter const&); + Derived* m_owner; + }; + +private: + // The number of handlers pending. + Atomic m_pending; +}; + +#endif diff --git a/modules/beast_asio/basics/SharedArg.h b/modules/beast_asio/basics/SharedArg.h new file mode 100644 index 0000000000..95f05c891a --- /dev/null +++ b/modules/beast_asio/basics/SharedArg.h @@ -0,0 +1,161 @@ +//------------------------------------------------------------------------------ +/* + 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_ASIO_SHAREDARG_H_INCLUDED +#define BEAST_ASIO_SHAREDARG_H_INCLUDED + +/** A container that turns T into a SharedObject. + We use this to manage the lifetime of objects passed to handlers. +*/ +template +struct SharedArg +{ +private: + struct Arg : SharedObject + { + Arg () + { + } + + explicit Arg (BEAST_MOVE_ARG(T) t) + : value (BEAST_MOVE_CAST(T)(t)) + { + } + + template + explicit Arg (P1 p1) + : value (p1) + { + } + + template + Arg (P1 p1, P2 p2) + : value (p1, p2) + { + } + + template + Arg (P1 p1, P2 p2, P3 p3) + : value (p1, p2, p3) + { + } + + template + Arg (P1 p1, P2 p2, P3 p3, P4 p4) + : value (p1, p2, p3, p4) + { + } + + ~Arg () + { + } + + T value; + }; + +public: + SharedArg () + { + } + + explicit SharedArg (BEAST_MOVE_ARG(T) t) + : m_arg (new Arg (BEAST_MOVE_CAST(T)(t))) + { + } + + template + explicit SharedArg (P1 p1) + : m_arg (new Arg (p1)) + { + } + + template + SharedArg (P1 p1, P2 p2) + : m_arg (new Arg (p1, p2)) + { + } + + template + SharedArg (P1 p1, P2 p2, P3 p3) + : m_arg (new Arg (p1, p2, p3)) + { + } + + template + SharedArg (P1 p1, P2 p2, P3 p3, P4 p4) + : m_arg (new Arg (p1, p2, p3, p4)) + { + } + + SharedArg (SharedArg const& other) + : m_arg (other.m_arg) + { + } + + SharedArg& operator= (SharedArg const& other) + { + m_arg = other.m_arg; + return *this; + } + + T& get () + { + return m_arg->value; + } + + T const& get () const + { + return m_arg->value; + } + + T& operator* () + { + return get(); + } + + T const& operator* () const + { + return get(); + } + + T* operator-> () + { + return &get(); + } + + T const* operator-> () const + { + return &get(); + } + + operator T& () + { + return m_arg->value; + } + + operator T const& () const + { + return m_arg->value; + } + +private: + SharedPtr m_arg; +}; + +#endif diff --git a/modules/beast_asio/beast_asio.h b/modules/beast_asio/beast_asio.h index 5d60c758d4..637f3e7068 100644 --- a/modules/beast_asio/beast_asio.h +++ b/modules/beast_asio/beast_asio.h @@ -65,6 +65,7 @@ namespace beast # include "async/SharedHandlerPtr.h" # include "async/ComposedAsyncOperation.h" #include "async/SharedHandlerAllocator.h" +#include "async/AsyncObject.h" # include "basics/BufferType.h" # include "basics/BuffersType.h" @@ -72,6 +73,7 @@ namespace beast #include "basics/FixedInputBuffer.h" #include "basics/PeerRole.h" #include "basics/SSLContext.h" +#include "basics/SharedArg.h" # include "sockets/SocketBase.h" # include "sockets/Socket.h" diff --git a/modules/beast_core/diagnostic/LeakChecked.cpp b/modules/beast_core/diagnostic/LeakChecked.cpp index 075069e644..7f7d51b64a 100644 --- a/modules/beast_core/diagnostic/LeakChecked.cpp +++ b/modules/beast_core/diagnostic/LeakChecked.cpp @@ -20,10 +20,10 @@ namespace detail { -class LeakCheckedBase::CounterBase::Singleton +class LeakCheckedBase::LeakCounterBase::Singleton { public: - void push_back (CounterBase* counter) + void push_back (LeakCounterBase* counter) { m_list.push_front (counter); } @@ -32,7 +32,7 @@ public: { for (;;) { - CounterBase* const counter = m_list.pop_front (); + LeakCounterBase* const counter = m_list.pop_front (); if (!counter) break; @@ -51,17 +51,17 @@ public: private: friend class LeakCheckedBase; - LockFreeStack m_list; + LockFreeStack m_list; }; //------------------------------------------------------------------------------ -LeakCheckedBase::CounterBase::CounterBase () +LeakCheckedBase::LeakCounterBase::LeakCounterBase () { Singleton::getInstance ().push_back (this); } -void LeakCheckedBase::CounterBase::checkForLeaks () +void LeakCheckedBase::LeakCounterBase::checkForLeaks () { // If there's a runtime error from this line, it means there's // an order of destruction problem between different translation units! @@ -120,7 +120,7 @@ void LeakCheckedBase::reportDanglingPointer (char const*) void LeakCheckedBase::checkForLeaks () { - CounterBase::Singleton::getInstance ().checkForLeaks (); + LeakCounterBase::Singleton::getInstance ().checkForLeaks (); } } diff --git a/modules/beast_core/diagnostic/LeakChecked.h b/modules/beast_core/diagnostic/LeakChecked.h index 254a7208fe..6e63f9fe55 100644 --- a/modules/beast_core/diagnostic/LeakChecked.h +++ b/modules/beast_core/diagnostic/LeakChecked.h @@ -29,12 +29,12 @@ public: static void checkForLeaks (); protected: - class CounterBase : public LockFreeStack ::Node + class LeakCounterBase : public LockFreeStack ::Node { public: - CounterBase (); + LeakCounterBase (); - virtual ~CounterBase () + virtual ~LeakCounterBase () { } @@ -95,10 +95,10 @@ protected: private: // Singleton that maintains the count of this object // - class Counter : public CounterBase + class LeakCounter : public LeakCounterBase { public: - Counter () noexcept + LeakCounter () noexcept { } @@ -123,9 +123,9 @@ private: // Retrieve the singleton for this object // - static Counter& getCounter () noexcept + static LeakCounter& getCounter () noexcept { - return StaticObject ::get(); + return StaticObject ::get(); } };