diff options
author | Thiago Macieira <thiago.macieira@nokia.com> | 2010-12-13 14:02:27 (GMT) |
---|---|---|
committer | Thiago Macieira <thiago.macieira@nokia.com> | 2010-12-13 14:44:19 (GMT) |
commit | bd9d5c80235ce6d1b005df96c3058b75e82bd6f0 (patch) | |
tree | 1467ba66629b21fcdf5dc136e3fefea91a3c6f8f | |
parent | a02a747a9d5294127dfe3e676a2759e228257e70 (diff) | |
download | Qt-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
-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 |