diff options
author | Josh Blum | 2013-06-01 22:46:29 -0700 |
---|---|---|
committer | Josh Blum | 2013-06-01 22:46:29 -0700 |
commit | d15ca88acfbd71c5d4f8ab3dabe0f4fbde205985 (patch) | |
tree | e0ba8437cf65503fa05197e774024da4f9b54230 | |
parent | 40af24eb55d2d43f51d7ada30566d5203f0fef8c (diff) | |
download | sandhi-d15ca88acfbd71c5d4f8ab3dabe0f4fbde205985.tar.gz sandhi-d15ca88acfbd71c5d4f8ab3dabe0f4fbde205985.tar.bz2 sandhi-d15ca88acfbd71c5d4f8ab3dabe0f4fbde205985.zip |
gras: created uid API - replaces name and unique_id
m--------- | gnuradio | 0 | ||||
-rw-r--r-- | include/gras/element.hpp | 33 | ||||
-rw-r--r-- | lib/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/block.cpp | 6 | ||||
-rw-r--r-- | lib/block_handlers.cpp | 2 | ||||
-rw-r--r-- | lib/element.cpp | 41 | ||||
-rw-r--r-- | lib/element_impl.hpp | 7 | ||||
-rw-r--r-- | lib/element_uid.cpp | 46 | ||||
-rw-r--r-- | lib/top_block_query.cpp | 4 |
9 files changed, 104 insertions, 36 deletions
diff --git a/gnuradio b/gnuradio -Subproject 2c0627d07360e31bb25ac334d349eb52e27086f +Subproject f4fc952e58ce318298258926f7382ed28b92bfa diff --git a/include/gras/element.hpp b/include/gras/element.hpp index 0aed924..47fbae6 100644 --- a/include/gras/element.hpp +++ b/include/gras/element.hpp @@ -56,18 +56,37 @@ struct GRAS_API Element : boost::shared_ptr<ElementImpl> */ bool equals(const Element &rhs); + /*! + * Get a canonical name for this element. + * This is used for printing elements for debug purposes. + * Do not rely on the string to have any specific formatting. + * \return a canonical string representation + */ + std::string to_string(void) const; + /******************************************************************* * identification interface ******************************************************************/ - //! An integer ID that is unique across the process - long unique_id(void) const; - - //! Get the name of this element - std::string name(void) const; + /*! + * Set the unique identifier of this element. + * The UID must be unique across the process. + * Typically the user will set a UID so an element + * will have a known indentification for the query client. + * This call will throw if UID is not process-unique. + * \param uid a new unique identifier for this element + */ + void set_uid(const std::string &uid); - //! get a canonical name for this element - std::string to_string(void) const; + /*! + * Get the unique identifier of this element. + * Typically, a name is given to an element on construction. + * By default UID will be the name or name + some hash + * when there is more than one element of the same name. + * Otherwise UID is set the by the set_uid API call. + * \return the element's unique identifier as a string + */ + std::string get_uid(void) const; /******************************************************************* * element tree interface diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index add46db..38377dd 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -42,6 +42,7 @@ list(APPEND GRAS_SOURCES ${apology_sources}) list(APPEND GRAS_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/debug.cpp ${CMAKE_CURRENT_SOURCE_DIR}/element.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/element_uid.cpp ${CMAKE_CURRENT_SOURCE_DIR}/sbuffer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/circular_buffer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/buffer_queue_circ.cpp diff --git a/lib/block.cpp b/lib/block.cpp index cd191ad..0059569 100644 --- a/lib/block.cpp +++ b/lib/block.cpp @@ -71,7 +71,7 @@ static void wait_block_cleanup(ElementImpl &self) case BLOCK_CLEANUP_WAIT: if (boost::get_system_time() > start + boost::posix_time::seconds(1)) { - std::cerr << self.id << ", waiting for you to finish." << std::endl; + std::cerr << self.repr << ", waiting for you to finish." << std::endl; state = BLOCK_CLEANUP_WARN; } break; @@ -79,7 +79,7 @@ static void wait_block_cleanup(ElementImpl &self) case BLOCK_CLEANUP_WARN: if (boost::get_system_time() > start + boost::posix_time::seconds(2)) { - std::cerr << self.id << ", give up the thread context!" << std::endl; + std::cerr << self.repr << ", give up the thread context!" << std::endl; state = BLOCK_CLEANUP_DAMN; } break; @@ -87,7 +87,7 @@ static void wait_block_cleanup(ElementImpl &self) case BLOCK_CLEANUP_DAMN: if (boost::get_system_time() > start + boost::posix_time::seconds(3)) { - std::cerr << self.id << " FAIL; application will now hang..." << std::endl; + std::cerr << self.repr << " FAIL; application will now hang..." << std::endl; state = BLOCK_CLEANUP_DOTS; } break; diff --git a/lib/block_handlers.cpp b/lib/block_handlers.cpp index 12ba065..e0ee67a 100644 --- a/lib/block_handlers.cpp +++ b/lib/block_handlers.cpp @@ -154,7 +154,7 @@ void BlockActor::handle_get_stats( //create the message reply object GetStatsMessage message; - message.block_id = this->block_ptr->to_string(); + message.block_id = this->block_ptr->get_uid(); message.stats = this->stats; message.stats_time = time_now(); diff --git a/lib/element.cpp b/lib/element.cpp index dfc3f57..04a638b 100644 --- a/lib/element.cpp +++ b/lib/element.cpp @@ -3,11 +3,10 @@ #include "element_impl.hpp" #include <gras/element.hpp> #include <boost/format.hpp> -#include <boost/detail/atomic_count.hpp> #include <boost/foreach.hpp> #include <boost/algorithm/string.hpp> - -static boost::detail::atomic_count unique_id_pool(0); +#include <boost/functional/hash.hpp> +#include <cstdlib> using namespace gras; @@ -20,8 +19,25 @@ Element::Element(const std::string &name) { this->reset(new ElementImpl()); (*this)->name = name; - (*this)->unique_id = ++unique_id_pool; - (*this)->id = str(boost::format("%s(%d)") % this->name() % this->unique_id()); + std::string extra; + std::string uid = name; + boost::hash<std::string> string_hash; + std::size_t h = string_hash(uid); + while (true) + { + try + { + this->set_uid(uid); + break; + } + catch(const std::invalid_argument &ex) + { + extra = str(boost::format("%04x") % short(h++)); + uid = name+"#"+extra; + } + } + if (not extra.empty()) (*this)->repr = name; + else (*this)->repr = str(boost::format("%s (%s)") % name % extra); if (GENESIS) std::cerr << "New element: " << to_string() << std::endl; } @@ -58,21 +74,6 @@ bool Element::equals(const Element &rhs) return this->get() == rhs.get(); } -long Element::unique_id(void) const -{ - return (*this)->unique_id; -} - -std::string Element::name(void) const -{ - return (*this)->name; -} - -std::string Element::to_string(void) const -{ - return (*this)->id; -} - void Element::adopt_element(const std::string &name, const Element &child) { if (child->parent) throw std::invalid_argument(str(boost::format( diff --git a/lib/element_impl.hpp b/lib/element_impl.hpp index 89097b4..477b478 100644 --- a/lib/element_impl.hpp +++ b/lib/element_impl.hpp @@ -25,10 +25,11 @@ struct ElementImpl void hier_block_cleanup(void); void block_cleanup(void); - //common element properties + //element identification std::string name; - long unique_id; - std::string id; + std::string repr; + boost::shared_ptr<std::string> uid; + boost::shared_ptr<WeakContainer> weak_self; //top block stuff diff --git a/lib/element_uid.cpp b/lib/element_uid.cpp new file mode 100644 index 0000000..89035b4 --- /dev/null +++ b/lib/element_uid.cpp @@ -0,0 +1,46 @@ +// Copyright (C) by Josh Blum. See LICENSE.txt for licensing information. + +#include "element_impl.hpp" +#include <gras/element.hpp> +#include <boost/thread/mutex.hpp> +#include <stdexcept> +#include <set> + +using namespace gras; + +static boost::mutex uid_mutex; +static std::set<std::string> &get_uid_set(void) +{ + static std::set<std::string> uid_set; + return uid_set; +} + +static void free_uid(void *p) +{ + boost::mutex::scoped_lock l(uid_mutex); + std::string *uid = reinterpret_cast<std::string *>(p); + get_uid_set().erase(*uid); + delete uid; +} + +void Element::set_uid(const std::string &uid) +{ + boost::mutex::scoped_lock l(uid_mutex); + if (get_uid_set().count(uid) > 0) + { + throw std::invalid_argument("Element::set_uid - uid already in use: " + uid); + } + (*this)->uid.reset(new std::string(uid), &free_uid); + get_uid_set().insert(uid); +} + +std::string Element::get_uid(void) const +{ + boost::mutex::scoped_lock l(uid_mutex); + return *((*this)->uid); +} + +std::string Element::to_string(void) const +{ + return (*this)->repr; +} diff --git a/lib/top_block_query.cpp b/lib/top_block_query.cpp index 9d8afbe..bf74204 100644 --- a/lib/top_block_query.cpp +++ b/lib/top_block_query.cpp @@ -56,7 +56,7 @@ static ptree query_blocks(ElementImpl *self, const ptree &) block_attrs.push_back(std::make_pair(p.first, prop_attrs)); prop_e.push_back(std::make_pair("props", block_attrs)); } - e.push_back(std::make_pair(block->block_ptr->to_string(), prop_e)); + e.push_back(std::make_pair(block->block_ptr->get_uid(), prop_e)); } root.push_back(std::make_pair("blocks", e)); return root; @@ -80,7 +80,7 @@ static ptree query_stats(ElementImpl *self, const ptree &query) BOOST_FOREACH(Apology::Worker *worker, self->executor->get_workers()) { //filter workers not needed in query - const std::string id = dynamic_cast<BlockActor *>(worker)->block_ptr->to_string(); + const std::string id = dynamic_cast<BlockActor *>(worker)->block_ptr->get_uid(); if (std::find(block_ids.begin(), block_ids.end(), id) == block_ids.end()) continue; //send a message to the block's actor to query stats |