Python/context: python could get invalid bpy.data in scene update handler after
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Tue, 8 May 2012 22:07:06 +0000 (22:07 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Tue, 8 May 2012 22:07:06 +0000 (22:07 +0000)
undo.

The way this got updated from the context is a bit unreliable, and for handlers
the update couldn't happen because there is no context passed in. Now it's
updated from setup_app_data, which is where the change actually happens. I left
in the other updates to be sure but they should not be needed anymore.

source/blender/blenkernel/intern/blender.c
source/blender/python/BPY_extern.h
source/blender/python/intern/bpy_interface.c
source/blender/python/intern/bpy_rna.c
source/blender/python/intern/bpy_util.h

index d8ae95e08e28097613eb2c800c25e15b902ed537..b2cbf0a1ce1f594e6798480cebaa6b52f2d72d1f 100644 (file)
 
 #include "WM_api.h" // XXXXX BAD, very BAD dependency (bad level call) - remove asap, elubie
 
+#ifdef WITH_PYTHON
+#include "BPY_extern.h"
+#endif
+
 Global G;
 UserDef U;
 /* ListBase = {NULL, NULL}; */
@@ -288,6 +292,11 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath
 
        G.f = bfd->globalf;
 
+#ifdef WITH_PYTHON
+       /* let python know about new main */
+       BPY_context_update(C);
+#endif
+
        if (!G.background) {
                //setscreen(G.curscreen);
        }
index 33ea139b474abb038875fea95dcb084201d11e24..83a40ecc068a56a8fc11d9047681ff3cd853cfe6 100644 (file)
@@ -82,6 +82,7 @@ int           BPY_string_exec(struct bContext *C, const char *expr);
 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_context_update(struct bContext *C);
 
 void   BPY_id_release(struct ID *id);
 
index d638a3edf30de5e84b7c2d44d39a3d1b61d1b09b..f3f05e939305bb7e9cefdbb0b35afcab661d185d 100644 (file)
@@ -96,7 +96,7 @@ static double  bpy_timer_run_tot;   /* accumulate python runs */
 #endif
 
 /* use for updating while a python script runs - in case of file load */
-void bpy_context_update(bContext *C)
+void BPY_context_update(bContext *C)
 {
        /* don't do this from a non-main (e.g. render) thread, it can cause a race
         * condition on C->data.recursion. ideal solution would be to disable
@@ -117,7 +117,7 @@ void bpy_context_set(bContext *C, PyGILState_STATE *gilstate)
                *gilstate = PyGILState_Ensure();
 
        if (py_call_level == 1) {
-               bpy_context_update(C);
+               BPY_context_update(C);
 
 #ifdef TIME_PY_RUN
                if (bpy_timer_count == 0) {
@@ -178,7 +178,8 @@ void BPY_modules_update(bContext *C)
 
        /* refreshes the main struct */
        BPY_update_rna_module();
-       bpy_context_module->ptr.data = (void *)C;
+       if(bpy_context_module)
+               bpy_context_module->ptr.data = (void *)C;
 }
 
 void BPY_context_set(bContext *C)
@@ -623,7 +624,7 @@ void BPY_modules_load_user(bContext *C)
        /* update pointers since this can run from a nested script
         * on file load */
        if (py_call_level) {
-               bpy_context_update(C);
+               BPY_context_update(C);
        }
 
        bpy_context_set(C, &gilstate);
index 2174241eeda6d229f6f1c48a7690379692c2c814..13c344655603ba4e042707daddbcdf13cb651414 100644 (file)
@@ -6339,11 +6339,13 @@ PyObject *BPY_rna_module(void)
 
 void BPY_update_rna_module(void)
 {
+       if(rna_module_ptr) {
 #if 0
-       RNA_main_pointer_create(G.main, rna_module_ptr);
+               RNA_main_pointer_create(G.main, rna_module_ptr);
 #else
-       rna_module_ptr->data = G.main; /* just set data is enough */
+               rna_module_ptr->data = G.main; /* just set data is enough */
 #endif
+       }
 }
 
 #if 0
index 4bebcb2ed8598df5b5b9f56b1ee070f112ae49aa..63660b0681349c0d309cf258a67ec579b39ea840 100644 (file)
@@ -49,7 +49,6 @@ short BPy_errors_to_report(struct ReportList *reports);
 struct bContext *BPy_GetContext(void);
 void BPy_SetContext(struct bContext *C);
 
-extern void bpy_context_update(struct bContext *C);
 extern void bpy_context_set(struct bContext *C, PyGILState_STATE *gilstate);
 extern void bpy_context_clear(struct bContext *C, PyGILState_STATE *gilstate);
 #endif