Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2011-03-01 12:02:54 +0300
committerCampbell Barton <ideasman42@gmail.com>2011-03-01 12:02:54 +0300
commitc9ee017fb52bf68df87fa498555f1df735b46131 (patch)
tree7e83b9dc127ea9d0c7eff3e414a873e0073a5a45 /source/blender/python
parentc8de6195c84caaa9abeb968047512fe8795d16c1 (diff)
Py/RNA API test code to prevent crashing blender when python references freed ID's.
This uses pythons GC so its no overhead during runtime but makes removing ID's slower. Commented definition 'USE_PYRNA_INVALIDATE_GC' for now, so no functional change.
Diffstat (limited to 'source/blender/python')
-rw-r--r--source/blender/python/BPY_extern.h2
-rw-r--r--source/blender/python/intern/bpy_rna.c49
-rw-r--r--source/blender/python/intern/bpy_rna.h3
3 files changed, 48 insertions, 6 deletions
diff --git a/source/blender/python/BPY_extern.h b/source/blender/python/BPY_extern.h
index f4899849702..7901957e5e4 100644
--- a/source/blender/python/BPY_extern.h
+++ b/source/blender/python/BPY_extern.h
@@ -93,6 +93,8 @@ void BPY_DECREF(void *pyob_ptr); /* Py_DECREF() */
int BPY_context_member_get(struct bContext *C, const char *member, struct bContextDataResult *result);
void BPY_context_set(struct bContext *C);
+void BPY_id_release(struct ID *id);
+
#ifdef __cplusplus
} /* extern "C" */
#endif
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index 561cc289e62..bc216207821 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -94,17 +94,54 @@ static int pyrna_prop_validity_check(BPy_PropertyRNA *self)
return -1;
}
-/*
-static void pyrna_struct_invalidate(BPy_StructRNA *self)
+static void pyrna_invalidate(BPy_DummyPointerRNA *self)
{
- self->ptr.type= NULL;
+ self->ptr.type= NULL; /* this is checked for validity */
+ self->ptr.id.data= NULL; /* should not be needed but prevent bad pointer access, just incase */
+}
+
+#ifdef USE_PYRNA_INVALIDATE_GC
+#define FROM_GC(g) ((PyObject *)(((PyGC_Head *)g)+1))
+
+/* only for sizeof() */
+struct gc_generation {
+ PyGC_Head head;
+ int threshold;
+ int count;
+} gc_generation;
+
+static void id_release_gc(struct ID *id)
+{
+ unsigned int j;
+ // unsigned int i= 0;
+ for(j=0; j<3; j++) {
+ /* hack below to get the 2 other lists from _PyGC_generation0 that are normally not exposed */
+ PyGC_Head *gen= (PyGC_Head *)(((char *)_PyGC_generation0) + (sizeof(gc_generation) * j));
+ PyGC_Head *g = gen->gc.gc_next;
+ while ((g= g->gc.gc_next) != gen) {
+ PyObject *ob= FROM_GC(g);
+ if(PyType_IsSubtype(Py_TYPE(ob), &pyrna_struct_Type) || PyType_IsSubtype(Py_TYPE(ob), &pyrna_prop_Type)) {
+ BPy_DummyPointerRNA *ob_ptr= (BPy_DummyPointerRNA *)ob;
+ if(ob_ptr->ptr.id.data == id) {
+ pyrna_invalidate(ob_ptr);
+ // printf("freeing: %p %s, %.200s\n", (void *)ob, id->name, Py_TYPE(ob)->tp_name);
+ // i++;
+ }
+ }
+ }
+ }
+ // printf("id_release_gc freed '%s': %d\n", id->name, i);
}
+#endif
+
-static void pyrna_prop_invalidate(BPy_PropertyRNA *self)
+void BPY_id_release(struct ID *id)
{
- self->ptr.type= NULL;
+ (void)id;
+#ifdef USE_PYRNA_INVALIDATE_GC
+ id_release_gc(id);
+#endif
}
-*/
#ifdef USE_PEDANTIC_WRITE
static short rna_disallow_writes= FALSE;
diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h
index fe30529f680..8d9fabf5627 100644
--- a/source/blender/python/intern/bpy_rna.h
+++ b/source/blender/python/intern/bpy_rna.h
@@ -44,6 +44,9 @@ extern PyTypeObject pyrna_prop_collection_Type;
#define BPy_PropertyRNA_Check(v) (PyObject_TypeCheck(v, &pyrna_prop_Type))
#define BPy_PropertyRNA_CheckExact(v) (Py_TYPE(v) == &pyrna_prop_Type)
+/* method to invalidate removed py data, XXX, slow to remove objects, otherwise no overhead */
+// #define USE_PYRNA_INVALIDATE_GC
+
/* play it safe and keep optional for now, need to test further now this affects looping on 10000's of verts for eg. */
// #define USE_WEAKREFS