summaryrefslogtreecommitdiff
path: root/python/generic.h
diff options
context:
space:
mode:
authorJulian Andres Klode <jak@debian.org>2009-06-21 19:47:31 +0200
committerJulian Andres Klode <jak@debian.org>2009-06-21 19:47:31 +0200
commit13423bbbafc823740126e90ef0d7ca6e76fc7341 (patch)
tree98f59b5559b6ad2f752ad46645e1284c3549fa02 /python/generic.h
parent894a226f24150cc35f933b72bf14c9587e15b73e (diff)
downloadpython-apt-13423bbbafc823740126e90ef0d7ca6e76fc7341.tar.gz
python: Make all CppOwnedPyObjects and similar support garbage collection.
If you want to subclass apt_pkg.Cache() and create an apt_pkg.DepCache() object in it (e.g. as self.depcache) this is needed because otherwise, Python would not know about the cyclic dependency and refuse to free any of them. This also changes apt_pkg.Cache to the standard deallocation schema, because the underlying CacheFile deletes its pointers automatically on deletion. Thus a second call is not needed.
Diffstat (limited to 'python/generic.h')
-rw-r--r--python/generic.h44
1 files changed, 40 insertions, 4 deletions
diff --git a/python/generic.h b/python/generic.h
index b7b958f5..a9e6b8bf 100644
--- a/python/generic.h
+++ b/python/generic.h
@@ -29,6 +29,7 @@
#include <Python.h>
#include <string>
+#include <iostream>
#include <new>
#if PYTHON_API_VERSION < 1013
@@ -99,6 +100,9 @@ inline PyObject *GetOwner(PyObject *Obj)
template <class T>
inline CppPyObject<T> *CppPyObject_NEW(PyTypeObject *Type)
{
+ #ifdef ALLOC_DEBUG
+ std::cerr << "=== ALLOCATING " << Type->tp_name << " ===\n";
+ #endif
CppPyObject<T> *New = (CppPyObject<T>*)Type->tp_alloc(Type, 0);
new (&New->Object) T;
return New;
@@ -107,6 +111,9 @@ inline CppPyObject<T> *CppPyObject_NEW(PyTypeObject *Type)
template <class T,class A>
inline CppPyObject<T> *CppPyObject_NEW(PyTypeObject *Type,A const &Arg)
{
+ #ifdef ALLOC_DEBUG
+ std::cerr << "=== ALLOCATING " << Type->tp_name << " ===\n";
+ #endif
CppPyObject<T> *New = (CppPyObject<T>*)Type->tp_alloc(Type, 0);
new (&New->Object) T(Arg);
return New;
@@ -116,6 +123,9 @@ template <class T>
inline CppOwnedPyObject<T> *CppOwnedPyObject_NEW(PyObject *Owner,
PyTypeObject *Type)
{
+ #ifdef ALLOC_DEBUG
+ std::cerr << "=== ALLOCATING " << Type->tp_name << "+ ===\n";
+ #endif
CppOwnedPyObject<T> *New = (CppOwnedPyObject<T>*)Type->tp_alloc(Type, 0);
new (&New->Object) T;
New->Owner = Owner;
@@ -127,6 +137,9 @@ template <class T,class A>
inline CppOwnedPyObject<T> *CppOwnedPyObject_NEW(PyObject *Owner,
PyTypeObject *Type,A const &Arg)
{
+ #ifdef ALLOC_DEBUG
+ std::cerr << "=== ALLOCATING " << Type->tp_name << "+ ===\n";
+ #endif
CppOwnedPyObject<T> *New = (CppOwnedPyObject<T>*)Type->tp_alloc(Type, 0);
new (&New->Object) T(Arg);
New->Owner = Owner;
@@ -135,10 +148,26 @@ inline CppOwnedPyObject<T> *CppOwnedPyObject_NEW(PyObject *Owner,
return New;
}
+// Traversal and Clean for owned objects
+template <class T>
+int CppOwnedTraverse(PyObject *self, visitproc visit, void* arg) {
+ Py_VISIT(((CppOwnedPyObject<T> *)self)->Owner);
+ return 0;
+}
+
+template <class T>
+int CppOwnedClear(PyObject *self) {
+ Py_CLEAR(((CppOwnedPyObject<T> *)self)->Owner);
+ return 0;
+}
+
// Generic Dealloc type functions
template <class T>
void CppDealloc(PyObject *Obj)
{
+ #ifdef ALLOC_DEBUG
+ std::cerr << "=== DEALLOCATING " << Obj->ob_type->tp_name << " ===\n";
+ #endif
GetCpp<T>(Obj).~T();
Obj->ob_type->tp_free(Obj);
}
@@ -146,10 +175,12 @@ void CppDealloc(PyObject *Obj)
template <class T>
void CppOwnedDealloc(PyObject *iObj)
{
+ #ifdef ALLOC_DEBUG
+ std::cerr << "=== DEALLOCATING " << iObj->ob_type->tp_name << "+ ===\n";
+ #endif
CppOwnedPyObject<T> *Obj = (CppOwnedPyObject<T> *)iObj;
Obj->Object.~T();
- if (Obj->Owner != 0)
- Py_DECREF(Obj->Owner);
+ CppOwnedClear<T>(iObj);
iObj->ob_type->tp_free(iObj);
}
@@ -158,6 +189,9 @@ void CppOwnedDealloc(PyObject *iObj)
template <class T>
void CppDeallocPtr(PyObject *Obj)
{
+ #ifdef ALLOC_DEBUG
+ std::cerr << "=== DEALLOCATING " << Obj->ob_type->tp_name << "* ===\n";
+ #endif
delete GetCpp<T>(Obj);
Obj->ob_type->tp_free(Obj);
}
@@ -165,10 +199,12 @@ void CppDeallocPtr(PyObject *Obj)
template <class T>
void CppOwnedDeallocPtr(PyObject *iObj)
{
+ #ifdef ALLOC_DEBUG
+ std::cerr << "=== DEALLOCATING " << iObj->ob_type->tp_name << "*+ ===\n";
+ #endif
CppOwnedPyObject<T> *Obj = (CppOwnedPyObject<T> *)iObj;
delete Obj->Object;
- if (Obj->Owner != 0)
- Py_DECREF(Obj->Owner);
+ CppOwnedClear<T>(iObj);
iObj->ob_type->tp_free(iObj);
}