[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [35324] trunk/blender/source/blender/ python/intern: Py/RNA api:

Campbell Barton ideasman42 at gmail.com
Thu Mar 3 10:16:07 CET 2011


Revision: 35324
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=35324
Author:   campbellbarton
Date:     2011-03-03 09:16:06 +0000 (Thu, 03 Mar 2011)
Log Message:
-----------
Py/RNA api:
fix for crash when iterating over a collection which allocates the collection and frees on when finished.

The ability for BPy_StructRNA to hold a reference to other PyObject's was added to support this.

Modified Paths:
--------------
    trunk/blender/source/blender/python/intern/bpy_rna.c
    trunk/blender/source/blender/python/intern/bpy_rna.h

Modified: trunk/blender/source/blender/python/intern/bpy_rna.c
===================================================================
--- trunk/blender/source/blender/python/intern/bpy_rna.c	2011-03-03 08:01:11 UTC (rev 35323)
+++ trunk/blender/source/blender/python/intern/bpy_rna.c	2011-03-03 09:16:06 UTC (rev 35324)
@@ -900,6 +900,18 @@
 	return x;
 }
 
+static int pyrna_struct_traverse(BPy_StructRNA *self, visitproc visit, void *arg)
+{
+	Py_VISIT(self->reference);
+	return 0;
+}
+
+static int pyrna_struct_clear(BPy_StructRNA *self)
+{
+	Py_CLEAR(self->reference);
+	return 0;
+}
+
 /* use our own dealloc so we can free a property if we use one */
 static void pyrna_struct_dealloc(BPy_StructRNA *self)
 {
@@ -915,10 +927,31 @@
 	}
 #endif
 
+	if(self->reference) {
+		PyObject_GC_UnTrack(self);
+		pyrna_struct_clear(self);
+	}
+
 	/* Note, for subclassed PyObjects we cant just call PyObject_DEL() directly or it will crash */
 	Py_TYPE(self)->tp_free(self);
 }
 
+/* internal use only */
+static void pyrna_struct_reference_set(BPy_StructRNA *self, PyObject *reference)
+{
+	if(self->reference) {
+//		PyObject_GC_UnTrack(self); /* INITIALIZED TRACKED? */
+		pyrna_struct_clear(self);
+	}
+	/* reference is now NULL */
+
+	if(reference) {
+		self->reference= reference;
+		Py_INCREF(reference);
+//		PyObject_GC_Track(self);  /* INITIALIZED TRACKED? */
+	}
+}
+
 /* use our own dealloc so we can free a property if we use one */
 static void pyrna_prop_dealloc(BPy_PropertyRNA *self)
 {
@@ -4312,15 +4345,15 @@
 	NULL,                       /* PyBufferProcs *tp_as_buffer; */
 
   /*** Flags to define presence of optional/expanded features ***/
-	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,         /* long tp_flags; */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,         /* long tp_flags; */
 
 	NULL,						/*  char *tp_doc;  Documentation string */
   /*** Assigned meaning in release 2.0 ***/
 	/* call function for all accessible objects */
-	NULL,                       /* traverseproc tp_traverse; */
+	(traverseproc) pyrna_struct_traverse,                       /* traverseproc tp_traverse; */
 
 	/* delete references to contained objects */
-	NULL,                       /* inquiry tp_clear; */
+	(inquiry )pyrna_struct_clear,                       /* inquiry tp_clear; */
 
   /***  Assigned meaning in release 2.1 ***/
   /*** rich comparisons ***/
@@ -4819,7 +4852,10 @@
 
 		if(pyrna) { /* unlikely but may fail */
 			if((PyObject *)pyrna != Py_None) {
-				// pyrna->reference;
+				/* hold a reference to the iterator since it may have
+				 * allocated memory 'pyrna' needs. eg: introspecting dynamic enum's  */
+				/* TODO, we could have an api call to know if this is needed since most collections don't */
+				pyrna_struct_reference_set(pyrna, (PyObject *)self);
 			}
 		}
 
@@ -5055,7 +5091,7 @@
 		}
 		else {
 			fprintf(stderr, "Could not make type\n");
-			pyrna = (BPy_StructRNA *) PyObject_NEW(BPy_StructRNA, &pyrna_struct_Type);
+			pyrna = (BPy_StructRNA *) PyObject_GC_New(BPy_StructRNA, &pyrna_struct_Type);
 #ifdef USE_WEAKREFS
 			pyrna->in_weakreflist= NULL;
 #endif
@@ -5069,6 +5105,7 @@
 
 	pyrna->ptr= *ptr;
 	pyrna->freeptr= FALSE;
+	pyrna->reference= NULL;
 
 	// PyC_ObSpit("NewStructRNA: ", (PyObject *)pyrna);
 

Modified: trunk/blender/source/blender/python/intern/bpy_rna.h
===================================================================
--- trunk/blender/source/blender/python/intern/bpy_rna.h	2011-03-03 08:01:11 UTC (rev 35323)
+++ trunk/blender/source/blender/python/intern/bpy_rna.h	2011-03-03 09:16:06 UTC (rev 35324)
@@ -90,6 +90,9 @@
 	PyObject *in_weakreflist;
 #endif
 	PointerRNA ptr;
+	/* generic PyObject we hold a reference to, example use:
+	 * hold onto the collection iterator to prevent it from freeing allocated data we may use */
+	PyObject *reference;
 	int freeptr; /* needed in some cases if ptr.data is created on the fly, free when deallocing */
 } BPy_StructRNA;
 




More information about the Bf-blender-cvs mailing list