From bd9d5c80235ce6d1b005df96c3058b75e82bd6f0 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 13 Dec 2010 15:02:27 +0100 Subject: Add a small protection against releasing a timer twice. The cell corresponding to an allocated timer ID in the free list is unused (because the ID isn't free). So use it to store an invalid value that we can check against the user's value. This provides some protection against a given timer being released twice. Since we store the serial counter of the nextFreeTimerId, getting the same ID twice is a 1-in-128 chance. Reviewed-By: Bradley T. Hughes --- src/corelib/kernel/qabstracteventdispatcher.cpp | 14 ++++++++++++-- 1 file 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 -- cgit v0.12