diff options
author | hjk <qtc-committer@nokia.com> | 2009-01-26 16:19:24 +0100 |
---|---|---|
committer | hjk <qtc-committer@nokia.com> | 2009-01-26 16:19:24 +0100 |
commit | fe0533de2a634ca377c2d8a0073e0eb2cbf89abf (patch) | |
tree | 29d3d30e6cc5a1068a94097a5660bc4d133a205f /src/shared/qtlockedfile | |
parent | c85ba53365d606192069a841ed806979f17d80bc (diff) | |
download | qt-creator-fe0533de2a634ca377c2d8a0073e0eb2cbf89abf.tar.gz |
Fixes: move all files in shared/* to src/shared/*
Diffstat (limited to 'src/shared/qtlockedfile')
-rw-r--r-- | src/shared/qtlockedfile/README.txt | 10 | ||||
-rw-r--r-- | src/shared/qtlockedfile/namespace.patch | 70 | ||||
-rw-r--r-- | src/shared/qtlockedfile/qtlockedfile.cpp | 162 | ||||
-rw-r--r-- | src/shared/qtlockedfile/qtlockedfile.h | 81 | ||||
-rw-r--r-- | src/shared/qtlockedfile/qtlockedfile.pri | 13 | ||||
-rw-r--r-- | src/shared/qtlockedfile/qtlockedfile_unix.cpp | 111 | ||||
-rw-r--r-- | src/shared/qtlockedfile/qtlockedfile_win.cpp | 207 |
7 files changed, 654 insertions, 0 deletions
diff --git a/src/shared/qtlockedfile/README.txt b/src/shared/qtlockedfile/README.txt new file mode 100644 index 0000000000..6fcf2fd295 --- /dev/null +++ b/src/shared/qtlockedfile/README.txt @@ -0,0 +1,10 @@ +This is the src directory of the QtLockedFile +solution integrated over from addons/main/utils/qtlockedfile/src . + +namespace.patch was applied to introduce the SharedTools namespace. + +It is required by the QtSingleApplication solution. + +History: + +16.05.2008 Integrated diff --git a/src/shared/qtlockedfile/namespace.patch b/src/shared/qtlockedfile/namespace.patch new file mode 100644 index 0000000000..eb894a3700 --- /dev/null +++ b/src/shared/qtlockedfile/namespace.patch @@ -0,0 +1,70 @@ + +--- qtlockedfile.cpp 1970-01-01 01:00:00.000000000 ++++ qtlockedfile.cpp 2008/05/16 10:51:19.000000000 +@@ -1,5 +1,7 @@ + #include "qtlockedfile.h" + ++namespace SharedTools { ++ + /*! + \class QtLockedFile + +@@ -123,3 +125,5 @@ + + Destroys the \e QtLockedFile object. If any locks were held, they are released. + */ ++ ++} + +--- qtlockedfile.h 1970-01-01 01:00:00.000000000 ++++ qtlockedfile.h 2008/05/16 10:51:19.000000000 +@@ -19,6 +19,8 @@ + # define QT_QTLOCKEDFILE_EXPORT + #endif + ++namespace SharedTools { ++ + class QT_QTLOCKEDFILE_EXPORT QtLockedFile : public QFile + { + public: +@@ -41,4 +43,6 @@ + LockMode m_lock_mode; + }; + ++} ++ + #endif + +--- qtlockedfile_unix.cpp 1970-01-01 01:00:00.000000000 ++++ qtlockedfile_unix.cpp 2008/05/16 10:51:19.000000000 +@@ -5,6 +5,8 @@ + + #include "qtlockedfile.h" + ++namespace SharedTools { ++ + bool QtLockedFile::lock(LockMode mode, bool block) + { + if (!isOpen()) { +@@ -73,3 +75,4 @@ + unlock(); + } + ++} + +--- qtlockedfile_win.cpp 1970-01-01 01:00:00.000000000 ++++ qtlockedfile_win.cpp 2008/05/16 10:51:19.000000000 +@@ -2,6 +2,8 @@ + #include <qt_windows.h> + #include <QtCore/QFileInfo> + ++namespace SharedTools { ++ + #define SEMAPHORE_PREFIX "QtLockedFile semaphore " + #define MUTEX_PREFIX "QtLockedFile mutex " + #define SEMAPHORE_MAX 100 +@@ -168,3 +170,4 @@ + } + } + ++} diff --git a/src/shared/qtlockedfile/qtlockedfile.cpp b/src/shared/qtlockedfile/qtlockedfile.cpp new file mode 100644 index 0000000000..fe2acfd612 --- /dev/null +++ b/src/shared/qtlockedfile/qtlockedfile.cpp @@ -0,0 +1,162 @@ +/*************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** +** Non-Open Source Usage +** +** Licensees may use this file in accordance with the Qt Beta Version +** License Agreement, Agreement version 2.2 provided with the Software or, +** alternatively, in accordance with the terms contained in a written +** agreement between you and Nokia. +** +** GNU General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the packaging +** of this file. Please review the following information to ensure GNU +** General Public Licensing requirements will be met: +** +** http://www.fsf.org/licensing/licenses/info/GPLv2.html and +** http://www.gnu.org/copyleft/gpl.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt GPL Exception +** version 1.3, included in the file GPL_EXCEPTION.txt in this package. +** +***************************************************************************/ + +#include "qtlockedfile.h" + +namespace SharedTools { + +/*! + \class QtLockedFile + + \brief The QtLockedFile class extends QFile with advisory locking functions. + + A file may be locked in read or write mode. Multiple instances of + \e QtLockedFile, created in multiple processes running on the same + machine, may have a file locked in read mode. Exactly one instance + may have it locked in write mode. A read and a write lock cannot + exist simultaneously on the same file. + + The file locks are advisory. This means that nothing prevents + another process from manipulating a locked file using QFile or + file system functions offered by the OS. Serialization is only + guaranteed if all processes that access the file use + QtLockedFile. Also, while holding a lock on a file, a process + must not open the same file again (through any API), or locks + can be unexpectedly lost. + + The lock provided by an instance of \e QtLockedFile is released + whenever the program terminates. This is true even when the + program crashes and no destructors are called. +*/ + +/*! \enum QtLockedFile::LockMode + + This enum describes the available lock modes. + + \value ReadLock A read lock. + \value WriteLock A write lock. + \value NoLock Neither a read lock nor a write lock. +*/ + +/*! + Constructs an unlocked \e QtLockedFile object. This constructor behaves in the same way + as \e QFile::QFile(). + + \sa QFile::QFile() +*/ +QtLockedFile::QtLockedFile() + : QFile() +{ +#ifdef Q_OS_WIN + m_semaphore_hnd = 0; + m_mutex_hnd = 0; +#endif + m_lock_mode = NoLock; +} + +/*! + Constructs an unlocked QtLockedFile object with file \a name. This constructor behaves in + the same way as \e QFile::QFile(const QString&). + + \sa QFile::QFile() +*/ +QtLockedFile::QtLockedFile(const QString &name) + : QFile(name) +{ +#ifdef Q_OS_WIN + m_semaphore_hnd = 0; + m_mutex_hnd = 0; +#endif + m_lock_mode = NoLock; +} + +/*! + Returns \e true if this object has a in read or write lock; + otherwise returns \e false. + + \sa lockMode() +*/ +bool QtLockedFile::isLocked() const +{ + return m_lock_mode != NoLock; +} + +/*! + Returns the type of lock currently held by this object, or \e QtLockedFile::NoLock. + + \sa isLocked() +*/ +QtLockedFile::LockMode QtLockedFile::lockMode() const +{ + return m_lock_mode; +} + +/*! + \fn bool QtLockedFile::lock(LockMode mode, bool block = true) + + Obtains a lock of type \a mode. + + If \a block is true, this + function will block until the lock is aquired. If \a block is + false, this function returns \e false immediately if the lock cannot + be aquired. + + If this object already has a lock of type \a mode, this function returns \e true immediately. If this object has a lock of a different type than \a mode, the lock + is first released and then a new lock is obtained. + + This function returns \e true if, after it executes, the file is locked by this object, + and \e false otherwise. + + \sa unlock(), isLocked(), lockMode() +*/ + +/*! + \fn bool QtLockedFile::unlock() + + Releases a lock. + + If the object has no lock, this function returns immediately. + + This function returns \e true if, after it executes, the file is not locked by + this object, and \e false otherwise. + + \sa lock(), isLocked(), lockMode() +*/ + +/*! + \fn QtLockedFile::~QtLockedFile() + + Destroys the \e QtLockedFile object. If any locks were held, they are released. +*/ + +} // namespace SharedTools diff --git a/src/shared/qtlockedfile/qtlockedfile.h b/src/shared/qtlockedfile/qtlockedfile.h new file mode 100644 index 0000000000..abf44fa452 --- /dev/null +++ b/src/shared/qtlockedfile/qtlockedfile.h @@ -0,0 +1,81 @@ +/*************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** +** Non-Open Source Usage +** +** Licensees may use this file in accordance with the Qt Beta Version +** License Agreement, Agreement version 2.2 provided with the Software or, +** alternatively, in accordance with the terms contained in a written +** agreement between you and Nokia. +** +** GNU General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the packaging +** of this file. Please review the following information to ensure GNU +** General Public Licensing requirements will be met: +** +** http://www.fsf.org/licensing/licenses/info/GPLv2.html and +** http://www.gnu.org/copyleft/gpl.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt GPL Exception +** version 1.3, included in the file GPL_EXCEPTION.txt in this package. +** +***************************************************************************/ + +#ifndef QTLOCKEDFILE_H +#define QTLOCKEDFILE_H + +#include <QtCore/QFile> + +#if defined(Q_WS_WIN) +# if !defined(QT_QTLOCKEDFILE_EXPORT) && !defined(QT_QTLOCKEDFILE_IMPORT) +# define QT_QTLOCKEDFILE_EXPORT +# elif defined(QT_QTLOCKEDFILE_IMPORT) +# if defined(QT_QTLOCKEDFILE_EXPORT) +# undef QT_QTLOCKEDFILE_EXPORT +# endif +# define QT_QTLOCKEDFILE_EXPORT __declspec(dllimport) +# elif defined(QT_QTLOCKEDFILE_EXPORT) +# undef QT_QTLOCKEDFILE_EXPORT +# define QT_QTLOCKEDFILE_EXPORT __declspec(dllexport) +# endif +#else +# define QT_QTLOCKEDFILE_EXPORT +#endif + +namespace SharedTools { + +class QT_QTLOCKEDFILE_EXPORT QtLockedFile : public QFile +{ +public: + enum LockMode { NoLock = 0, ReadLock, WriteLock }; + + QtLockedFile(); + QtLockedFile(const QString &name); + ~QtLockedFile(); + + bool lock(LockMode mode, bool block = true); + bool unlock(); + bool isLocked() const; + LockMode lockMode() const; + +private: +#ifdef Q_OS_WIN + Qt::HANDLE m_semaphore_hnd; + Qt::HANDLE m_mutex_hnd; +#endif + LockMode m_lock_mode; +}; + +} // namespace SharedTools + +#endif // QTLOCKEDFILE_H diff --git a/src/shared/qtlockedfile/qtlockedfile.pri b/src/shared/qtlockedfile/qtlockedfile.pri new file mode 100644 index 0000000000..46d1f1a12a --- /dev/null +++ b/src/shared/qtlockedfile/qtlockedfile.pri @@ -0,0 +1,13 @@ +INCLUDEPATH += $$PWD +DEPENDPATH += $$PWD +HEADERS += $$PWD/qtlockedfile.h +SOURCES += $$PWD/qtlockedfile.cpp + +unix:SOURCES += $$PWD/qtlockedfile_unix.cpp +win32:SOURCES += $$PWD/qtlockedfile_win.cpp + +win32:contains(TEMPLATE, lib):contains(CONFIG, shared) { + DEFINES += QT_QTLOCKEDFILE_EXPORT=__declspec(dllexport) +} + + diff --git a/src/shared/qtlockedfile/qtlockedfile_unix.cpp b/src/shared/qtlockedfile/qtlockedfile_unix.cpp new file mode 100644 index 0000000000..10ae8f69c3 --- /dev/null +++ b/src/shared/qtlockedfile/qtlockedfile_unix.cpp @@ -0,0 +1,111 @@ +/*************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** +** Non-Open Source Usage +** +** Licensees may use this file in accordance with the Qt Beta Version +** License Agreement, Agreement version 2.2 provided with the Software or, +** alternatively, in accordance with the terms contained in a written +** agreement between you and Nokia. +** +** GNU General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the packaging +** of this file. Please review the following information to ensure GNU +** General Public Licensing requirements will be met: +** +** http://www.fsf.org/licensing/licenses/info/GPLv2.html and +** http://www.gnu.org/copyleft/gpl.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt GPL Exception +** version 1.3, included in the file GPL_EXCEPTION.txt in this package. +** +***************************************************************************/ + +#include "qtlockedfile.h" + +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <fcntl.h> + +namespace SharedTools { + +bool QtLockedFile::lock(LockMode mode, bool block) +{ + if (!isOpen()) { + qWarning("QtLockedFile::lock(): file is not opened"); + return false; + } + + if (mode == NoLock) + return unlock(); + + if (mode == m_lock_mode) + return true; + + if (m_lock_mode != NoLock) + unlock(); + + struct flock fl; + fl.l_whence = SEEK_SET; + fl.l_start = 0; + fl.l_len = 0; + fl.l_type = (mode == ReadLock) ? F_RDLCK : F_WRLCK; + int cmd = block ? F_SETLKW : F_SETLK; + int ret = fcntl(handle(), cmd, &fl); + + if (ret == -1) { + if (errno != EINTR && errno != EAGAIN) + qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno)); + return false; + } + + + m_lock_mode = mode; + return true; +} + + +bool QtLockedFile::unlock() +{ + if (!isOpen()) { + qWarning("QtLockedFile::unlock(): file is not opened"); + return false; + } + + if (!isLocked()) + return true; + + struct flock fl; + fl.l_whence = SEEK_SET; + fl.l_start = 0; + fl.l_len = 0; + fl.l_type = F_UNLCK; + int ret = fcntl(handle(), F_SETLKW, &fl); + + if (ret == -1) { + qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno)); + return false; + } + + m_lock_mode = NoLock; + return true; +} + +QtLockedFile::~QtLockedFile() +{ + if (isOpen()) + unlock(); +} + +} // namespace SharedTools diff --git a/src/shared/qtlockedfile/qtlockedfile_win.cpp b/src/shared/qtlockedfile/qtlockedfile_win.cpp new file mode 100644 index 0000000000..f1d74e30fc --- /dev/null +++ b/src/shared/qtlockedfile/qtlockedfile_win.cpp @@ -0,0 +1,207 @@ +/*************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** +** Non-Open Source Usage +** +** Licensees may use this file in accordance with the Qt Beta Version +** License Agreement, Agreement version 2.2 provided with the Software or, +** alternatively, in accordance with the terms contained in a written +** agreement between you and Nokia. +** +** GNU General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the packaging +** of this file. Please review the following information to ensure GNU +** General Public Licensing requirements will be met: +** +** http://www.fsf.org/licensing/licenses/info/GPLv2.html and +** http://www.gnu.org/copyleft/gpl.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt GPL Exception +** version 1.3, included in the file GPL_EXCEPTION.txt in this package. +** +***************************************************************************/ + +#include "qtlockedfile.h" + +#include <qt_windows.h> +#include <QtCore/QFileInfo> + +namespace SharedTools { + +#define SEMAPHORE_PREFIX "QtLockedFile semaphore " +#define MUTEX_PREFIX "QtLockedFile mutex " +#define SEMAPHORE_MAX 100 + +static QString errorCodeToString(DWORD errorCode) +{ + QString result; + char *data = 0; + FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + 0, errorCode, 0, + (char*)&data, 0, 0); + result = QString::fromLocal8Bit(data); + if (data != 0) + LocalFree(data); + + if (result.endsWith("\n")) + result.truncate(result.length() - 1); + + return result; +} + +bool QtLockedFile::lock(LockMode mode, bool block) +{ + if (!isOpen()) { + qWarning("QtLockedFile::lock(): file is not opened"); + return false; + } + + if (mode == m_lock_mode) + return true; + + if (m_lock_mode != 0) + unlock(); + + if (m_semaphore_hnd == 0) { + QFileInfo fi(*this); + QString sem_name = QString::fromLatin1(SEMAPHORE_PREFIX) + + fi.absoluteFilePath().toLower(); + + QT_WA( { + m_semaphore_hnd = CreateSemaphoreW(0, SEMAPHORE_MAX, SEMAPHORE_MAX, + (TCHAR*)sem_name.utf16()); + } , { + m_semaphore_hnd = CreateSemaphoreA(0, SEMAPHORE_MAX, SEMAPHORE_MAX, + sem_name.toLocal8Bit().constData()); + } ); + + if (m_semaphore_hnd == 0) { + qWarning("QtLockedFile::lock(): CreateSemaphore: %s", + errorCodeToString(GetLastError()).toLatin1().constData()); + return false; + } + } + + bool gotMutex = false; + int decrement; + if (mode == ReadLock) { + decrement = 1; + } else { + decrement = SEMAPHORE_MAX; + if (m_mutex_hnd == 0) { + QFileInfo fi(*this); + QString mut_name = QString::fromLatin1(MUTEX_PREFIX) + + fi.absoluteFilePath().toLower(); + QT_WA( { + m_mutex_hnd = CreateMutexW(NULL, FALSE, (TCHAR*)mut_name.utf16()); + } , { + m_mutex_hnd = CreateMutexA(NULL, FALSE, mut_name.toLocal8Bit().constData()); + } ); + + if (m_mutex_hnd == 0) { + qWarning("QtLockedFile::lock(): CreateMutex: %s", + errorCodeToString(GetLastError()).toLatin1().constData()); + return false; + } + } + DWORD res = WaitForSingleObject(m_mutex_hnd, block ? INFINITE : 0); + if (res == WAIT_TIMEOUT) + return false; + if (res == WAIT_FAILED) { + qWarning("QtLockedFile::lock(): WaitForSingleObject (mutex): %s", + errorCodeToString(GetLastError()).toLatin1().constData()); + return false; + } + gotMutex = true; + } + + for (int i = 0; i < decrement; ++i) { + DWORD res = WaitForSingleObject(m_semaphore_hnd, block ? INFINITE : 0); + if (res == WAIT_TIMEOUT) { + if (i) { + // A failed nonblocking rw locking. Undo changes to semaphore. + if (ReleaseSemaphore(m_semaphore_hnd, i, NULL) == 0) { + qWarning("QtLockedFile::unlock(): ReleaseSemaphore: %s", + errorCodeToString(GetLastError()).toLatin1().constData()); + // Fall through + } + } + if (gotMutex) + ReleaseMutex(m_mutex_hnd); + return false; + } + if (res != WAIT_OBJECT_0) { + if (gotMutex) + ReleaseMutex(m_mutex_hnd); + qWarning("QtLockedFile::lock(): WaitForSingleObject (semaphore): %s", + errorCodeToString(GetLastError()).toLatin1().constData()); + return false; + } + } + + m_lock_mode = mode; + if (gotMutex) + ReleaseMutex(m_mutex_hnd); + return true; +} + +bool QtLockedFile::unlock() +{ + if (!isOpen()) { + qWarning("QtLockedFile::unlock(): file is not opened"); + return false; + } + + if (!isLocked()) + return true; + + int increment; + if (m_lock_mode == ReadLock) + increment = 1; + else + increment = SEMAPHORE_MAX; + + DWORD ret = ReleaseSemaphore(m_semaphore_hnd, increment, 0); + if (ret == 0) { + qWarning("QtLockedFile::unlock(): ReleaseSemaphore: %s", + errorCodeToString(GetLastError()).toLatin1().constData()); + return false; + } + + m_lock_mode = QtLockedFile::NoLock; + return true; +} + +QtLockedFile::~QtLockedFile() +{ + if (isOpen()) + unlock(); + if (m_mutex_hnd != 0) { + DWORD ret = CloseHandle(m_mutex_hnd); + if (ret == 0) { + qWarning("QtLockedFile::~QtLockedFile(): CloseHandle (mutex): %s", + errorCodeToString(GetLastError()).toLatin1().constData()); + } + m_mutex_hnd = 0; + } + if (m_semaphore_hnd != 0) { + DWORD ret = CloseHandle(m_semaphore_hnd); + if (ret == 0) { + qWarning("QtLockedFile::~QtLockedFile(): CloseHandle (semaphore): %s", + errorCodeToString(GetLastError()).toLatin1().constData()); + } + m_semaphore_hnd = 0; + } +} + +} // namespace SharedTools |