From d4c4a03e42c058a92fda246403b9db317fa3a25f Mon Sep 17 00:00:00 2001 From: Nik Bougalis Date: Sat, 10 Oct 2015 19:34:59 -0700 Subject: [PATCH] Remove beast::SharedData --- beast/Threads.h | 1 - beast/insight/impl/StatsDCollector.cpp | 27 +-- beast/threads/SharedData.h | 287 ------------------------- beast/utility/PropertyStream.h | 32 +-- beast/utility/impl/PropertyStream.cpp | 94 +++----- 5 files changed, 50 insertions(+), 391 deletions(-) delete mode 100644 beast/threads/SharedData.h diff --git a/beast/Threads.h b/beast/Threads.h index 73a7ec77b..07a76138d 100644 --- a/beast/Threads.h +++ b/beast/Threads.h @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include diff --git a/beast/insight/impl/StatsDCollector.cpp b/beast/insight/impl/StatsDCollector.cpp index c180f3e66..e16035f19 100644 --- a/beast/insight/impl/StatsDCollector.cpp +++ b/beast/insight/impl/StatsDCollector.cpp @@ -20,13 +20,13 @@ #include #include #include -#include #include #include #include #include #include #include +#include #include #include #include @@ -192,13 +192,6 @@ private: max_packet_size = 1472 }; - struct StateType - { - List metrics; - }; - - using State = SharedData ; - Journal m_journal; IP::Endpoint m_address; std::string m_prefix; @@ -208,7 +201,8 @@ private: boost::asio::deadline_timer m_timer; boost::asio::ip::udp::socket m_socket; std::deque m_data; - State m_state; + std::recursive_mutex metricsLock_; + List metrics_; // Must come last for order of init std::thread m_thread; @@ -288,14 +282,14 @@ public: void add (StatsDMetricBase& metric) { - State::Access state (m_state); - state->metrics.push_back (metric); + std::lock_guard _(metricsLock_); + metrics_.push_back (metric); } void remove (StatsDMetricBase& metric) { - State::Access state (m_state); - state->metrics.erase (state->metrics.iterator_to (metric)); + std::lock_guard _(metricsLock_); + metrics_.erase (metrics_.iterator_to (metric)); } //-------------------------------------------------------------------------- @@ -425,11 +419,10 @@ public: return; } - State::Access state (m_state); + std::lock_guard _(metricsLock_); - for (List ::iterator iter (state->metrics.begin()); - iter != state->metrics.end(); ++iter) - iter->do_process(); + for (auto& m : metrics_) + m.do_process(); send_buffers (); diff --git a/beast/threads/SharedData.h b/beast/threads/SharedData.h deleted file mode 100644 index 9c6412987..000000000 --- a/beast/threads/SharedData.h +++ /dev/null @@ -1,287 +0,0 @@ -//------------------------------------------------------------------------------ -/* - 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_SHAREDDATA_H_INCLUDED -#define BEAST_THREADS_SHAREDDATA_H_INCLUDED - -#include -#include - -namespace beast { - -/** Structured, multi-threaded access to a shared state. - - This container combines locking semantics with data access semantics to - create an alternative to the typical synchronization method of first - acquiring a lock and then accessing data members. - - With this container, access to the underlying data is only possible after - first acquiring a lock. The steps of acquiring the lock and obtaining - a const or non-const reference to the data are combined into one - RAII style operation. - - There are three types of access: - - - Access - Provides access to the shared state via a non-const reference or pointer. - Access acquires a unique lock on the mutex associated with the - container. - - - ConstAccess - Provides access to the shared state via a const reference or pointer. - ConstAccess acquires a shared lock on the mutex associated with the - container. - - - ConstUnlockedAccess - Provides access to the shared state via a const reference or pointer. - No locking is performed. It is the callers responsibility to ensure that - the operation is synchronized. This can be useful for diagnostics or - assertions, or for when it is known that no other threads can access - the data. - - - UnlockedAccess - Provides access to the shared state via a reference or pointer. - No locking is performed. It is the callers responsibility to ensure that - the operation is synchronized. This can be useful for diagnostics or - assertions, or for when it is known that no other threads can access - the data. - - Usage example: - - @code - - struct State - { - int value1; - String value2; - }; - - using SharedState = SharedData ; - - SharedState m_state; - - void readExample () - { - SharedState::ConstAccess state (m_state); - - print (state->value1); // read access - print (state->value2); // read access - - state->value1 = 42; // write disallowed: compile error - } - - void writeExample () - { - SharedState::Access state (m_state); - - state->value2 = "Label"; // write access, allowed - } - - @endcode - - Requirements for Value: - Constructible - Destructible - - Requirements for SharedMutexType: - X is SharedMutexType, a is an instance of X: - X a; DefaultConstructible - X::LockGuardType Names a type that implements the LockGuard concept. - X::SharedLockGuardType Names a type that implements the SharedLockGuard concept. - - @tparam Value The type which the container holds. - @tparam SharedMutexType The type of shared mutex to use. -*/ -template > -class SharedData -{ -private: - using LockGuardType = typename SharedMutexType::LockGuardType; - using SharedLockGuardType = typename SharedMutexType::SharedLockGuardType; - -public: - using ValueType = Value; - - class Access; - class ConstAccess; - class UnlockedAccess; - class ConstUnlockedAccess; - - /** Create a shared data container. - Up to 8 parameters can be specified in the constructor. These parameters - are forwarded to the corresponding constructor in Data. If no - constructor in Data matches the parameter list, a compile error is - generated. - */ - /** @{ */ - SharedData () = default; - - template - explicit SharedData (T1 t1) - : m_value (t1) { } - - template - SharedData (T1 t1, T2 t2) - : m_value (t1, t2) { } - - template - SharedData (T1 t1, T2 t2, T3 t3) - : m_value (t1, t2, t3) { } - - template - SharedData (T1 t1, T2 t2, T3 t3, T4 t4) - : m_value (t1, t2, t3, t4) { } - - template - SharedData (T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) - : m_value (t1, t2, t3, t4, t5) { } - - template - SharedData (T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) - : m_value (t1, t2, t3, t4, t5, t6) { } - - template - SharedData (T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7) : m_value (t1, t2, t3, t4, t5, t6, t7) { } - - template - SharedData (T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8) - : m_value (t1, t2, t3, t4, t5, t6, t7, t8) { } - /** @} */ - - SharedData (SharedData const&) = delete; - SharedData& operator= (SharedData const&) = delete; - -private: - Value m_value; - SharedMutexType m_mutex; -}; - -//------------------------------------------------------------------------------ - -/** Provides non-const access to the contents of a SharedData. - This acquires a unique lock on the underlying mutex. -*/ -template -class SharedData ::Access -{ -public: - explicit Access (SharedData& state) - : m_state (state) - , m_lock (m_state.m_mutex) - { } - - Access (Access const&) = delete; - Access& operator= (Access const&) = delete; - - Data const& get () const { return m_state.m_value; } - Data const& operator* () const { return get (); } - Data const* operator-> () const { return &get (); } - Data& get () { return m_state.m_value; } - Data& operator* () { return get (); } - Data* operator-> () { return &get (); } - -private: - SharedData& m_state; - typename SharedData::LockGuardType m_lock; -}; - -//------------------------------------------------------------------------------ - -/** Provides const access to the contents of a SharedData. - This acquires a shared lock on the underlying mutex. -*/ -template -class SharedData ::ConstAccess -{ -public: - /** Create a ConstAccess from the specified SharedData */ - explicit ConstAccess (SharedData const volatile& state) - : m_state (const_cast (state)) - , m_lock (m_state.m_mutex) - { } - - ConstAccess (ConstAccess const&) = delete; - ConstAccess& operator= (ConstAccess const&) = delete; - - Data const& get () const { return m_state.m_value; } - Data const& operator* () const { return get (); } - Data const* operator-> () const { return &get (); } - -private: - SharedData const& m_state; - typename SharedData::SharedLockGuardType m_lock; -}; - -//------------------------------------------------------------------------------ - -/** Provides const access to the contents of a SharedData. - This acquires a shared lock on the underlying mutex. -*/ -template -class SharedData ::ConstUnlockedAccess -{ -public: - /** Create an UnlockedAccess from the specified SharedData */ - explicit ConstUnlockedAccess (SharedData const volatile& state) - : m_state (const_cast (state)) - { } - - ConstUnlockedAccess (ConstUnlockedAccess const&) = delete; - ConstUnlockedAccess& operator= (ConstUnlockedAccess const&) = delete; - - Data const& get () const { return m_state.m_value; } - Data const& operator* () const { return get (); } - Data const* operator-> () const { return &get (); } - -private: - SharedData const& m_state; -}; - -//------------------------------------------------------------------------------ - -/** Provides access to the contents of a SharedData. - This acquires a shared lock on the underlying mutex. -*/ -template -class SharedData ::UnlockedAccess -{ -public: - /** Create an UnlockedAccess from the specified SharedData */ - explicit UnlockedAccess (SharedData& state) - : m_state (state) - { } - - UnlockedAccess (UnlockedAccess const&) = delete; - UnlockedAccess& operator= (UnlockedAccess const&) = delete; - - Data const& get () const { return m_state.m_value; } - Data const& operator* () const { return get (); } - Data const* operator-> () const { return &get (); } - Data& get () { return m_state.m_value; } - Data& operator* () { return get (); } - Data* operator-> () { return &get (); } - -private: - SharedData& m_state; -}; - -} - -#endif diff --git a/beast/utility/PropertyStream.h b/beast/utility/PropertyStream.h index cdedf01eb..ce0be6400 100644 --- a/beast/utility/PropertyStream.h +++ b/beast/utility/PropertyStream.h @@ -21,9 +21,9 @@ #define BEAST_UTILITY_PROPERTYSTREAM_H_INCLUDED #include -#include #include +#include #include #include #include @@ -274,31 +274,11 @@ public: class PropertyStream::Source { private: - struct State - { - explicit State (Source* source) - : item (source) - , parent (nullptr) - { } - - Item item; - Source* parent; - List children; - }; - - using SharedState = SharedData ; - std::string const m_name; - SharedState m_state; - - //-------------------------------------------------------------------------- - - void remove (SharedState::Access& state, - SharedState::Access& childState); - - void removeAll (SharedState::Access& state); - - void write (SharedState::Access& state, PropertyStream& stream); + std::recursive_mutex lock_; + Item item_; + Source* parent_; + List children_; public: explicit Source (std::string const& name); @@ -326,7 +306,7 @@ public: /** Remove a child source from this Source. */ void remove (Source& child); - /** Remove all child sources of this Source. */ + /** Remove all child sources from this Source. */ void removeAll (); /** Write only this Source to the stream. */ diff --git a/beast/utility/impl/PropertyStream.cpp b/beast/utility/impl/PropertyStream.cpp index de271a06a..641be5ee8 100644 --- a/beast/utility/impl/PropertyStream.cpp +++ b/beast/utility/impl/PropertyStream.cpp @@ -173,16 +173,17 @@ PropertyStream const& PropertyStream::Set::stream() const PropertyStream::Source::Source (std::string const& name) : m_name (name) - , m_state (this) + , item_ (this) + , parent_ (nullptr) { } PropertyStream::Source::~Source () { - SharedState::Access state (m_state); - if (state->parent != nullptr) - state->parent->remove (*this); - removeAll (state); + std::lock_guard _(lock_); + if (parent_ != nullptr) + parent_->remove (*this); + removeAll (); } std::string const& PropertyStream::Source::name () const @@ -192,37 +193,35 @@ std::string const& PropertyStream::Source::name () const void PropertyStream::Source::add (Source& source) { - SharedState::Access state (m_state); - SharedState::Access childState (source.m_state); - bassert (childState->parent == nullptr); - state->children.push_back (childState->item); - childState->parent = this; + std::lock(lock_, source.lock_); + std::lock_guard lk1(lock_, std::adopt_lock); + std::lock_guard lk2(source.lock_, std::adopt_lock); + + bassert (source.parent_ == nullptr); + children_.push_back (source.item_); + source.parent_ = this; } void PropertyStream::Source::remove (Source& child) { - SharedState::Access state (m_state); - SharedState::Access childState (child.m_state); - remove (state, childState); + std::lock(lock_, child.lock_); + std::lock_guard lk1(lock_, std::adopt_lock); + std::lock_guard lk2(child.lock_, std::adopt_lock); + + bassert (child.parent_ == this); + children_.erase ( + children_.iterator_to ( + child.item_)); + child.parent_ = nullptr; } void PropertyStream::Source::removeAll () { - SharedState::Access state (m_state); - removeAll (state); -} - -//------------------------------------------------------------------------------ - -void PropertyStream::Source::write ( - SharedState::Access& state, PropertyStream &stream) -{ - for (List ::iterator iter (state->children.begin()); - iter != state->children.end(); ++iter) + std::lock_guard _(lock_); + for (auto iter = children_.begin(); iter != children_.end(); ) { - Source& source (iter->source()); - Map map (source.name(), stream); - source.write (stream); + std::lock_guard _cl((*iter)->lock_); + remove (*(*iter)); } } @@ -239,14 +238,10 @@ void PropertyStream::Source::write (PropertyStream& stream) Map map (m_name, stream); onWrite (map); - SharedState::Access state (m_state); + std::lock_guard _(lock_); - for (List ::iterator iter (state->children.begin()); - iter != state->children.end(); ++iter) - { - Source& source (iter->source()); - source.write (stream); - } + for (auto& child : children_) + child.source().write (stream); } void PropertyStream::Source::write (PropertyStream& stream, std::string const& path) @@ -330,8 +325,9 @@ PropertyStream::Source* PropertyStream::Source::find_one_deep (std::string const Source* found = find_one (name); if (found != nullptr) return found; - SharedState::Access state (this->m_state); - for (auto& s : state->children) + + std::lock_guard _(lock_); + for (auto& s : children_) { found = s.source().find_one_deep (name); if (found != nullptr) @@ -360,8 +356,8 @@ PropertyStream::Source* PropertyStream::Source::find_path (std::string path) // If no immediate children match, then return nullptr PropertyStream::Source* PropertyStream::Source::find_one (std::string const& name) { - SharedState::Access state (this->m_state); - for (auto& s : state->children) + std::lock_guard _(lock_); + for (auto& s : children_) { if (s.source().m_name == name) return &s.source(); @@ -373,28 +369,6 @@ void PropertyStream::Source::onWrite (Map&) { } -//------------------------------------------------------------------------------ - -void PropertyStream::Source::remove ( - SharedState::Access& state, SharedState::Access& childState) -{ - bassert (childState->parent == this); - state->children.erase ( - state->children.iterator_to ( - childState->item)); - childState->parent = nullptr; -} - -void PropertyStream::Source::removeAll (SharedState::Access& state) -{ - for (List ::iterator iter (state->children.begin()); - iter != state->children.end();) - { - SharedState::Access childState ((*iter)->m_state); - remove (state, childState); - } -} - //------------------------------------------------------------------------------ // // PropertyStream