diff options
author | Rainer Keller <rainer.keller@nokia.com> | 2011-03-24 09:07:19 +0100 |
---|---|---|
committer | Rainer Keller <rainer.keller@nokia.com> | 2011-04-18 09:19:09 +0200 |
commit | 05d759483946e96655fae86cc92645ef06ead127 (patch) | |
tree | 10cdbb1960a4e4ac37413059fd928ce9acc53b12 | |
parent | fdcce1e1803644c669bc07515e56457eabac2b01 (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.cpp | 47 |
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); |