summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/gras/detail/element.hpp16
-rw-r--r--include/gras/element.hpp11
-rw-r--r--lib/hier_block.cpp7
-rw-r--r--python/gras/GRAS_Block.i51
4 files changed, 74 insertions, 11 deletions
diff --git a/include/gras/detail/element.hpp b/include/gras/detail/element.hpp
index 35033e1..22a63a0 100644
--- a/include/gras/detail/element.hpp
+++ b/include/gras/detail/element.hpp
@@ -5,6 +5,19 @@
namespace gras
{
+ 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;
+ };
+
template <typename T>
inline Element::Element(const boost::shared_ptr<T> &elem)
{
@@ -16,7 +29,8 @@ namespace gras
{
try
{
- this->weak_self = this->shared_from_this();
+ if (not this->weak_self)
+ this->weak_self.reset(new WeakElementSharedPtr(this->shared_from_this()));
}
catch(...){}
return *this;
diff --git a/include/gras/element.hpp b/include/gras/element.hpp
index 40a24cf..f9a223d 100644
--- a/include/gras/element.hpp
+++ b/include/gras/element.hpp
@@ -19,6 +19,11 @@ struct ElementImpl;
typedef boost::shared_ptr<ElementImpl> ElementBase;
+struct WeakElement
+{
+ virtual boost::shared_ptr<void> lock(void) = 0;
+};
+
struct Block;
struct GRAS_API Element : ElementBase, boost::enable_shared_from_this<Element>
@@ -87,13 +92,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/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..e18476a 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,12 @@ struct BlockPython : Block
this->reset();
}
+ void _Py_set_ref(PyObject *o)
+ {
+ std::cout << o->ob_refcnt <<std::endl;
+ this->weak_self.reset(new WeakElementPyObject(o));
+ }
+
void notify_active(void)
{
PyGILPhondler phil;
@@ -195,16 +239,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.set_input_signature(in_sig)
self.set_output_signature(out_sig)
- blocks_ref_container.append(self)
self.__prop_registry = dict();
+ self._Py_set_ref(self)
def set_input_signature(self, sig):
self.__in_sig = sig_to_dtype_sig(sig)