diff --git a/Builds/QtCreator/rippled.pro b/Builds/QtCreator/rippled.pro index 8c921b6825..40cf9912f4 100644 --- a/Builds/QtCreator/rippled.pro +++ b/Builds/QtCreator/rippled.pro @@ -65,6 +65,7 @@ UI_HEADERS_DIR += ../../src/ripple_basics SOURCES += \ ../../src/ripple/beast/ripple_beast.cpp \ ../../src/ripple/beast/ripple_beastc.c \ + ../../src/ripple/common/ripple_common.cpp \ ../../src/ripple/http/ripple_http.cpp \ ../../src/ripple/json/ripple_json.cpp \ ../../src/ripple/peerfinder/ripple_peerfinder.cpp \ diff --git a/Builds/VisualStudio2012/RippleD.vcxproj b/Builds/VisualStudio2012/RippleD.vcxproj index 2500709e5a..f2097bbc20 100644 --- a/Builds/VisualStudio2012/RippleD.vcxproj +++ b/Builds/VisualStudio2012/RippleD.vcxproj @@ -22,6 +22,13 @@ + + true + true + true + true + + true true @@ -1532,6 +1539,12 @@ true true + + true + true + true + true + true true @@ -2128,6 +2141,7 @@ + @@ -2487,6 +2501,7 @@ + diff --git a/Builds/VisualStudio2012/RippleD.vcxproj.filters b/Builds/VisualStudio2012/RippleD.vcxproj.filters index 2fb26387d3..e5df7b624b 100644 --- a/Builds/VisualStudio2012/RippleD.vcxproj.filters +++ b/Builds/VisualStudio2012/RippleD.vcxproj.filters @@ -289,6 +289,15 @@ {013f0eb9-bf1d-4b11-8c2c-3fd99d4b8ef5} + + {b99052d6-a903-4dfd-9c68-ff767a7d8f63} + + + {70365f6a-d1e6-45f2-a064-0e842b0fdd78} + + + {9b8137bd-737d-4825-98bf-897a0635293a} + @@ -1401,8 +1410,14 @@ [1] Ripple\types\impl - - [1] Ripple\types\impl + + [1] Ripple\common + + + [1] Ripple\common\functional\impl + + + [2] Old Ripple\ripple_core\nodestore\backend @@ -2880,6 +2895,12 @@ [1] Ripple\types\api + + [1] Ripple\common\functional + + + [2] Old Ripple\ripple_core\nodestore\backend + diff --git a/SConstruct b/SConstruct index f31e45b99a..4d22c18696 100644 --- a/SConstruct +++ b/SConstruct @@ -156,6 +156,7 @@ COMPILED_FILES.extend (['src/ripple/beast/ripple_beastc.c']) # New-style Ripple unity sources # COMPILED_FILES.extend([ + 'src/ripple/common/ripple_common.cpp', 'src/ripple/http/ripple_http.cpp', 'src/ripple/json/ripple_json.cpp', 'src/ripple/peerfinder/ripple_peerfinder.cpp', diff --git a/src/ripple/common/functional/counted_bind.h b/src/ripple/common/functional/counted_bind.h new file mode 100644 index 0000000000..9dd6b881d9 --- /dev/null +++ b/src/ripple/common/functional/counted_bind.h @@ -0,0 +1,241 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2012, 2013 Ripple Labs Inc. + + 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 RIPPLE_COUNTED_BIND_H_INCLUDED +#define RIPPLE_COUNTED_BIND_H_INCLUDED + +#include +#include +#include + +namespace ripple { + +namespace detail { + +// Wrapper for managing the handler count +template +class counted_bind_wrapper +{ +public: + template + counted_bind_wrapper (H&& h, Counter& c) + : m_handler (std::forward (h)) + , m_counter (c) + { + ++m_counter; + } + + counted_bind_wrapper (counted_bind_wrapper&& w) + : m_handler (std::move (w.m_handler)) + , m_counter (w.m_counter) + { + ++m_counter; + } + + counted_bind_wrapper (counted_bind_wrapper const& w) + : m_handler (w.m_handler) + , m_counter (w.m_counter) + { + ++m_counter; + } + + ~counted_bind_wrapper () + { + --m_counter; + } + + //counted_bind_wrapper& operator= (counted_bind_wrapper const&) = delete; + +#if 0 + // When variadic template arguments are supported + template + void operator () (Args&& ...args) const + { + m_handler (std::forward (args)...); + } + +#else + void operator() () + { + m_handler (); + } + + void operator() () const + { + m_handler (); + } + + template + void operator() (P1 const& p1) + { + m_handler (p1); + } + + template + void operator() (P1 const& p1) const + { + m_handler (p1); + } + + template + void operator() (P1 const& p1, P2 const& p2) + { + m_handler (p1, p2); + } + + template + void operator() (P1 const& p1, P2 const& p2) const + { + m_handler (p1, p2); + } + + template + void operator() (P1 const& p1, P2 const& p2, P3 const& p3) + { + m_handler (p1, p2, p3); + } + + template + void operator() (P1 const& p1, P2 const& p2, P3 const& p3) const + { + m_handler (p1, p2, p3); + } + + template + void operator() (P1 const& p1, P2 const& p2, P3 const& p3, P4 const& p4) + { + m_handler (p1, p2, p3, p4); + } + + template + void operator() (P1 const& p1, P2 const& p2, P3 const& p3, P4 const& p4) const + { + 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_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_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_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_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, P7 const& p7) + { + m_handler (p1, p2, p3, p4, p5, p6, p7); + } + + template + void operator() (P1 const& p1, P2 const& p2, P3 const& p3, P4 const& p4, + P5 const& p5, P6 const& p6, P7 const& p7) const + { + m_handler (p1, p2, p3, p4, p5, p6, p7); + } + + template + void operator() (P1 const& p1, P2 const& p2, P3 const& p3, P4 const& p4, + P5 const& p5, P6 const& p6, P7 const& p7, P8 const& p8) + { + m_handler (p1, p2, p3, p4, p5, p6, p7, p8); + } + + template + void operator() (P1 const& p1, P2 const& p2, P3 const& p3, P4 const& p4, + P5 const& p5, P6 const& p6, P7 const& p7, P8 const& p8) const + { + m_handler (p1, p2, p3, p4, p5, p6, p7, p8); + } + +#endif + +private: + Handler m_handler; + Counter& m_counter; +}; + +} + +//------------------------------------------------------------------------------ + +/** Provides a counted_bind replacement for bind which counts pending I/Os. + Derive your class from this class and then call the bind member + function instead. +*/ +class enable_counted_bind +{ +public: + typedef std::size_t size_type; + +private: + typedef std::atomic counter_type; + +public: + enable_counted_bind () + : m_count (0) + { + } + + /** Return the number of binds pending completion. */ + size_type bind_count () const + { + return m_count.load (); + } + + /** Returns a wrapper that calls the handler and manages the counter. */ + template + detail::counted_bind_wrapper wrap (Handler&& h) + { + return detail::counted_bind_wrapper ( + std::forward (h), m_count); + } + +private: + counter_type m_count; +}; + +} + +#endif diff --git a/src/ripple/common/functional/impl/counted_bind.cpp b/src/ripple/common/functional/impl/counted_bind.cpp new file mode 100644 index 0000000000..9ebcc718f6 --- /dev/null +++ b/src/ripple/common/functional/impl/counted_bind.cpp @@ -0,0 +1,176 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2012, 2013 Ripple Labs Inc. + + 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. +*/ +//============================================================================== + +#include "../counted_bind.h" + +namespace ripple { + +using namespace beast; + +class TrackedHandler +{ +public: + explicit TrackedHandler (Journal journal) + : m_journal (journal) + { + m_journal.info << "Constructor"; + } + + TrackedHandler (TrackedHandler const& h) + : m_journal (h.m_journal) + { + m_journal.info << "Copy Constructor"; + } + + TrackedHandler (TrackedHandler&& h) + : m_journal (std::move (h.m_journal)) + { + m_journal.info << "Move Constructor"; + } + + // VFALCO NOTE What the heck does this do? + TrackedHandler (TrackedHandler const&& h) + : m_journal (h.m_journal) + { + m_journal.info << "Move Constructor (const)"; + } + + ~TrackedHandler () + { + m_journal.info << "Destructor"; + } + + void operator () () const + { + m_journal.info << "Function call"; + } + +private: + Journal m_journal; +}; + +//------------------------------------------------------------------------------ + +template +struct HandlerWrapper +{ +#if 1 + // Universal constructor + template + HandlerWrapper (H&& h, std::nullptr_t) // dummy arg + : m_handler (std::forward (h)) + { + } + +#else + // move construct + HandlerWrapper (Handler&& h, nullptr_t) + : m_handler (std::move (h)) + { + } + + // copy construct + HandlerWrapper (Handler const& h, nullptr_t) + : m_handler (h) + { + } +#endif + +#if 0 + template + void operator () (Args&& ...args) + { + m_handler (std::forward (args)...); + } + +#else + void operator() () const + { + m_handler (); + } + +#endif + + Handler const m_handler; +}; + +template +HandlerWrapper < + typename std::remove_reference ::type> make_handler (Handler&& h) +{ + typedef typename std::remove_reference ::type handler_type; + return HandlerWrapper ( + std::forward (h), nullptr); +} + +//------------------------------------------------------------------------------ + +class CountedBindTests : public UnitTest +{ +public: + void runTest () + { + beginTestCase ("Move"); + + Journal const j (journal()); + + { + j.info << "w1"; + TrackedHandler h (j); + HandlerWrapper w1 (std::move (h), nullptr); + w1 (); + } + + { + j.info << "w2"; + HandlerWrapper w2 ((TrackedHandler (j)), nullptr); + w2 (); + } + + { + j.info << "w3"; + TrackedHandler const h (j); + HandlerWrapper w3 (h, nullptr); + w3 (); + } + + { + j.info << "w4"; + auto w4 (make_handler (TrackedHandler (j))); + w4 (); + } + + { + j.info << "w5"; + TrackedHandler const h (j); + auto w5 (make_handler (h)); + w5 (); + } + + pass (); + } + + CountedBindTests () : UnitTest ("counted_bind", "ripple", runManual) + { + } +}; + +static CountedBindTests countedBindTests; + +} diff --git a/src/ripple/common/ripple_common.cpp b/src/ripple/common/ripple_common.cpp new file mode 100644 index 0000000000..1d1795d32b --- /dev/null +++ b/src/ripple/common/ripple_common.cpp @@ -0,0 +1,24 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2012, 2013 Ripple Labs Inc. + + 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. +*/ +//============================================================================== + +#include "BeastConfig.h" + +#include "../../beast/modules/beast_core/beast_core.h" // for UnitTest + +#include "functional/impl/counted_bind.cpp"