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);
 }

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to