Fix #21062 and #22175: crash with node previews being calculated while
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Sun, 4 Jul 2010 19:58:52 +0000 (19:58 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Sun, 4 Jul 2010 19:58:52 +0000 (19:58 +0000)
editing nodes. Now preview jobs are killed before making any node edits.

source/blender/editors/include/ED_render.h
source/blender/editors/interface/interface_templates.c
source/blender/editors/render/render_preview.c
source/blender/editors/space_file/filelist.c
source/blender/editors/space_node/node_edit.c
source/blender/windowmanager/WM_api.h
source/blender/windowmanager/intern/wm_jobs.c

index 6100ecd436f3b127e61e39f1ff0f6fe40737e1de..f34670da471f78b697d94be619d4b4e4f359baf5 100644 (file)
@@ -78,6 +78,7 @@ void ED_preview_free_dbase(void);
 
 void ED_preview_shader_job(const struct bContext *C, void *owner, struct ID *id, struct ID *parent, struct MTex *slot, int sizex, int sizey, int method);
 void ED_preview_icon_job(const struct bContext *C, void *owner, struct ID *id, unsigned int *rect, int sizex, int sizey);
+void ED_preview_kill_jobs(const struct bContext *C);
 
 void ED_preview_draw(const struct bContext *C, void *idp, void *parentp, void *slot, rcti *rect);
 
index 865a4ec8af9bc484c97b0d8dfeafe480ea86ad12..dbe64bedbc628e35bb9464d4c03a6b5852975724 100644 (file)
@@ -952,7 +952,6 @@ static uiLayout *draw_constraint(uiLayout *layout, Object *ob, bConstraint *con,
        uiLayout *result= NULL, *col, *col1, *col2, *box, *row, *subrow, *split;
        PointerRNA ptr;
        char typestr[32];
-       short width = 265;
        short proxy_protected, xco=0, yco=0;
        int rb_col;
 
@@ -2444,13 +2443,13 @@ static void do_running_jobs(bContext *C, void *arg, int event)
                        G.afbreek= 1;
                        break;
                case B_STOPCAST:
-                       WM_jobs_stop(CTX_wm_manager(C), CTX_wm_screen(C));
+                       WM_jobs_stop(CTX_wm_manager(C), CTX_wm_screen(C), NULL);
                        break;
                case B_STOPANIM:
                        WM_operator_name_call(C, "SCREEN_OT_animation_play", WM_OP_INVOKE_SCREEN, NULL);
                        break;
                case B_STOPCOMPO:
-                       WM_jobs_stop(CTX_wm_manager(C), CTX_wm_area(C));
+                       WM_jobs_stop(CTX_wm_manager(C), CTX_wm_area(C), NULL);
                        break;
        }
 }
index 898a8f527c3c66a023a6a92343782a600cd989f6..ae2462b95f84d5388a913612e60bc798df9df455 100644 (file)
@@ -1153,4 +1153,10 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, M
        WM_jobs_start(CTX_wm_manager(C), steve);
 }
 
+void ED_preview_kill_jobs(const struct bContext *C)
+{
+       wmWindowManager *wm= CTX_wm_manager(C);
+       if(wm)
+               WM_jobs_kill(wm, NULL, common_preview_startjob);
+}
 
index 5e4887827b6f6b0393cf3d30d586d9a55694fc28..37653d616c4a8b8b3665d464cb3811e575fc1c75 100644 (file)
@@ -1360,7 +1360,7 @@ void thumbnails_start(struct FileList* filelist, const struct bContext* C)
 
 void thumbnails_stop(struct FileList* filelist, const struct bContext* C)
 {
-       WM_jobs_kill(CTX_wm_manager(C), filelist);
+       WM_jobs_kill(CTX_wm_manager(C), filelist, NULL);
 }
 
 int thumbnails_running(struct FileList* filelist, const struct bContext* C)
index 222504179cb43354031145f08f91504165adac7c..cea88c33c5b98a887ef578051f785f020b4c0cdf 100644 (file)
@@ -66,6 +66,7 @@
 
 #include "ED_node.h"
 #include "ED_screen.h"
+#include "ED_render.h"
 
 #include "RNA_access.h"
 #include "RNA_define.h"
@@ -549,6 +550,8 @@ static int node_group_edit_exec(bContext *C, wmOperator *op)
        SpaceNode *snode = CTX_wm_space_node(C);
        bNode *gnode;
 
+       ED_preview_kill_jobs(C);
+
        gnode= nodeGetActive(snode->edittree);
        snode_make_group_editable(snode, gnode);
 
@@ -594,6 +597,8 @@ static int node_group_ungroup_exec(bContext *C, wmOperator *op)
        SpaceNode *snode = CTX_wm_space_node(C);
        bNode *gnode;
 
+       ED_preview_kill_jobs(C);
+
        /* are we inside of a group? */
        gnode= node_tree_get_editgroup(snode->nodetree);
        if(gnode)
@@ -1099,13 +1104,16 @@ static int node_active_link_viewer(bContext *C, wmOperator *op)
        SpaceNode *snode= CTX_wm_space_node(C);
        bNode *node;
        
-       
        node= editnode_get_active(snode->edittree);
        
-       if(node) {
-               node_link_viewer(snode, node);
-               snode_notify(C, snode);
-       }
+       if(!node)
+               return OPERATOR_CANCELLED;
+
+       ED_preview_kill_jobs(C);
+
+       node_link_viewer(snode, node);
+       snode_notify(C, snode);
+
        return OPERATOR_FINISHED;
 }
 
@@ -1467,6 +1475,8 @@ static int node_duplicate_exec(bContext *C, wmOperator *op)
 {
        SpaceNode *snode= CTX_wm_space_node(C);
        
+       ED_preview_kill_jobs(C);
+
        ntreeCopyTree(snode->edittree, 1);      /* 1 == internally selected nodes */
        
        ntreeSolveOrder(snode->edittree);
@@ -1625,7 +1635,7 @@ static int node_link_modal(bContext *C, wmOperator *op, wmEvent *event)
 static int node_link_init(SpaceNode *snode, NodeLinkDrag *nldrag)
 {
        bNodeLink *link;
-       
+
        /* output indicated? */
        if(find_indicated_socket(snode, &nldrag->node, &nldrag->sock, SOCK_OUT)) {
                if(nodeCountSocketLinks(snode->edittree, nldrag->sock) < nldrag->sock->limit)
@@ -1679,6 +1689,8 @@ static int node_link_invoke(bContext *C, wmOperator *op, wmEvent *event)
        UI_view2d_region_to_view(&ar->v2d, event->x - ar->winrct.xmin, event->y - ar->winrct.ymin, 
                                                         &snode->mx, &snode->my);
 
+       ED_preview_kill_jobs(C);
+
        nldrag->in_out= node_link_init(snode, nldrag);
                
        if(nldrag->in_out) {
@@ -1725,6 +1737,8 @@ static int node_make_link_exec(bContext *C, wmOperator *op)
        SpaceNode *snode= CTX_wm_space_node(C);
        int replace = RNA_boolean_get(op->ptr, "replace");
 
+       ED_preview_kill_jobs(C);
+
        snode_autoconnect(snode, 0, replace);
 
        node_tree_verify_groups(snode->nodetree);
@@ -1788,6 +1802,8 @@ static int cut_links_exec(bContext *C, wmOperator *op)
        
        if(i>1) {
                bNodeLink *link, *next;
+
+               ED_preview_kill_jobs(C);
                
                for(link= snode->edittree->links.first; link; link= next) {
                        next= link->next;
@@ -1840,6 +1856,8 @@ static int node_read_renderlayers_exec(bContext *C, wmOperator *op)
        Scene *curscene= CTX_data_scene(C), *scene;
        bNode *node;
 
+       ED_preview_kill_jobs(C);
+
        /* first tag scenes unread */
        for(scene= G.main->scene.first; scene; scene= scene->id.next) 
                scene->id.flag |= LIB_DOIT;
@@ -1956,6 +1974,8 @@ static int node_group_make_exec(bContext *C, wmOperator *op)
                        return OPERATOR_CANCELLED;
                }
        }
+
+       ED_preview_kill_jobs(C);
        
        gnode= nodeMakeGroupFromSelected(snode->nodetree);
        if(gnode==NULL) {
@@ -2058,6 +2078,8 @@ static int node_preview_exec(bContext *C, wmOperator *op)
        if((snode == NULL) || (snode->edittree == NULL))
                return OPERATOR_CANCELLED;
 
+       ED_preview_kill_jobs(C);
+
        node_flag_toggle_exec(snode, NODE_PREVIEW);
 
        snode_notify(C, snode);
@@ -2090,6 +2112,8 @@ static int node_socket_toggle_exec(bContext *C, wmOperator *op)
        if((snode == NULL) || (snode->edittree == NULL))
                return OPERATOR_CANCELLED;
 
+       ED_preview_kill_jobs(C);
+
        for(node= snode->edittree->nodes.first; node; node= node->next) {
                if(node->flag & SELECT) {
                        if(node_has_hidden_sockets(node)) {
@@ -2138,6 +2162,8 @@ static int node_mute_exec(bContext *C, wmOperator *op)
        if(node_tree_get_editgroup(snode->nodetree))
                return OPERATOR_CANCELLED;
        
+       ED_preview_kill_jobs(C);
+
        for(node= snode->edittree->nodes.first; node; node= node->next) {
                if(node->flag & SELECT) {
                        if(node->inputs.first && node->outputs.first) {
@@ -2174,6 +2200,8 @@ static int node_delete_exec(bContext *C, wmOperator *op)
        SpaceNode *snode= CTX_wm_space_node(C);
        bNode *node, *next;
        
+       ED_preview_kill_jobs(C);
+
        for(node= snode->edittree->nodes.first; node; node= next) {
                next= node->next;
                if(node->flag & SELECT) {
@@ -2275,6 +2303,8 @@ static int node_add_file_exec(bContext *C, wmOperator *op)
        
        if (snode->nodetree->type==NTREE_COMPOSIT)
                ntype = CMP_NODE_IMAGE;
+
+       ED_preview_kill_jobs(C);
        
        node = node_add_node(snode, scene, ntype, snode->mx, snode->my);
        
index 235be838f633968f4be58927f4e85d3e0f3b3857..78ea0350667c415e724d124e9b4711e75631c3bc 100644 (file)
@@ -325,8 +325,8 @@ void                WM_jobs_callbacks(struct wmJob *,
                                                          void (*endjob)(void *));
 
 void           WM_jobs_start(struct wmWindowManager *wm, struct wmJob *);
-void           WM_jobs_stop(struct wmWindowManager *wm, void *owner);
-void           WM_jobs_kill(struct wmWindowManager *wm, void *owner);
+void           WM_jobs_stop(struct wmWindowManager *wm, void *owner, void *startjob);
+void           WM_jobs_kill(struct wmWindowManager *wm, void *owner, void *startjob);
 void           WM_jobs_stop_all(struct wmWindowManager *wm);
 
                        /* clipboard */
index c3ad8f96cb081129c6ef6ea081d57231f781d631..80f1c6809314bf741f8a7d0315eb27bd38374206 100644 (file)
@@ -339,28 +339,25 @@ void WM_jobs_stop_all(wmWindowManager *wm)
        
 }
 
-/* signal job(s) from this owner to stop, timer is required to get handled */
-void WM_jobs_stop(wmWindowManager *wm, void *owner)
+/* signal job(s) from this owner or callback to stop, timer is required to get handled */
+void WM_jobs_stop(wmWindowManager *wm, void *owner, void *startjob)
 {
        wmJob *steve;
        
        for(steve= wm->jobs.first; steve; steve= steve->next)
-               if(steve->owner==owner)
+               if(steve->owner==owner || steve->startjob==startjob)
                        if(steve->running)
                                steve->stop= 1;
 }
 
 /* actually terminate thread and job timer */
-void WM_jobs_kill(wmWindowManager *wm, void *owner)
+void WM_jobs_kill(wmWindowManager *wm, void *owner, void *startjob)
 {
        wmJob *steve;
        
        for(steve= wm->jobs.first; steve; steve= steve->next)
-               if(steve->owner==owner)
-                       break;
-       
-       if (steve) 
-               wm_jobs_kill_job(wm, steve);
+               if(steve->owner==owner || steve->startjob==startjob)
+                       wm_jobs_kill_job(wm, steve);
 }