diff options
author | Josh Blum | 2013-04-03 23:58:52 -0700 |
---|---|---|
committer | Josh Blum | 2013-04-03 23:58:52 -0700 |
commit | 06b800166e995cf53ec0f87200427512e1518d8f (patch) | |
tree | cf75d446f986f0bee4976bd4d2d99ea1397cceff | |
parent | f7f459df3b1b4349138324b14703fc18bff7e2a6 (diff) | |
parent | c85fe5cb75d32544eb89a573e8df61757a940766 (diff) | |
download | sandhi-06b800166e995cf53ec0f87200427512e1518d8f.tar.gz sandhi-06b800166e995cf53ec0f87200427512e1518d8f.tar.bz2 sandhi-06b800166e995cf53ec0f87200427512e1518d8f.zip |
Merge branch 'ownership_work'
-rw-r--r-- | include/gras/detail/element.hpp | 11 | ||||
-rw-r--r-- | include/gras/element.hpp | 20 | ||||
-rw-r--r-- | lib/element.cpp | 27 | ||||
-rw-r--r-- | lib/hier_block.cpp | 7 | ||||
-rw-r--r-- | python/gras/GRAS_Block.i | 52 |
5 files changed, 95 insertions, 22 deletions
diff --git a/include/gras/detail/element.hpp b/include/gras/detail/element.hpp index 35033e1..2b97c8f 100644 --- a/include/gras/detail/element.hpp +++ b/include/gras/detail/element.hpp @@ -11,17 +11,6 @@ namespace gras *this = elem->shared_to_element(); } - //! Convert a shared ptr of a derived class to an Element - inline Element &Element::shared_to_element(void) - { - try - { - this->weak_self = this->shared_from_this(); - } - catch(...){} - return *this; - } - } //namespace gras #endif /*INCLUDED_GRAS_DETAIL_ELEMENT_HPP*/ diff --git a/include/gras/element.hpp b/include/gras/element.hpp index 40a24cf..cfaa5e4 100644 --- a/include/gras/element.hpp +++ b/include/gras/element.hpp @@ -21,6 +21,20 @@ typedef boost::shared_ptr<ElementImpl> ElementBase; struct Block; +/*! + * Weak Element interface class: + * Allows internals to get a reference to the container holding an element. + * This container could be a shared_ptr or perhaps a Python object. + */ +struct WeakElement +{ + //! Lock creates a shared pointer holding a container reference + virtual boost::shared_ptr<void> lock(void) = 0; +}; + +/*! + * Element is a base class for all topological elements. + */ struct GRAS_API Element : ElementBase, boost::enable_shared_from_this<Element> { //! Create an empty element @@ -87,13 +101,13 @@ struct GRAS_API Element : ElementBase, boost::enable_shared_from_this<Element> * Good for that factory function/shared ptr paradigm. */ template <typename T> - inline Element(const boost::shared_ptr<T> &elem); + Element(const boost::shared_ptr<T> &elem); //! Convert a shared ptr of a derived class to an Element - inline Element &shared_to_element(void); + Element &shared_to_element(void); //! for internal use only - boost::weak_ptr<Element> weak_self; + boost::shared_ptr<WeakElement> weak_self; }; diff --git a/lib/element.cpp b/lib/element.cpp index 6736011..340bd85 100644 --- a/lib/element.cpp +++ b/lib/element.cpp @@ -31,6 +31,33 @@ Element::~Element(void) //NOP } +//! Weak element overload for the case of shared_ptr container +struct WeakElementSharedPtr : WeakElement +{ + 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; +}; + +Element &Element::shared_to_element(void) +{ + try + { + if (not this->weak_self) + { + this->weak_self.reset(new WeakElementSharedPtr(this->shared_from_this())); + } + } + catch(...){} + return *this; +} + ElementImpl::~ElementImpl(void) { if (this->executor) this->top_block_cleanup(); diff --git a/lib/hier_block.cpp b/lib/hier_block.cpp index 4c0aef3..ab474c5 100644 --- a/lib/hier_block.cpp +++ b/lib/hier_block.cpp @@ -40,8 +40,11 @@ void HierBlock::disconnect(const Element &elem) static Apology::Wax get_ref(const Element &elem) { - boost::shared_ptr<Element> shared_self = elem.weak_self.lock(); - if (shared_self) return shared_self; + if (elem.weak_self) + { + boost::shared_ptr<void> shared_self = elem.weak_self->lock(); + if (shared_self) return shared_self; + } return elem; } diff --git a/python/gras/GRAS_Block.i b/python/gras/GRAS_Block.i index 82c5d78..9cd96e2 100644 --- a/python/gras/GRAS_Block.i +++ b/python/gras/GRAS_Block.i @@ -56,15 +56,53 @@ %{ #include <gras/block.hpp> #include <iostream> +#include <boost/make_shared.hpp> %} %include <gras/element.i> %include <gras/block.i> +%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 //////////////////////////////////////////////////////////////////////// -%include "GRAS_Utils.i" %inline %{ namespace gras @@ -84,6 +122,11 @@ 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; @@ -195,16 +238,13 @@ def sig_to_dtype_sig(sig): if sig is None: sig = () return map(numpy.dtype, sig) -#FIXME major kludge for ref holding -blocks_ref_container = list() - 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) - blocks_ref_container.append(self) - self.__prop_registry = dict(); + self.__prop_registry = dict() def set_input_signature(self, sig): self.__in_sig = sig_to_dtype_sig(sig) |