summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Blum2013-04-04 22:07:59 -0700
committerJosh Blum2013-04-04 22:07:59 -0700
commit0f493354d46706ed81b81699c4e5197ee2b82d08 (patch)
treed177af0a64fa643a5630091dd797d38492e73912
parent06b800166e995cf53ec0f87200427512e1518d8f (diff)
downloadsandhi-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---------gnuradio0
-rw-r--r--include/gras/detail/element.hpp27
-rw-r--r--include/gras/element.hpp32
-rw-r--r--lib/block_actor.cpp2
-rw-r--r--lib/element.cpp25
-rw-r--r--lib/hier_block.cpp3
-rw-r--r--python/gras/GRAS_Block.i43
-rw-r--r--python/gras/GRAS_HierBlock.i37
-rw-r--r--python/gras/GRAS_Utils.i22
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;
+};
+
+%}