diff options
author | Josh Blum | 2013-04-04 22:07:59 -0700 |
---|---|---|
committer | Josh Blum | 2013-04-04 22:07:59 -0700 |
commit | 0f493354d46706ed81b81699c4e5197ee2b82d08 (patch) | |
tree | d177af0a64fa643a5630091dd797d38492e73912 | |
parent | 06b800166e995cf53ec0f87200427512e1518d8f (diff) | |
download | sandhi-0f493354d46706ed81b81699c4e5197ee2b82d08.tar.gz sandhi-0f493354d46706ed81b81699c4e5197ee2b82d08.tar.bz2 sandhi-0f493354d46706ed81b81699c4e5197ee2b82d08.zip |
gras: revisit container storage after yesterdays learning
The mechanisms of connect are now resonsible for grabbing the container ref.
When the object is a shared ptr, the element contructor overload sets weakself.
When the object is in python, the python reference is held,
even if its shared ptr underneath that.
* removed the need for shared_from_this
* removed the ref stuff in python Block
m--------- | gnuradio | 0 | ||||
-rw-r--r-- | include/gras/detail/element.hpp | 27 | ||||
-rw-r--r-- | include/gras/element.hpp | 32 | ||||
-rw-r--r-- | lib/block_actor.cpp | 2 | ||||
-rw-r--r-- | lib/element.cpp | 25 | ||||
-rw-r--r-- | lib/hier_block.cpp | 3 | ||||
-rw-r--r-- | python/gras/GRAS_Block.i | 43 | ||||
-rw-r--r-- | python/gras/GRAS_HierBlock.i | 37 | ||||
-rw-r--r-- | python/gras/GRAS_Utils.i | 22 |
9 files changed, 107 insertions, 84 deletions
diff --git a/gnuradio b/gnuradio -Subproject 993ff9e8c1050bad327041132828370986a72b2 +Subproject 9b7dec28d8554de385f591f8485f1f322d25fcc diff --git a/include/gras/detail/element.hpp b/include/gras/detail/element.hpp index 2b97c8f..f8a8904 100644 --- a/include/gras/detail/element.hpp +++ b/include/gras/detail/element.hpp @@ -3,12 +3,37 @@ #ifndef INCLUDED_GRAS_DETAIL_ELEMENT_HPP #define INCLUDED_GRAS_DETAIL_ELEMENT_HPP +#include <boost/weak_ptr.hpp> + namespace gras { + + //! Weak element overload for the case of shared_ptr container + struct WeakElementSharedPtr : WeakElement + { + WeakElementSharedPtr(boost::weak_ptr<const void> weak_self) + { + _weak_self = weak_self; + } + boost::shared_ptr<const void> lock(void) + { + return _weak_self.lock(); + } + boost::weak_ptr<const void> _weak_self; + }; + template <typename T> inline Element::Element(const boost::shared_ptr<T> &elem) { - *this = elem->shared_to_element(); + //the container is a shared pointer, so save the reference, + //unless the reference was already set to something + if (not elem->weak_self) + { + elem->weak_self.reset(new WeakElementSharedPtr(elem)); + } + + //initialize this new Element from the argument passed + *this = *elem; } } //namespace gras diff --git a/include/gras/element.hpp b/include/gras/element.hpp index cfaa5e4..98286e2 100644 --- a/include/gras/element.hpp +++ b/include/gras/element.hpp @@ -10,7 +10,6 @@ #include <gras/gras.hpp> #include <boost/shared_ptr.hpp> -#include <boost/enable_shared_from_this.hpp> namespace gras { @@ -29,13 +28,13 @@ struct Block; struct WeakElement { //! Lock creates a shared pointer holding a container reference - virtual boost::shared_ptr<void> lock(void) = 0; + virtual boost::shared_ptr<const void> lock(void) = 0; }; /*! * Element is a base class for all topological elements. */ -struct GRAS_API Element : ElementBase, boost::enable_shared_from_this<Element> +struct GRAS_API Element : ElementBase { //! Create an empty element Element(void); @@ -43,8 +42,21 @@ struct GRAS_API Element : ElementBase, boost::enable_shared_from_this<Element> //! Creates a new element given the name Element(const std::string &name); + /*! + * Create an element from a shared pointer to an element. + * Good for that factory function/shared ptr paradigm. + */ + template <typename T> + Element(const boost::shared_ptr<T> &elem); + /*virtual*/ ~Element(void); + //! Convert this object to the element base class + const Element &to_element(void) const; + + //! Convert this object to the element base class + Element &to_element(void); + /*! * Check if another element is the same as this one. * \return true if the rhs is the same as *this. @@ -94,19 +106,13 @@ struct GRAS_API Element : ElementBase, boost::enable_shared_from_this<Element> Block *locate_block(const std::string &path); /******************************************************************* - * Compatibility for dealing with shared ptrs of Elements + * API for dealing with parent containers - for internal use ******************************************************************/ + /*! - * Create an element from a shared pointer to an element. - * Good for that factory function/shared ptr paradigm. + * Allows internals to get a reference to the container holding an element. + * This container could be a shared_ptr or perhaps a Python object. */ - template <typename T> - Element(const boost::shared_ptr<T> &elem); - - //! Convert a shared ptr of a derived class to an Element - Element &shared_to_element(void); - - //! for internal use only boost::shared_ptr<WeakElement> weak_self; }; diff --git a/lib/block_actor.cpp b/lib/block_actor.cpp index 5b1c5db..10c863e 100644 --- a/lib/block_actor.cpp +++ b/lib/block_actor.cpp @@ -92,5 +92,5 @@ BlockActor::BlockActor(void): BlockActor::~BlockActor(void) { - this->mark_done(); + //NOP } diff --git a/lib/element.cpp b/lib/element.cpp index 340bd85..989c184 100644 --- a/lib/element.cpp +++ b/lib/element.cpp @@ -31,30 +31,13 @@ Element::~Element(void) //NOP } -//! Weak element overload for the case of shared_ptr container -struct WeakElementSharedPtr : WeakElement +const Element &Element::to_element(void) const { - WeakElementSharedPtr(boost::weak_ptr<Element> weak_self) - { - _weak_self = weak_self; - } - boost::shared_ptr<void> lock(void) - { - return _weak_self.lock(); - } - boost::weak_ptr<Element> _weak_self; -}; + return *this; +} -Element &Element::shared_to_element(void) +Element &Element::to_element(void) { - try - { - if (not this->weak_self) - { - this->weak_self.reset(new WeakElementSharedPtr(this->shared_from_this())); - } - } - catch(...){} return *this; } diff --git a/lib/hier_block.cpp b/lib/hier_block.cpp index ab474c5..d8756a4 100644 --- a/lib/hier_block.cpp +++ b/lib/hier_block.cpp @@ -42,7 +42,7 @@ static Apology::Wax get_ref(const Element &elem) { if (elem.weak_self) { - boost::shared_ptr<void> shared_self = elem.weak_self->lock(); + boost::shared_ptr<const void> shared_self = elem.weak_self->lock(); if (shared_self) return shared_self; } return elem; @@ -54,7 +54,6 @@ void HierBlock::connect( const Element &sink, const size_t sink_index ){ - //TODO, this is the perfect place to validate IO sigs const Apology::Flow flow( Apology::Port(src->get_elem(), src_index, get_ref(src)), Apology::Port(sink->get_elem(), sink_index, get_ref(sink)) diff --git a/python/gras/GRAS_Block.i b/python/gras/GRAS_Block.i index 9cd96e2..f429e30 100644 --- a/python/gras/GRAS_Block.i +++ b/python/gras/GRAS_Block.i @@ -56,7 +56,6 @@ %{ #include <gras/block.hpp> #include <iostream> -#include <boost/make_shared.hpp> %} %include <gras/element.i> @@ -65,42 +64,6 @@ %include "GRAS_Utils.i" //////////////////////////////////////////////////////////////////////// -// Create a reference holder for python objects -//////////////////////////////////////////////////////////////////////// -%inline %{ - -struct PyObjectRefHolder -{ - PyObjectRefHolder(PyObject *o): - o(o) - { - Py_INCREF(o); - } - ~PyObjectRefHolder(void) - { - PyGILPhondler phil; - Py_DECREF(o); - } - PyObject *o; -}; - -struct WeakElementPyObject : gras::WeakElement -{ - WeakElementPyObject(PyObject *o): - o(o) - { - //NOP - } - boost::shared_ptr<void> lock(void) - { - return boost::make_shared<PyObjectRefHolder>(o); - } - PyObject *o; -}; - -%} - -//////////////////////////////////////////////////////////////////////// // Make a special block with safe overloads //////////////////////////////////////////////////////////////////////// %inline %{ @@ -122,11 +85,6 @@ struct BlockPython : Block this->reset(); } - void _Py_init_weak_ref__(PyObject *o) - { - this->weak_self.reset(new WeakElementPyObject(o)); - } - void notify_active(void) { PyGILPhondler phil; @@ -241,7 +199,6 @@ def sig_to_dtype_sig(sig): class Block(BlockPython): def __init__(self, name='Block', in_sig=None, out_sig=None): BlockPython.__init__(self, name) - self._Py_init_weak_ref__(self) self.set_input_signature(in_sig) self.set_output_signature(out_sig) self.__prop_registry = dict() diff --git a/python/gras/GRAS_HierBlock.i b/python/gras/GRAS_HierBlock.i index 4afe8fe..2ffb349 100644 --- a/python/gras/GRAS_HierBlock.i +++ b/python/gras/GRAS_HierBlock.i @@ -20,6 +20,7 @@ %{ #include <gras/hier_block.hpp> #include <gras/top_block.hpp> +#include <boost/make_shared.hpp> %} //////////////////////////////////////////////////////////////////////// @@ -29,10 +30,37 @@ %include <gras/hier_block.i> %include <gras/top_block.hpp> +%include "GRAS_Utils.i" + +//////////////////////////////////////////////////////////////////////// +// weak element overload for python +//////////////////////////////////////////////////////////////////////// +%inline %{ + +struct WeakElementPyObject : gras::WeakElement +{ + WeakElementPyObject(PyObject *o): + o(o) + { + //NOP + } + boost::shared_ptr<const void> lock(void) + { + return boost::make_shared<PyObjectRefHolder>(o); + } + PyObject *o; +}; + +inline void set_weak_py_self(gras::Element &elem, PyObject *o) +{ + elem.weak_self.reset(new WeakElementPyObject(o)); +} + +%} + //////////////////////////////////////////////////////////////////////// // Make a special top block with python safe unlocking wait //////////////////////////////////////////////////////////////////////// -%include "GRAS_Utils.i" %inline %{ namespace gras @@ -109,13 +137,16 @@ struct HierBlockPython : HierBlock def to_element(obj): if isinstance(obj, Element): return obj - try: return obj.shared_to_element() + try: + elem = obj.to_element() + set_weak_py_self(elem, obj) + return elem except: raise Exception('cant coerce obj %s to element'%(obj)) def internal_connect__(fcn, obj, *args): if len(args) == 1: - elem = (args[0]) + elem = to_element(args[0]) fcn(obj, elem) return diff --git a/python/gras/GRAS_Utils.i b/python/gras/GRAS_Utils.i index afe3314..1b23aca 100644 --- a/python/gras/GRAS_Utils.i +++ b/python/gras/GRAS_Utils.i @@ -41,3 +41,25 @@ struct PyTSPhondler }; %} + +//////////////////////////////////////////////////////////////////////// +// Create a reference holder for python objects +//////////////////////////////////////////////////////////////////////// +%inline %{ + +struct PyObjectRefHolder +{ + PyObjectRefHolder(PyObject *o): + o(o) + { + Py_INCREF(o); + } + ~PyObjectRefHolder(void) + { + PyGILPhondler phil; + Py_DECREF(o); + } + PyObject *o; +}; + +%} |