diff options
Diffstat (limited to 'src/corelib/kernel/qabstracteventdispatcher.cpp')
-rw-r--r-- | src/corelib/kernel/qabstracteventdispatcher.cpp | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/src/corelib/kernel/qabstracteventdispatcher.cpp b/src/corelib/kernel/qabstracteventdispatcher.cpp index 002d360..bf675a7 100644 --- a/src/corelib/kernel/qabstracteventdispatcher.cpp +++ b/src/corelib/kernel/qabstracteventdispatcher.cpp @@ -132,18 +132,24 @@ void QAbstractEventDispatcherPrivate::init() // Allocating a timer ID involves taking the ID from // X[nextFreeTimerId] // updating nextFreeTimerId to this value and returning the old value +// +// When the timer ID is allocated, its cell in the vector is unused (it's a +// free list). As an added protection, we use the cell to store an invalid +// (negative) value that we can later check for integrity. +// // (continues below). int QAbstractEventDispatcherPrivate::allocateTimerId() { int timerId, newTimerId; + int at, *b; do { timerId = nextFreeTimerId; //.loadAcquire(); // ### FIXME Proper memory ordering semantics // which bucket are we looking in? int which = timerId & TimerIdMask; int bucket = bucketOffset(which); - int at = bucketIndex(bucket, which); - int *b = timerIds[bucket]; + at = bucketIndex(bucket, which); + b = timerIds[bucket]; if (!b) { // allocate a new bucket @@ -158,6 +164,8 @@ int QAbstractEventDispatcherPrivate::allocateTimerId() newTimerId = prepareNewValueWithSerialNumber(timerId, b[at]); } while (!nextFreeTimerId.testAndSetRelaxed(timerId, newTimerId)); + b[at] = -timerId; + return timerId; } @@ -179,6 +187,8 @@ void QAbstractEventDispatcherPrivate::releaseTimerId(int timerId) int at = bucketIndex(bucket, which); int *b = timerIds[bucket]; + Q_ASSERT(b[at] == -timerId); + int freeId, newTimerId; do { freeId = nextFreeTimerId;//.loadAcquire(); // ### FIXME Proper memory ordering semantics |