diff options
author | Campbell Barton <ideasman42@gmail.com> | 2014-12-10 13:06:00 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2014-12-10 13:16:42 +0300 |
commit | 602250d9fe796ff5e762a4880a0be97ef3f4b139 (patch) | |
tree | 5fce5daba548ca93990d87303480ea913b3acb93 /source/blender/blenkernel/intern/CCGSubSurf.c | |
parent | 47788b5e68b7b0f2b7a061a1dae8f4b1995b67e2 (diff) |
Fix T42748: Crash in subsurf, threaded access
Allocating the iterator from a BLI_memarena wasn't threadsafe.
Change the API to use stack memory for iterators.
Thanks to @mont29 for finding exact cause of the bug.
Diffstat (limited to 'source/blender/blenkernel/intern/CCGSubSurf.c')
-rw-r--r-- | source/blender/blenkernel/intern/CCGSubSurf.c | 42 |
1 files changed, 10 insertions, 32 deletions
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c index 623fb50b62c..9e5d4afffe2 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf.c +++ b/source/blender/blenkernel/intern/CCGSubSurf.c @@ -172,29 +172,19 @@ static void *_ehash_lookup(EHash *eh, void *key) /**/ -typedef struct _EHashIterator { - EHash *eh; - int curBucket; - EHEntry *curEntry; -} EHashIterator; - -static EHashIterator *_ehashIterator_new(EHash *eh) +static void _ehashIterator_init(EHash *eh, EHashIterator *ehi) { - EHashIterator *ehi = EHASH_alloc(eh, sizeof(*ehi)); + /* fill all members */ ehi->eh = eh; - ehi->curEntry = NULL; ehi->curBucket = -1; + ehi->curEntry = NULL; + while (!ehi->curEntry) { ehi->curBucket++; if (ehi->curBucket == ehi->eh->curSize) break; ehi->curEntry = ehi->eh->buckets[ehi->curBucket]; } - return ehi; -} -static void _ehashIterator_free(EHashIterator *ehi) -{ - EHASH_free(ehi->eh, ehi); } static void *_ehashIterator_getCurrent(EHashIterator *ehi) @@ -3051,17 +3041,17 @@ void *ccgSubSurf_getFaceGridData(CCGSubSurf *ss, CCGFace *f, int gridIndex, int /*** External API iterator functions ***/ -CCGVertIterator *ccgSubSurf_getVertIterator(CCGSubSurf *ss) +void ccgSubSurf_initVertIterator(CCGSubSurf *ss, CCGVertIterator *viter) { - return (CCGVertIterator *) _ehashIterator_new(ss->vMap); + _ehashIterator_init(ss->vMap, viter); } -CCGEdgeIterator *ccgSubSurf_getEdgeIterator(CCGSubSurf *ss) +void ccgSubSurf_initEdgeIterator(CCGSubSurf *ss, CCGEdgeIterator *eiter) { - return (CCGEdgeIterator *) _ehashIterator_new(ss->eMap); + _ehashIterator_init(ss->eMap, eiter); } -CCGFaceIterator *ccgSubSurf_getFaceIterator(CCGSubSurf *ss) +void ccgSubSurf_initFaceIterator(CCGSubSurf *ss, CCGFaceIterator *fiter) { - return (CCGFaceIterator *) _ehashIterator_new(ss->fMap); + _ehashIterator_init(ss->fMap, fiter); } CCGVert *ccgVertIterator_getCurrent(CCGVertIterator *vi) @@ -3076,10 +3066,6 @@ void ccgVertIterator_next(CCGVertIterator *vi) { _ehashIterator_next((EHashIterator *) vi); } -void ccgVertIterator_free(CCGVertIterator *vi) -{ - _ehashIterator_free((EHashIterator *) vi); -} CCGEdge *ccgEdgeIterator_getCurrent(CCGEdgeIterator *vi) { @@ -3093,10 +3079,6 @@ void ccgEdgeIterator_next(CCGEdgeIterator *vi) { _ehashIterator_next((EHashIterator *) vi); } -void ccgEdgeIterator_free(CCGEdgeIterator *vi) -{ - _ehashIterator_free((EHashIterator *) vi); -} CCGFace *ccgFaceIterator_getCurrent(CCGFaceIterator *vi) { @@ -3110,10 +3092,6 @@ void ccgFaceIterator_next(CCGFaceIterator *vi) { _ehashIterator_next((EHashIterator *) vi); } -void ccgFaceIterator_free(CCGFaceIterator *vi) -{ - _ehashIterator_free((EHashIterator *) vi); -} /*** Extern API final vert/edge/face interface ***/ |