[Bf-blender-cvs] [1d17e18] wiggly-widgets: Fix mem leak with selected widgets, possible other mem leaks, cleanup mem freeing

Julian Eisel noreply at git.blender.org
Tue Mar 8 21:34:33 CET 2016


Commit: 1d17e186898987626ce5aa60d41b7949e38d661e
Author: Julian Eisel
Date:   Tue Mar 8 21:33:05 2016 +0100
Branches: wiggly-widgets
https://developer.blender.org/rB1d17e186898987626ce5aa60d41b7949e38d661e

Fix mem leak with selected widgets, possible other mem leaks, cleanup mem freeing

===================================================================

M	source/blender/windowmanager/widgets/intern/wm_widget.c
M	source/blender/windowmanager/widgets/intern/wm_widget_intern.h
M	source/blender/windowmanager/widgets/intern/wm_widgetgroup.c
M	source/blender/windowmanager/widgets/intern/wm_widgetmap.c

===================================================================

diff --git a/source/blender/windowmanager/widgets/intern/wm_widget.c b/source/blender/windowmanager/widgets/intern/wm_widget.c
index e60535d..520c9ba 100644
--- a/source/blender/windowmanager/widgets/intern/wm_widget.c
+++ b/source/blender/windowmanager/widgets/intern/wm_widget.c
@@ -329,8 +329,7 @@ void wm_widget_deselect(const bContext *C, wmWidgetMap *wmap, wmWidget *widget)
 
 	/* update array data */
 	if ((*tot_selected) <= 1) {
-		MEM_SAFE_FREE(*sel);
-		*tot_selected = 0;
+		wm_widgetmap_selected_delete(wmap);
 	}
 	else {
 		*sel = MEM_reallocN(*sel, sizeof(**sel) * (*tot_selected));
@@ -356,7 +355,7 @@ void wm_widget_select(bContext *C, wmWidgetMap *wmap, wmWidget *widget)
 
 	(*tot_selected)++;
 
-	*sel = MEM_reallocN(*sel, sizeof(**sel) * (*tot_selected));
+	*sel = MEM_reallocN(*sel, sizeof(wmWidget *) * (*tot_selected));
 	(*sel)[(*tot_selected) - 1] = widget;
 
 	widget->flag |= WM_WIDGET_SELECTED;
diff --git a/source/blender/windowmanager/widgets/intern/wm_widget_intern.h b/source/blender/windowmanager/widgets/intern/wm_widget_intern.h
index 1cee292..0cd4760 100644
--- a/source/blender/windowmanager/widgets/intern/wm_widget_intern.h
+++ b/source/blender/windowmanager/widgets/intern/wm_widget_intern.h
@@ -73,6 +73,8 @@ enum {
 	TWEAK_MODAL_PRECISION_OFF,
 };
 
+void wm_widgetgroup_free(bContext *C, wmWidgetMap *wmap, struct wmWidgetGroup *wgroup);
+
 void wm_widgetgrouptype_keymap_init(struct wmWidgetGroupType *wgrouptype, struct wmKeyConfig *keyconf);
 
 
@@ -95,6 +97,8 @@ typedef struct wmWidgetMapType {
 	ListBase widgetgrouptypes;
 } wmWidgetMapType;
 
+void wm_widgetmap_selected_delete(wmWidgetMap *wmap);
+
 
 /* -------------------------------------------------------------------- */
 /* Widget drawing */
diff --git a/source/blender/windowmanager/widgets/intern/wm_widgetgroup.c b/source/blender/windowmanager/widgets/intern/wm_widgetgroup.c
index de8945b..622629e 100644
--- a/source/blender/windowmanager/widgets/intern/wm_widgetgroup.c
+++ b/source/blender/windowmanager/widgets/intern/wm_widgetgroup.c
@@ -61,7 +61,7 @@
  *
  * \{ */
 
-static void wm_widgetgroup_free(bContext *C, wmWidgetMap *wmap, wmWidgetGroup *wgroup)
+void wm_widgetgroup_free(bContext *C, wmWidgetMap *wmap, wmWidgetGroup *wgroup)
 {
 	for (wmWidget *widget = wgroup->widgets.first; widget;) {
 		wmWidget *widget_next = widget->next;
@@ -74,6 +74,7 @@ static void wm_widgetgroup_free(bContext *C, wmWidgetMap *wmap, wmWidgetGroup *w
 		wm_widget_delete(&wgroup->widgets, widget);
 		widget = widget_next;
 	}
+	BLI_assert(BLI_listbase_is_empty(&wgroup->widgets));
 
 #ifdef WITH_PYTHON
 	if (wgroup->py_instance) {
diff --git a/source/blender/windowmanager/widgets/intern/wm_widgetmap.c b/source/blender/windowmanager/widgets/intern/wm_widgetmap.c
index b136200..0496e72 100644
--- a/source/blender/windowmanager/widgets/intern/wm_widgetmap.c
+++ b/source/blender/windowmanager/widgets/intern/wm_widgetmap.c
@@ -92,22 +92,24 @@ wmWidgetMap *WM_widgetmap_from_type(const struct wmWidgetMapType_Params *wmap_pa
 	return wmap;
 }
 
+void wm_widgetmap_selected_delete(wmWidgetMap *wmap)
+{
+	MEM_SAFE_FREE(wmap->wmap_context.selected_widgets);
+	wmap->wmap_context.tot_selected = 0;
+}
+
 void WM_widgetmap_delete(wmWidgetMap *wmap)
 {
 	if (!wmap)
 		return;
 
-	for (wmWidgetGroup *wgroup = wmap->widgetgroups.first; wgroup; wgroup = wgroup->next) {
-		for (wmWidget *widget = wgroup->widgets.first; widget;) {
-			wmWidget *widget_next = widget->next;
-			wm_widget_delete(&wgroup->widgets, widget);
-			widget = widget_next;
-		}
+	for (wmWidgetGroup *wgroup = wmap->widgetgroups.first, *wgroup_next; wgroup; wgroup = wgroup_next) {
+		wgroup_next = wgroup->next;
+		wm_widgetgroup_free(NULL, wmap, wgroup);
 	}
-	BLI_freelistN(&wmap->widgetgroups);
+	BLI_assert(BLI_listbase_is_empty(&wmap->widgetgroups));
 
-	/* XXX shouldn't widgets in wmap_context.selected_widgets be freed here? */
-	MEM_SAFE_FREE(wmap->wmap_context.selected_widgets);
+	wm_widgetmap_selected_delete(wmap);
 
 	MEM_freeN(wmap);
 }
@@ -244,8 +246,7 @@ void WM_widgetmap_widgets_update(const bContext *C, wmWidgetMap *wmap)
 				if (sel_old->flag & WM_WIDGET_HIGHLIGHT) {
 					widget_highlight_update(wmap, sel_old, sel_new);
 				}
-				wm_widget_data_free(sel_old);
-				/* XXX freeing sel_old leads to crashes, hrmpf */
+				wm_widget_delete(NULL, sel_old);
 
 				sel_new->flag |= WM_WIDGET_SELECTED;
 				wmap->wmap_context.selected_widgets[i] = sel_new;
@@ -516,8 +517,7 @@ bool wm_widgetmap_deselect_all(wmWidgetMap *wmap, wmWidget ***sel)
 		(*sel)[i]->flag &= ~WM_WIDGET_SELECTED;
 		(*sel)[i] = NULL;
 	}
-	MEM_SAFE_FREE(*sel);
-	wmap->wmap_context.tot_selected = 0;
+	wm_widgetmap_selected_delete(wmap);
 
 	/* always return true, we already checked
 	 * if there's anything to deselect */
@@ -710,7 +710,7 @@ wmWidget *wm_widgetmap_get_highlighted_widget(wmWidgetMap *wmap)
 
 void wm_widgetmap_set_active_widget(wmWidgetMap *wmap, bContext *C, const wmEvent *event, wmWidget *widget)
 {
-	if (widget) {
+	if (widget && C) {
 		widget->flag |= WM_WIDGET_ACTIVE;
 		wmap->wmap_context.active_widget = widget;
 
@@ -762,8 +762,10 @@ void wm_widgetmap_set_active_widget(wmWidgetMap *wmap, bContext *C, const wmEven
 		}
 		wmap->wmap_context.active_widget = NULL;
 
-		ED_region_tag_redraw(CTX_wm_region(C));
-		WM_event_add_mousemove(C);
+		if (C) {
+			ED_region_tag_redraw(CTX_wm_region(C));
+			WM_event_add_mousemove(C);
+		}
 	}
 }




More information about the Bf-blender-cvs mailing list