summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@nokia.com>2010-12-13 14:02:27 (GMT)
committerThiago Macieira <thiago.macieira@nokia.com>2010-12-13 14:44:19 (GMT)
commitbd9d5c80235ce6d1b005df96c3058b75e82bd6f0 (patch)
tree1467ba66629b21fcdf5dc136e3fefea91a3c6f8f /src/corelib
parenta02a747a9d5294127dfe3e676a2759e228257e70 (diff)
downloadQt-bd9d5c80235ce6d1b005df96c3058b75e82bd6f0.zip
Qt-bd9d5c80235ce6d1b005df96c3058b75e82bd6f0.tar.gz
Qt-bd9d5c80235ce6d1b005df96c3058b75e82bd6f0.tar.bz2
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
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/kernel/qabstracteventdispatcher.cpp14
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