[Bf-blender-cvs] [b98b331] master: writefile: simplify outliner treestore workaround

Campbell Barton noreply at git.blender.org
Wed Jul 6 13:59:21 CEST 2016


Commit: b98b331d04fe3a335cc0656809b4b09196507500
Author: Campbell Barton
Date:   Wed Jul 6 21:58:47 2016 +1000
Branches: master
https://developer.blender.org/rBb98b331d04fe3a335cc0656809b4b09196507500

writefile: simplify outliner treestore workaround

Instead of keeping a list of allocations, write to unique addresses
based on the BLI_mempool address since we know this is unique.

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

M	source/blender/blenloader/intern/writefile.c

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

diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 19fb80f..7933f54 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -2911,43 +2911,41 @@ static void write_uilist(WriteData *wd, uiList *ui_list)
 	}
 }
 
-static void write_soops(WriteData *wd, SpaceOops *so, LinkNode **tmp_mem_list)
+static void write_soops(WriteData *wd, SpaceOops *so)
 {
 	BLI_mempool *ts = so->treestore;
 
 	if (ts) {
+		SpaceOops so_flat = *so;
+
 		int elems = BLI_mempool_count(ts);
 		/* linearize mempool to array */
 		TreeStoreElem *data = elems ? BLI_mempool_as_arrayN(ts, "TreeStoreElem") : NULL;
 
 		if (data) {
-			TreeStore *ts_flat = MEM_callocN(sizeof(TreeStore), "TreeStore");
+			/* In this block we use the memory location of the treestore
+			 * but _not_ its data, the addresses in this case are UUID's,
+			 * since we can't rely on malloc giving us different values each time.
+			 */
+			TreeStore ts_flat = {0};
 
-			ts_flat->usedelem = elems;
-			ts_flat->totelem = elems;
-			ts_flat->data = data;
+			/* we know the treestore is at least as big as a pointer,
+			 * so offsetting works to give us a UUID. */
+			void *data_addr = (void *)POINTER_OFFSET(ts, sizeof(void *));
 
-			/* temporarily replace mempool-treestore by flat-treestore */
-			so->treestore = (BLI_mempool *)ts_flat;
-			writestruct(wd, DATA, SpaceOops, 1, so);
+			ts_flat.usedelem = elems;
+			ts_flat.totelem = elems;
+			ts_flat.data = data_addr;
 
-			writestruct(wd, DATA, TreeStore, 1, ts_flat);
-			writestruct(wd, DATA, TreeStoreElem, elems, data);
+			writestruct(wd, DATA, SpaceOops, 1, so);
 
-			/* we do not free the pointers immediately, because if we have multiple
-			 * outliners in a screen we might get the same address on the next
-			 * malloc, which makes the address no longer unique and so invalid for
-			 * lookups on file read, causing crashes or double frees */
-			BLI_linklist_prepend(tmp_mem_list, ts_flat);
-			BLI_linklist_prepend(tmp_mem_list, data);
+			writestruct_at_address(wd, DATA, TreeStore, 1, ts, &ts_flat);
+			writestruct_at_address(wd, DATA, TreeStoreElem, elems, data_addr, data);
 		}
 		else {
-			so->treestore = NULL;
-			writestruct(wd, DATA, SpaceOops, 1, so);
+			so_flat.treestore = NULL;
+			writestruct_at_address(wd, DATA, SpaceOops, 1, so, &so_flat);
 		}
-
-		/* restore old treestore */
-		so->treestore = ts;
 	}
 	else {
 		writestruct(wd, DATA, SpaceOops, 1, so);
@@ -2960,7 +2958,6 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
 	ScrArea *sa;
 	ScrVert *sv;
 	ScrEdge *se;
-	LinkNode *tmp_mem_list = NULL;
 
 	sc = scrbase->first;
 	while (sc) {
@@ -3064,7 +3061,7 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
 				}
 				else if (sl->spacetype == SPACE_OUTLINER) {
 					SpaceOops *so = (SpaceOops *)sl;
-					write_soops(wd, so, &tmp_mem_list);
+					write_soops(wd, so);
 				}
 				else if (sl->spacetype == SPACE_IMAGE) {
 					writestruct(wd, DATA, SpaceImage, 1, sl);
@@ -3132,8 +3129,6 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
 		sc = sc->id.next;
 	}
 
-	BLI_linklist_freeN(tmp_mem_list);
-
 	/* flush helps the compression for undo-save */
 	mywrite(wd, MYWRITE_FLUSH, 0);
 }




More information about the Bf-blender-cvs mailing list