Replace beast::SharedPtr with std::shared_ptr

This commit is contained in:
Joe Loser
2018-05-23 21:32:59 -04:00
committed by Mike Ellery
parent 6a74d771ee
commit f0cc7c4c8d
6 changed files with 22 additions and 482 deletions

View File

@@ -1,134 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
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_SMART_PTR_SHAREDOBJECT_H_INCLUDED
#define BEAST_SMART_PTR_SHAREDOBJECT_H_INCLUDED
#include <atomic>
#include <cassert>
#include <ripple/beast/core/Config.h>
namespace beast {
//==============================================================================
/**
Adds reference-counting to an object.
To add reference-counting to a class, derive it from this class, and
use the SharedPtr class to point to it.
e.g. @code
class MyClass : public SharedObject
{
void foo();
// This is a neat way of declaring a using Ptr = for a pointer class,
// rather than typing out the full templated name each time..
using Ptr = SharedPtr<MyClass>;
};
MyClass::Ptr p = new MyClass();
MyClass::Ptr p2 = p;
p = nullptr;
p2->foo();
@endcode
Once a new SharedObject has been assigned to a pointer, be
careful not to delete the object manually.
This class uses an std::atomic<int> value to hold the reference count, so
that the pointers can be passed between threads safely.
@see SharedPtr, SharedObjectArray
*/
class SharedObject
{
public:
//==============================================================================
/** Increments the object's reference count.
This is done automatically by the smart pointer, but is public just
in case it's needed for nefarious purposes.
*/
void incReferenceCount() const noexcept
{
++refCount;
}
/** Decreases the object's reference count. */
void decReferenceCount () const
{
assert (getReferenceCount() > 0);
if (--refCount == 0)
destroy ();
}
/** Returns the object's current reference count. */
int getReferenceCount() const noexcept
{
return refCount.load();
}
protected:
//==============================================================================
/** Creates the reference-counted object (with an initial ref count of zero). */
SharedObject()
: refCount (0)
{
}
SharedObject (SharedObject const&) = delete;
SharedObject& operator= (SharedObject const&) = delete;
/** Destructor. */
virtual ~SharedObject()
{
// it's dangerous to delete an object that's still referenced by something else!
assert (getReferenceCount() == 0);
}
/** Destroy the object.
Derived classes can override this for different behaviors.
*/
virtual void destroy () const
{
delete this;
}
/** Resets the reference count to zero without deleting the object.
You should probably never need to use this!
*/
void resetReferenceCount() noexcept
{
refCount.store (0);
}
private:
//==============================================================================
std::atomic <int> mutable refCount;
};
}
#endif

View File

@@ -1,327 +0,0 @@
//------------------------------------------------------------------------------
/*
This file is part of Beast: https://github.com/vinniefalco/Beast
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
Portions of this file are from JUCE.
Copyright (c) 2013 - Raw Material Software Ltd.
Please visit http://www.juce.com
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_SMART_PTR_SHAREDPTR_H_INCLUDED
#define BEAST_SMART_PTR_SHAREDPTR_H_INCLUDED
#include <ripple/beast/core/Config.h>
#include <ripple/beast/core/SharedObject.h>
namespace beast {
// Visual Studio doesn't seem to do very well when it comes
// to templated constructors and assignments so we provide
// non-templated versions when U and T are the same type.
//
#ifndef BEAST_SHAREDPTR_PROVIDE_COMPILER_WORKAROUNDS
#define BEAST_SHAREDPTR_PROVIDE_COMPILER_WORKAROUNDS 1
#endif
/** A smart-pointer container.
Requirement:
T must support the SharedObject concept.
The template parameter specifies the class of the object you want to point
to - the easiest way to make a class reference-countable is to simply make
it inherit from SharedObject, but if you need to, you could roll your own
reference-countable class by implementing a pair of methods called
incReferenceCount() and decReferenceCount().
When using this class, you'll probably want to create a using MyClassPtr = to
abbreviate the full templated name - e.g.
@code
using MyClassPtr = SharedPtr <MyClass>;
@endcode
@see SharedObject, SharedObjectArray
*/
template <class T>
class SharedPtr
{
public:
using value_type = T;
/** The class being referenced by this container. */
using ReferencedType = T;
/** Construct a container pointing to nothing. */
SharedPtr () noexcept
: m_p (nullptr)
{
}
/** Construct a container holding an object.
This will increment the object's reference-count if it is non-null.
Requirement:
U* must be convertible to T*
*/
/** @{ */
SharedPtr (T* t) noexcept
: m_p (acquire (t))
{
}
template <class U>
SharedPtr (U* u) noexcept
: m_p (acquire (u))
{
}
/** @} */
/** Construct a container holding an object from another container.
This will increment the object's reference-count (if it is non-null).
Requirement:
U* must be convertible to T*
*/
/** @{ */
#if BEAST_SHAREDPTR_PROVIDE_COMPILER_WORKAROUNDS
SharedPtr (SharedPtr const& sp) noexcept
: m_p (acquire (sp.get ()))
{
}
#endif
template <class U>
SharedPtr (SharedPtr <U> const& sp) noexcept
: m_p (acquire (sp.get ()))
{
}
/** @} */
/** Assign a different object to the container.
The previous object beind held, if any, loses a reference count and
will be destroyed if it is the last reference.
Requirement:
U* must be convertible to T*
*/
/** @{ */
#if BEAST_SHAREDPTR_PROVIDE_COMPILER_WORKAROUNDS
SharedPtr& operator= (T* t)
{
return assign (t);
}
#endif
template <class U>
SharedPtr& operator= (U* u)
{
return assign (u);
}
/** @} */
/** Assign an object from another container to this one. */
/** @{ */
SharedPtr& operator= (SharedPtr const& sp)
{
return assign (sp.get ());
}
/** Assign an object from another container to this one. */
template <class U>
SharedPtr& operator= (SharedPtr <U> const& sp)
{
return assign (sp.get ());
}
/** @} */
#if BEAST_COMPILER_SUPPORTS_MOVE_SEMANTICS
/** Construct a container with an object transferred from another container.
The originating container loses its reference to the object.
Requires:
U* must be convertible to T*
*/
/** @{ */
#if BEAST_SHAREDPTR_PROVIDE_COMPILER_WORKAROUNDS
SharedPtr (SharedPtr && sp) noexcept
: m_p (sp.swap <T> (nullptr))
{
}
#endif
template <class U>
SharedPtr (SharedPtr <U>&& sp) noexcept
: m_p (sp.template swap <U> (nullptr))
{
}
/** @} */
/** Transfer ownership of another object to this container.
The originating container loses its reference to the object.
Requires:
U* must be convertible to T*
*/
/** @{ */
#if BEAST_SHAREDPTR_PROVIDE_COMPILER_WORKAROUNDS
SharedPtr& operator= (SharedPtr && sp)
{
return assign (sp.swap <T> (nullptr));
}
#endif
template <class U>
SharedPtr& operator= (SharedPtr <U>&& sp)
{
return assign (sp.template swap <U> (nullptr));
}
/** @} */
#endif
/** Destroy the container and release the held reference, if any.
*/
~SharedPtr ()
{
release (m_p);
}
/** Returns `true` if the container is not pointing to an object. */
bool empty () const noexcept
{
return m_p == nullptr;
}
/** Returns the object that this pointer references if any, else nullptr. */
operator T* () const noexcept
{
return m_p;
}
/** Returns the object that this pointer references if any, else nullptr. */
T* operator-> () const noexcept
{
return m_p;
}
/** Returns the object that this pointer references if any, else nullptr. */
T* get () const noexcept
{
return m_p;
}
private:
// Acquire a reference to u for the caller.
//
template <class U>
static T* acquire (U* u) noexcept
{
if (u != nullptr)
u->incReferenceCount ();
return u;
}
static void release (T* t)
{
if (t != nullptr)
t->decReferenceCount ();
}
// Swap ownership of the currently referenced object.
// The caller receives a pointer to the original object,
// and this container is left with the passed object. No
// reference counts are changed.
//
template <class U>
T* swap (U* u)
{
T* const t (m_p);
m_p = u;
return t;
}
// Acquire ownership of u.
// Any previous reference is released.
//
template <class U>
SharedPtr& assign (U* u)
{
if (m_p != u)
release (this->swap (acquire (u)));
return *this;
}
T* m_p;
};
//------------------------------------------------------------------------------
// bind() helpers for pointer to member function
template <class T>
const T* get_pointer (SharedPtr<T> const& ptr)
{
return ptr.get();
}
template <class T>
T* get_pointer (SharedPtr<T>& ptr)
{
return ptr.get();
}
//------------------------------------------------------------------------------
/** SharedPtr comparisons. */
/** @{ */
template <class T, class U>
bool operator== (SharedPtr <T> const& lhs, U* const rhs) noexcept
{
return lhs.get() == rhs;
}
template <class T, class U>
bool operator== (SharedPtr <T> const& lhs, SharedPtr <U> const& rhs) noexcept
{
return lhs.get() == rhs.get();
}
template <class T, class U>
bool operator== (T const* lhs, SharedPtr <U> const& rhs) noexcept
{
return lhs == rhs.get();
}
template <class T, class U>
bool operator!= (SharedPtr <T> const& lhs, U const* rhs) noexcept
{
return lhs.get() != rhs;
}
template <class T, class U>
bool operator!= (SharedPtr <T> const& lhs, SharedPtr <U> const& rhs) noexcept
{
return lhs.get() != rhs.get();
}
template <class T, class U>
bool operator!= (T const* lhs, SharedPtr <U> const& rhs) noexcept
{
return lhs != rhs.get();
}
/** @} */
}
#endif

View File

@@ -20,24 +20,24 @@
#ifndef RIPPLE_PEERFINDER_LOGIC_H_INCLUDED #ifndef RIPPLE_PEERFINDER_LOGIC_H_INCLUDED
#define RIPPLE_PEERFINDER_LOGIC_H_INCLUDED #define RIPPLE_PEERFINDER_LOGIC_H_INCLUDED
#include <ripple/basics/contract.h>
#include <ripple/basics/Log.h> #include <ripple/basics/Log.h>
#include <ripple/basics/contract.h>
#include <ripple/beast/container/aged_container_utility.h>
#include <ripple/beast/net/IPAddressConversion.h>
#include <ripple/peerfinder/PeerfinderManager.h> #include <ripple/peerfinder/PeerfinderManager.h>
#include <ripple/peerfinder/impl/Bootcache.h> #include <ripple/peerfinder/impl/Bootcache.h>
#include <ripple/peerfinder/impl/Counts.h> #include <ripple/peerfinder/impl/Counts.h>
#include <ripple/peerfinder/impl/Fixed.h> #include <ripple/peerfinder/impl/Fixed.h>
#include <ripple/peerfinder/impl/iosformat.h>
#include <ripple/peerfinder/impl/Handouts.h> #include <ripple/peerfinder/impl/Handouts.h>
#include <ripple/peerfinder/impl/Livecache.h> #include <ripple/peerfinder/impl/Livecache.h>
#include <ripple/peerfinder/impl/Reporting.h> #include <ripple/peerfinder/impl/Reporting.h>
#include <ripple/peerfinder/impl/SlotImp.h> #include <ripple/peerfinder/impl/SlotImp.h>
#include <ripple/peerfinder/impl/Source.h> #include <ripple/peerfinder/impl/Source.h>
#include <ripple/peerfinder/impl/Store.h> #include <ripple/peerfinder/impl/Store.h>
#include <ripple/beast/net/IPAddressConversion.h> #include <ripple/peerfinder/impl/iosformat.h>
#include <ripple/beast/container/aged_container_utility.h>
#include <ripple/beast/core/SharedPtr.h>
#include <functional> #include <functional>
#include <map> #include <map>
#include <memory>
#include <set> #include <set>
namespace ripple { namespace ripple {
@@ -54,8 +54,8 @@ public:
// Maps remote endpoints to slots. Since a slot has a // Maps remote endpoints to slots. Since a slot has a
// remote endpoint upon construction, this holds all counts. // remote endpoint upon construction, this holds all counts.
// //
using Slots = std::map <beast::IP::Endpoint, using Slots = std::map<beast::IP::Endpoint,
std::shared_ptr <SlotImp>>; std::shared_ptr<SlotImp>>;
beast::Journal m_journal; beast::Journal m_journal;
clock_type& m_clock; clock_type& m_clock;
@@ -69,7 +69,7 @@ public:
// The source we are currently fetching. // The source we are currently fetching.
// This is used to cancel I/O during program exit. // This is used to cancel I/O during program exit.
beast::SharedPtr <Source> fetchSource_; std::shared_ptr<Source> fetchSource_;
// Configuration settings // Configuration settings
Config config_; Config config_;
@@ -78,7 +78,7 @@ public:
Counts counts_; Counts counts_;
// A list of slots that should always be connected // A list of slots that should always be connected
std::map <beast::IP::Endpoint, Fixed> fixed_; std::map<beast::IP::Endpoint, Fixed> fixed_;
// Live livecache from mtENDPOINTS messages // Live livecache from mtENDPOINTS messages
Livecache <> livecache_; Livecache <> livecache_;
@@ -92,13 +92,13 @@ public:
// The addresses (but not port) we are connected to. This includes // The addresses (but not port) we are connected to. This includes
// outgoing connection attempts. Note that this set can contain // outgoing connection attempts. Note that this set can contain
// duplicates (since the port is not set) // duplicates (since the port is not set)
std::multiset <beast::IP::Address> connectedAddresses_; std::multiset<beast::IP::Address> connectedAddresses_;
// Set of public keys belonging to active peers // Set of public keys belonging to active peers
std::set <PublicKey> keys_; std::set<PublicKey> keys_;
// A list of dynamic sources to consult as a fallback // A list of dynamic sources to consult as a fallback
std::vector <beast::SharedPtr <Source>> m_sources; std::vector<std::shared_ptr<Source>> m_sources;
clock_type::time_point m_whenBroadcast; clock_type::time_point m_whenBroadcast;
@@ -971,13 +971,13 @@ public:
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
void void
addStaticSource (beast::SharedPtr <Source> const& source) addStaticSource (std::shared_ptr<Source> const& source)
{ {
fetch (source); fetch (source);
} }
void void
addSource (beast::SharedPtr <Source> const& source) addSource (std::shared_ptr<Source> const& source)
{ {
m_sources.push_back (source); m_sources.push_back (source);
} }
@@ -1004,7 +1004,8 @@ public:
} }
// Fetch bootcache addresses from the specified source. // Fetch bootcache addresses from the specified source.
void fetch (beast::SharedPtr <Source> const& source) void
fetch (std::shared_ptr<Source> const& source)
{ {
Source::Results results; Source::Results results;

View File

@@ -21,7 +21,6 @@
#define RIPPLE_PEERFINDER_SOURCE_H_INCLUDED #define RIPPLE_PEERFINDER_SOURCE_H_INCLUDED
#include <ripple/peerfinder/PeerfinderManager.h> #include <ripple/peerfinder/PeerfinderManager.h>
#include <ripple/beast/core/SharedObject.h>
#include <boost/system/error_code.hpp> #include <boost/system/error_code.hpp>
namespace ripple { namespace ripple {
@@ -35,7 +34,7 @@ namespace PeerFinder {
be updated automatically. Another solution is to use a custom DNS server be updated automatically. Another solution is to use a custom DNS server
that hands out peer IP addresses when name lookups are performed. that hands out peer IP addresses when name lookups are performed.
*/ */
class Source : public beast::SharedObject class Source
{ {
public: public:
/** The results of a fetch. */ /** The results of a fetch. */

View File

@@ -61,10 +61,10 @@ private:
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
beast::SharedPtr <Source> std::shared_ptr<Source>
SourceStrings::New (std::string const& name, Strings const& strings) SourceStrings::New (std::string const& name, Strings const& strings)
{ {
return new SourceStringsImp (name, strings); return std::make_shared<SourceStringsImp> (name, strings);
} }
} }

View File

@@ -21,7 +21,7 @@
#define RIPPLE_PEERFINDER_SOURCESTRINGS_H_INCLUDED #define RIPPLE_PEERFINDER_SOURCESTRINGS_H_INCLUDED
#include <ripple/peerfinder/impl/Source.h> #include <ripple/peerfinder/impl/Source.h>
#include <ripple/beast/core/SharedPtr.h> #include <memory>
namespace ripple { namespace ripple {
namespace PeerFinder { namespace PeerFinder {
@@ -34,7 +34,8 @@ public:
using Strings = std::vector <std::string>; using Strings = std::vector <std::string>;
static beast::SharedPtr <Source> New (std::string const& name, Strings const& strings); static std::shared_ptr<Source>
New (std::string const& name, Strings const& strings);
}; };
} }