diff --git a/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj b/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj index 18f2243de8..b53c3918ec 100644 --- a/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj +++ b/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj @@ -164,6 +164,7 @@ + diff --git a/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj.filters b/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj.filters index 2e5383b85e..2692e37621 100644 --- a/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj.filters +++ b/Subtrees/beast/Builds/VisualStudio2012/beast.vcxproj.filters @@ -629,6 +629,9 @@ beast_core\diagnostic + + beast_core\memory + diff --git a/Subtrees/beast/TODO.txt b/Subtrees/beast/TODO.txt index 1402c9af32..ae7183418e 100644 --- a/Subtrees/beast/TODO.txt +++ b/Subtrees/beast/TODO.txt @@ -2,6 +2,8 @@ BEAST TODO -------------------------------------------------------------------------------- +- Macro for acquiring a ScopedLock that records file and line. + - Rename HeapBlock routines to not conflict with _CRTDBG_MAP_ALLOC macros - Design a WeakPtr / SharedPtr / SharedObject intrusive system diff --git a/Subtrees/beast/modules/beast_core/beast_core.h b/Subtrees/beast/modules/beast_core/beast_core.h index cbc27191a0..c19c149f27 100644 --- a/Subtrees/beast/modules/beast_core/beast_core.h +++ b/Subtrees/beast/modules/beast_core/beast_core.h @@ -276,6 +276,7 @@ namespace beast #include "memory/beast_WeakReference.h" #include "memory/beast_MemoryAlignment.h" #include "memory/beast_CacheLine.h" +#include "memory/beast_RecycledObjectPool.h" #include "misc/beast_Result.h" #include "misc/beast_Uuid.h" #include "misc/beast_WindowsRegistry.h" diff --git a/Subtrees/beast/modules/beast_core/memory/beast_RecycledObjectPool.h b/Subtrees/beast/modules/beast_core/memory/beast_RecycledObjectPool.h new file mode 100644 index 0000000000..6981427bf5 --- /dev/null +++ b/Subtrees/beast/modules/beast_core/memory/beast_RecycledObjectPool.h @@ -0,0 +1,126 @@ +//------------------------------------------------------------------------------ +/* + 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_RECYCLEDOBJECTPOOL_H_INCLUDED +#define BEAST_RECYCLEDOBJECTPOOL_H_INCLUDED + +/** A pool of objects which may be recycled. + + This is a thread safe pool of objects that get re-used. It is + primarily designed to eliminate the need for many memory allocations + and frees when temporary buffers are needed for operations. + + To use it, first declare a structure containing the information + that you want to recycle. Then when you want to use a recycled object + put a ScopedItem on your stack: + + @code + + struct StdString + { + std::string data; + }; + + RecycledObjectPool pool; + + void foo () + { + RecycledObjectPool ::ScopedItem item; + + item.getObject ().data = "text"; + } + + @endcode +*/ +template +class RecycledObjectPool +{ +public: + struct Item : Object, LockFreeStack ::Node, LeakChecked + { + }; + + class ScopedItem + { + public: + explicit ScopedItem (RecycledObjectPool & pool) + : m_pool (pool) + , m_item (pool.get ()) + { + } + + ~ScopedItem () + { + m_pool.release (m_item); + } + + Object& getObject () noexcept + { + return *m_item; + } + + private: + RecycledObjectPool & m_pool; + Item* const m_item; + }; + +public: + RecycledObjectPool () noexcept + { + } + + ~RecycledObjectPool () + { + for (;;) + { + Item* const item = m_stack.pop_front (); + + if (item != nullptr) + delete item; + else + break; + } + } + +private: + Item* get () + { + Item* item = m_stack.pop_front (); + + if (item == nullptr) + { + item = new Item; + + if (item == nullptr) + Throw (std::bad_alloc ()); + } + + return item; + } + + void release (Item* item) noexcept + { + m_stack.push_front (item); + } + +private: + LockFreeStack m_stack; +}; + +#endif