Fix a race in QFreeList

The _next variable need the acquire and release fence in next()
to synchronize with the equivalent operations in release() (which
already have the them)
The ordering on the _v[block] is not enough as this does not
synchronize the same object.

Task-number: QTBUG-58917
Change-Id: I17cc39e6791433348b6227363dbea92bcf03700d
Reviewed-by: David Faure <david.faure@kdab.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
bb10
Olivier Goffart 2017-02-16 15:52:00 +01:00 committed by Olivier Goffart (Woboq GmbH)
parent 0e3d6fe4f6
commit dd7f62059c
1 changed files with 2 additions and 2 deletions

View File

@ -237,7 +237,7 @@ inline int QFreeList<T, ConstantsType>::next()
int id, newid, at;
ElementType *v;
do {
id = _next.load();
id = _next.loadAcquire();
at = id & ConstantsType::IndexMask;
const int block = blockfor(at);
@ -254,7 +254,7 @@ inline int QFreeList<T, ConstantsType>::next()
}
newid = v[at].next.load() | (id & ~ConstantsType::IndexMask);
} while (!_next.testAndSetRelaxed(id, newid));
} while (!_next.testAndSetRelease(id, newid));
// qDebug("QFreeList::next(): returning %d (_next now %d, serial %d)",
// id & ConstantsType::IndexMask,
// newid & ConstantsType::IndexMask,