Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2016-07-06 14:58:47 +0300
committerCampbell Barton <ideasman42@gmail.com>2016-07-06 14:58:47 +0300
commitb98b331d04fe3a335cc0656809b4b09196507500 (patch)
treee11e1bbf5d1c046ec93013015f511363d1f6e72e /source
parent95ff9e9904d1f31d9352220a8779b4ef35c16bd8 (diff)
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.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenloader/intern/writefile.c45
1 files changed, 20 insertions, 25 deletions
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 19fb80ffb66..7933f5450f3 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);
}