summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel
diff options
context:
space:
mode:
authorBea Lam <bea.lam@nokia.com>2011-01-27 04:03:13 (GMT)
committerBea Lam <bea.lam@nokia.com>2011-01-27 04:03:13 (GMT)
commit05ba01a2519996a3dffaab2e498dc3d2a999dc45 (patch)
treec478929354b59407bea92e885baf0eecb4e351c8 /src/corelib/kernel
parentf15778e60ba538b8715f6433a472ffe08a21d934 (diff)
parent5c91e32a6238fd112a7282443214c8686cda51de (diff)
downloadQt-05ba01a2519996a3dffaab2e498dc3d2a999dc45.zip
Qt-05ba01a2519996a3dffaab2e498dc3d2a999dc45.tar.gz
Qt-05ba01a2519996a3dffaab2e498dc3d2a999dc45.tar.bz2
Merge branch '4.7' of scm.dev.nokia.troll.no:qt/qt-qml into qtquick11
Conflicts: src/declarative/graphicsitems/qdeclarativegridview.cpp src/declarative/graphicsitems/qdeclarativelistview.cpp
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r--src/corelib/kernel/qabstracteventdispatcher.cpp30
-rw-r--r--src/corelib/kernel/qsharedmemory.cpp6
-rw-r--r--src/corelib/kernel/qsharedmemory_unix.cpp14
-rw-r--r--src/corelib/kernel/qsharedmemory_win.cpp3
-rw-r--r--src/corelib/kernel/qsystemsemaphore_symbian.cpp4
-rw-r--r--src/corelib/kernel/qsystemsemaphore_win.cpp3
6 files changed, 35 insertions, 25 deletions
diff --git a/src/corelib/kernel/qabstracteventdispatcher.cpp b/src/corelib/kernel/qabstracteventdispatcher.cpp
index e79f87a..cc08f092 100644
--- a/src/corelib/kernel/qabstracteventdispatcher.cpp
+++ b/src/corelib/kernel/qabstracteventdispatcher.cpp
@@ -137,6 +137,12 @@ void QAbstractEventDispatcherPrivate::init()
// free list). As an added protection, we use the cell to store an invalid
// (negative) value that we can later check for integrity.
//
+// ABA prevention simply adds a value to 7 of the top 8 bits when resetting
+// nextFreeTimerId.
+//
+// The extra code is the bucket allocation which allows us to start with a
+// very small bucket size and grow as needed.
+//
// (continues below).
int QAbstractEventDispatcherPrivate::allocateTimerId()
{
@@ -164,6 +170,8 @@ int QAbstractEventDispatcherPrivate::allocateTimerId()
newTimerId = prepareNewValueWithSerialNumber(timerId, b[at]);
} while (!nextFreeTimerId.testAndSetRelaxed(timerId, newTimerId));
+ timerId &= TimerIdMask;
+ timerId |= b[at] & TimerSerialMask;
b[at] = -timerId;
return timerId;
@@ -174,12 +182,13 @@ int QAbstractEventDispatcherPrivate::allocateTimerId()
// X[timerId] = nextFreeTimerId;
// then we update nextFreeTimerId to the timer we've just released
//
-// The extra code in allocateTimerId and releaseTimerId are ABA prevention
-// and bucket memory. The buckets are simply to make sure we allocate only
-// the necessary number of timers. See above.
-//
// ABA prevention simply adds a value to 7 of the top 8 bits when resetting
// nextFreeTimerId.
+//
+// In addition to that, we update the same 7 bits in each entry in the bucket
+// as a counter. That way, a timer ID allocated and released will always be
+// returned with a different ID. This reduces the chances of timers being released
+// erroneously by application code.
void QAbstractEventDispatcherPrivate::releaseTimerId(int timerId)
{
int which = timerId & TimerIdMask;
@@ -187,12 +196,21 @@ void QAbstractEventDispatcherPrivate::releaseTimerId(int timerId)
int at = bucketIndex(bucket, which);
int *b = timerIds[bucket];
- Q_ASSERT(b[at] == -timerId);
+#ifndef QT_NO_DEBUG
+ // debug code
+ Q_ASSERT_X(timerId == -b[at], "QAbstractEventDispatcher::releaseTimerId", "Timer ID was not found, fix application");
+#else
+ if (timerId != -b[at]) {
+ // release code
+ qWarning("Timer ID %d was not found, fix application", timerId);
+ return;
+ }
+#endif
int freeId, newTimerId;
do {
freeId = nextFreeTimerId;//.loadAcquire(); // ### FIXME Proper memory ordering semantics
- b[at] = freeId & TimerIdMask;
+ b[at] = prepareNewValueWithSerialNumber(-b[at], freeId);
newTimerId = prepareNewValueWithSerialNumber(freeId, timerId);
} while (!nextFreeTimerId.testAndSetRelease(freeId, newTimerId));
diff --git a/src/corelib/kernel/qsharedmemory.cpp b/src/corelib/kernel/qsharedmemory.cpp
index 2fd6c50..85b37d0 100644
--- a/src/corelib/kernel/qsharedmemory.cpp
+++ b/src/corelib/kernel/qsharedmemory.cpp
@@ -399,11 +399,7 @@ bool QSharedMemory::detach()
return false;
#endif
- if (d->detach()) {
- d->size = 0;
- return true;
- }
- return false;
+ return d->detach();
}
/*!
diff --git a/src/corelib/kernel/qsharedmemory_unix.cpp b/src/corelib/kernel/qsharedmemory_unix.cpp
index bea5b63..ddb0e34 100644
--- a/src/corelib/kernel/qsharedmemory_unix.cpp
+++ b/src/corelib/kernel/qsharedmemory_unix.cpp
@@ -199,7 +199,7 @@ bool QSharedMemoryPrivate::create(int size)
}
// create
- if (-1 == shmget(handle(), size, 0666 | IPC_CREAT | IPC_EXCL)) {
+ if (-1 == shmget(unix_key, size, 0666 | IPC_CREAT | IPC_EXCL)) {
QString function = QLatin1String("QSharedMemory::create");
switch (errno) {
case EINVAL:
@@ -220,10 +220,7 @@ bool QSharedMemoryPrivate::create(int size)
bool QSharedMemoryPrivate::attach(QSharedMemory::AccessMode mode)
{
// grab the shared memory segment id
- if (!handle())
- return false;
-
- int id = shmget(handle(), 0, (mode == QSharedMemory::ReadOnly ? 0444 : 0660));
+ int id = shmget(unix_key, 0, (mode == QSharedMemory::ReadOnly ? 0444 : 0660));
if (-1 == id) {
setErrorString(QLatin1String("QSharedMemory::attach (shmget)"));
return false;
@@ -265,12 +262,11 @@ bool QSharedMemoryPrivate::detach()
return false;
}
memory = 0;
+ size = 0;
// Get the number of current attachments
- if (!handle())
- return false;
- int id = shmget(handle(), 0, 0444);
- unix_key = 0;
+ int id = shmget(unix_key, 0, 0444);
+ cleanHandle();
struct shmid_ds shmid_ds;
if (0 != shmctl(id, IPC_STAT, &shmid_ds)) {
diff --git a/src/corelib/kernel/qsharedmemory_win.cpp b/src/corelib/kernel/qsharedmemory_win.cpp
index 85600a2..ac9c86a 100644
--- a/src/corelib/kernel/qsharedmemory_win.cpp
+++ b/src/corelib/kernel/qsharedmemory_win.cpp
@@ -124,8 +124,8 @@ bool QSharedMemoryPrivate::cleanHandle()
{
if (hand != 0 && !CloseHandle(hand)) {
hand = 0;
- return false;
setErrorString(QLatin1String("QSharedMemory::cleanHandle"));
+ return false;
}
hand = 0;
return true;
@@ -186,6 +186,7 @@ bool QSharedMemoryPrivate::detach()
return false;
}
memory = 0;
+ size = 0;
// close handle
return cleanHandle();
diff --git a/src/corelib/kernel/qsystemsemaphore_symbian.cpp b/src/corelib/kernel/qsystemsemaphore_symbian.cpp
index 07cfffc..0d257b8 100644
--- a/src/corelib/kernel/qsystemsemaphore_symbian.cpp
+++ b/src/corelib/kernel/qsystemsemaphore_symbian.cpp
@@ -73,6 +73,7 @@ void QSystemSemaphorePrivate::setErrorString(const QString &function, int err)
case KErrInUse:
errorString = QCoreApplication::tr("%1: out of resources", "QSystemSemaphore").arg(function);
error = QSystemSemaphore::OutOfResources;
+ break;
case KErrPermissionDenied:
errorString = QCoreApplication::tr("%1: permission denied", "QSystemSemaphore").arg(function);
error = QSystemSemaphore::PermissionDenied;
@@ -97,8 +98,7 @@ int QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode)
if (key.isEmpty())
return 0;
- QString safeName = makeKeyFileName();
- TPtrC name(qt_QString2TPtrC(safeName));
+ TPtrC name(qt_QString2TPtrC(fileName));
int err = KErrAlreadyExists;
int tryCount = 10;
// Sort out race conditions by retrying several times until existing handle is acquired.
diff --git a/src/corelib/kernel/qsystemsemaphore_win.cpp b/src/corelib/kernel/qsystemsemaphore_win.cpp
index 7f002f8..fad50f2 100644
--- a/src/corelib/kernel/qsystemsemaphore_win.cpp
+++ b/src/corelib/kernel/qsystemsemaphore_win.cpp
@@ -86,8 +86,7 @@ HANDLE QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode)
// Create it if it doesn't already exists.
if (semaphore == 0) {
- QString safeName = makeKeyFileName();
- semaphore = CreateSemaphore(0, initialValue, MAXLONG, (wchar_t*)safeName.utf16());
+ semaphore = CreateSemaphore(0, initialValue, MAXLONG, (wchar_t*)fileName.utf16());
if (semaphore == NULL)
setErrorString(QLatin1String("QSystemSemaphore::handle"));
}