summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Keller <rainer.keller@nokia.com>2011-03-24 09:07:19 +0100
committerRainer Keller <rainer.keller@nokia.com>2011-04-18 09:19:09 +0200
commit05d759483946e96655fae86cc92645ef06ead127 (patch)
tree10cdbb1960a4e4ac37413059fd928ce9acc53b12
parentfdcce1e1803644c669bc07515e56457eabac2b01 (diff)
Workaround for superfluous shared memory segments
When the simulator application crashes shared memory segments are left unused. This patch checks on simulator startup for unused segments and deletes them. Reviewed-by: ckamm Task-number: QTSIM-73
-rw-r--r--src/main.cpp47
1 files changed, 47 insertions, 0 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 540fce7..3ce9aa0 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -37,6 +37,14 @@
#include "qsimulatordata_p.h"
#include "messaging.h"
+#ifdef Q_OS_UNIX
+ extern "C" {
+ #include <sys/types.h>
+ #include <sys/ipc.h>
+ #include <sys/shm.h>
+ }
+#endif
+
#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QSettings>
@@ -99,8 +107,47 @@ static void registerSimulator(const QString &location)
settings->setValue(dataKey, appDataLocation);
}
+void cleanupUnusedSharedMemory()
+{
+#ifdef Q_OS_UNIX
+ // This code depends on the implementation of QSharedMemory
+ QDir tmp(QDir::tempPath());
+ QStringList possibleFiles = tmp.entryList(QStringList("qipc_sharedmemory_QTSIMULATORSHAREDMEMORY*"), QDir::Files);
+
+ foreach (QString fileName, possibleFiles) {
+ int unix_key = ::ftok(QFile::encodeName(tmp.absoluteFilePath(fileName)).constData(), 'Q');
+
+ // Get the number of current attachments
+ int id = ::shmget(unix_key, 0, 0444);
+
+ struct shmid_ds shmid_ds;
+ if (0 != ::shmctl(id, IPC_STAT, &shmid_ds)) {
+ qWarning("getting the number of current attachments failed");
+ continue;
+ }
+
+ // If there are no attachments then remove it.
+ if (shmid_ds.shm_nattch == 0) {
+ // mark for removal
+ if (-1 == ::shmctl(id, IPC_RMID, &shmid_ds)) {
+ qWarning("mark shared memory segment for removal failed");
+ continue;
+ }
+
+ // remove file
+ if (!tmp.remove(fileName)) {
+ qWarning("could not remove shared memory segment 'file'");
+ continue;
+ }
+ qDebug() << "superfluous shared memory segment removed";
+ }
+ }
+#endif
+}
int main(int argc, char **argv)
{
+ cleanupUnusedSharedMemory();
+
QCoreApplication::setOrganizationName(SIMULATOR_APP_VENDOR);
QCoreApplication::setApplicationName(SIMULATOR_APP_NAME);