summaryrefslogtreecommitdiffstats
path: root/libraries/LocalPeer/src
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/LocalPeer/src')
-rw-r--r--libraries/LocalPeer/src/LocalPeer.cpp248
-rw-r--r--libraries/LocalPeer/src/LockedFile.cpp152
-rw-r--r--libraries/LocalPeer/src/LockedFile.h34
-rw-r--r--libraries/LocalPeer/src/LockedFile_unix.cpp96
-rw-r--r--libraries/LocalPeer/src/LockedFile_win.cpp272
5 files changed, 401 insertions, 401 deletions
diff --git a/libraries/LocalPeer/src/LocalPeer.cpp b/libraries/LocalPeer/src/LocalPeer.cpp
index f71c62d8..129f3abc 100644
--- a/libraries/LocalPeer/src/LocalPeer.cpp
+++ b/libraries/LocalPeer/src/LocalPeer.cpp
@@ -67,60 +67,60 @@ static const char* ack = "ack";
ApplicationId ApplicationId::fromTraditionalApp()
{
- QString protoId = QCoreApplication::applicationFilePath();
+ QString protoId = QCoreApplication::applicationFilePath();
#if defined(Q_OS_WIN)
- protoId = protoId.toLower();
+ protoId = protoId.toLower();
#endif
- auto prefix = protoId.section(QLatin1Char('/'), -1);
- prefix.remove(QRegExp("[^a-zA-Z]"));
- prefix.truncate(6);
- QByteArray idc = protoId.toUtf8();
- quint16 idNum = qChecksum(idc.constData(), idc.size());
- auto socketName = QLatin1String("qtsingleapp-") + prefix + QLatin1Char('-') + QString::number(idNum, 16);
+ auto prefix = protoId.section(QLatin1Char('/'), -1);
+ prefix.remove(QRegExp("[^a-zA-Z]"));
+ prefix.truncate(6);
+ QByteArray idc = protoId.toUtf8();
+ quint16 idNum = qChecksum(idc.constData(), idc.size());
+ auto socketName = QLatin1String("qtsingleapp-") + prefix + QLatin1Char('-') + QString::number(idNum, 16);
#if defined(Q_OS_WIN)
- if (!pProcessIdToSessionId)
- {
- QLibrary lib("kernel32");
- pProcessIdToSessionId = (PProcessIdToSessionId)lib.resolve("ProcessIdToSessionId");
- }
- if (pProcessIdToSessionId)
- {
- DWORD sessionId = 0;
- pProcessIdToSessionId(GetCurrentProcessId(), &sessionId);
- socketName += QLatin1Char('-') + QString::number(sessionId, 16);
- }
+ if (!pProcessIdToSessionId)
+ {
+ QLibrary lib("kernel32");
+ pProcessIdToSessionId = (PProcessIdToSessionId)lib.resolve("ProcessIdToSessionId");
+ }
+ if (pProcessIdToSessionId)
+ {
+ DWORD sessionId = 0;
+ pProcessIdToSessionId(GetCurrentProcessId(), &sessionId);
+ socketName += QLatin1Char('-') + QString::number(sessionId, 16);
+ }
#else
- socketName += QLatin1Char('-') + QString::number(::getuid(), 16);
+ socketName += QLatin1Char('-') + QString::number(::getuid(), 16);
#endif
- return ApplicationId(socketName);
+ return ApplicationId(socketName);
}
ApplicationId ApplicationId::fromPathAndVersion(const QString& dataPath, const QString& version)
{
- QCryptographicHash shasum(QCryptographicHash::Algorithm::Sha1);
- QString result = dataPath + QLatin1Char('-') + version;
- shasum.addData(result.toUtf8());
- return ApplicationId(QLatin1String("qtsingleapp-") + QString::fromLatin1(shasum.result().toHex()));
+ QCryptographicHash shasum(QCryptographicHash::Algorithm::Sha1);
+ QString result = dataPath + QLatin1Char('-') + version;
+ shasum.addData(result.toUtf8());
+ return ApplicationId(QLatin1String("qtsingleapp-") + QString::fromLatin1(shasum.result().toHex()));
}
ApplicationId ApplicationId::fromCustomId(const QString& id)
{
- return ApplicationId(QLatin1String("qtsingleapp-") + id);
+ return ApplicationId(QLatin1String("qtsingleapp-") + id);
}
ApplicationId ApplicationId::fromRawString(const QString& id)
{
- return ApplicationId(id);
+ return ApplicationId(id);
}
LocalPeer::LocalPeer(QObject * parent, const ApplicationId &appId)
- : QObject(parent), id(appId)
+ : QObject(parent), id(appId)
{
- socketName = id.toString();
- server.reset(new QLocalServer());
- QString lockName = QDir(QDir::tempPath()).absolutePath() + QLatin1Char('/') + socketName + QLatin1String("-lockfile");
- lockFile.reset(new LockedFile(lockName));
- lockFile->open(QIODevice::ReadWrite);
+ socketName = id.toString();
+ server.reset(new QLocalServer());
+ QString lockName = QDir(QDir::tempPath()).absolutePath() + QLatin1Char('/') + socketName + QLatin1String("-lockfile");
+ lockFile.reset(new LockedFile(lockName));
+ lockFile->open(QIODevice::ReadWrite);
}
LocalPeer::~LocalPeer()
@@ -129,113 +129,113 @@ LocalPeer::~LocalPeer()
ApplicationId LocalPeer::applicationId() const
{
- return id;
+ return id;
}
bool LocalPeer::isClient()
{
- if (lockFile->isLocked())
- return false;
+ if (lockFile->isLocked())
+ return false;
- if (!lockFile->lock(LockedFile::WriteLock, false))
- return true;
+ if (!lockFile->lock(LockedFile::WriteLock, false))
+ return true;
- bool res = server->listen(socketName);
+ bool res = server->listen(socketName);
#if defined(Q_OS_UNIX)
- // ### Workaround
- if (!res && server->serverError() == QAbstractSocket::AddressInUseError) {
- QFile::remove(QDir::cleanPath(QDir::tempPath())+QLatin1Char('/')+socketName);
- res = server->listen(socketName);
- }
+ // ### Workaround
+ if (!res && server->serverError() == QAbstractSocket::AddressInUseError) {
+ QFile::remove(QDir::cleanPath(QDir::tempPath())+QLatin1Char('/')+socketName);
+ res = server->listen(socketName);
+ }
#endif
- if (!res)
- qWarning("QtSingleCoreApplication: listen on local socket failed, %s", qPrintable(server->errorString()));
- QObject::connect(server.get(), SIGNAL(newConnection()), SLOT(receiveConnection()));
- return false;
+ if (!res)
+ qWarning("QtSingleCoreApplication: listen on local socket failed, %s", qPrintable(server->errorString()));
+ QObject::connect(server.get(), SIGNAL(newConnection()), SLOT(receiveConnection()));
+ return false;
}
bool LocalPeer::sendMessage(const QString &message, int timeout)
{
- if (!isClient())
- return false;
-
- QLocalSocket socket;
- bool connOk = false;
- for(int i = 0; i < 2; i++) {
- // Try twice, in case the other instance is just starting up
- socket.connectToServer(socketName);
- connOk = socket.waitForConnected(timeout/2);
- if (connOk || i)
- {
- break;
- }
- std::this_thread::sleep_for(std::chrono::milliseconds(250));
- }
- if (!connOk)
- {
- return false;
- }
-
- QByteArray uMsg(message.toUtf8());
- QDataStream ds(&socket);
-
- ds.writeBytes(uMsg.constData(), uMsg.size());
- if(!socket.waitForBytesWritten(timeout))
- {
- return false;
- }
-
- // wait for 'ack'
- if(!socket.waitForReadyRead(timeout))
- {
- return false;
- }
-
- // make sure we got 'ack'
- if(!(socket.read(qstrlen(ack)) == ack))
- {
- return false;
- }
- return true;
+ if (!isClient())
+ return false;
+
+ QLocalSocket socket;
+ bool connOk = false;
+ for(int i = 0; i < 2; i++) {
+ // Try twice, in case the other instance is just starting up
+ socket.connectToServer(socketName);
+ connOk = socket.waitForConnected(timeout/2);
+ if (connOk || i)
+ {
+ break;
+ }
+ std::this_thread::sleep_for(std::chrono::milliseconds(250));
+ }
+ if (!connOk)
+ {
+ return false;
+ }
+
+ QByteArray uMsg(message.toUtf8());
+ QDataStream ds(&socket);
+
+ ds.writeBytes(uMsg.constData(), uMsg.size());
+ if(!socket.waitForBytesWritten(timeout))
+ {
+ return false;
+ }
+
+ // wait for 'ack'
+ if(!socket.waitForReadyRead(timeout))
+ {
+ return false;
+ }
+
+ // make sure we got 'ack'
+ if(!(socket.read(qstrlen(ack)) == ack))
+ {
+ return false;
+ }
+ return true;
}
void LocalPeer::receiveConnection()
{
- QLocalSocket* socket = server->nextPendingConnection();
- if (!socket)
- {
- return;
- }
-
- while (socket->bytesAvailable() < (int)sizeof(quint32))
- {
- socket->waitForReadyRead();
- }
- QDataStream ds(socket);
- QByteArray uMsg;
- quint32 remaining;
- ds >> remaining;
- uMsg.resize(remaining);
- int got = 0;
- char* uMsgBuf = uMsg.data();
- do
- {
- got = ds.readRawData(uMsgBuf, remaining);
- remaining -= got;
- uMsgBuf += got;
- } while (remaining && got >= 0 && socket->waitForReadyRead(2000));
- if (got < 0)
- {
- qWarning("QtLocalPeer: Message reception failed %s", socket->errorString().toLatin1().constData());
- delete socket;
- return;
- }
- QString message(QString::fromUtf8(uMsg));
- socket->write(ack, qstrlen(ack));
- socket->waitForBytesWritten(1000);
- socket->waitForDisconnected(1000); // make sure client reads ack
- delete socket;
- emit messageReceived(message); //### (might take a long time to return)
+ QLocalSocket* socket = server->nextPendingConnection();
+ if (!socket)
+ {
+ return;
+ }
+
+ while (socket->bytesAvailable() < (int)sizeof(quint32))
+ {
+ socket->waitForReadyRead();
+ }
+ QDataStream ds(socket);
+ QByteArray uMsg;
+ quint32 remaining;
+ ds >> remaining;
+ uMsg.resize(remaining);
+ int got = 0;
+ char* uMsgBuf = uMsg.data();
+ do
+ {
+ got = ds.readRawData(uMsgBuf, remaining);
+ remaining -= got;
+ uMsgBuf += got;
+ } while (remaining && got >= 0 && socket->waitForReadyRead(2000));
+ if (got < 0)
+ {
+ qWarning("QtLocalPeer: Message reception failed %s", socket->errorString().toLatin1().constData());
+ delete socket;
+ return;
+ }
+ QString message(QString::fromUtf8(uMsg));
+ socket->write(ack, qstrlen(ack));
+ socket->waitForBytesWritten(1000);
+ socket->waitForDisconnected(1000); // make sure client reads ack
+ delete socket;
+ emit messageReceived(message); //### (might take a long time to return)
}
diff --git a/libraries/LocalPeer/src/LockedFile.cpp b/libraries/LocalPeer/src/LockedFile.cpp
index a4951bfe..73294a16 100644
--- a/libraries/LocalPeer/src/LockedFile.cpp
+++ b/libraries/LocalPeer/src/LockedFile.cpp
@@ -41,70 +41,70 @@
#include "LockedFile.h"
/*!
- \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
- QLockedFile. 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.
+ \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
+ QLockedFile. 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.
+ 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.
+ \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().
+ Constructs an unlocked \e QtLockedFile object. This constructor
+ behaves in the same way as \e QFile::QFile().
- \sa QFile::QFile()
+ \sa QFile::QFile()
*/
LockedFile::LockedFile()
- : QFile()
+ : QFile()
{
#ifdef Q_OS_WIN
- wmutex = 0;
- rmutex = 0;
+ wmutex = 0;
+ rmutex = 0;
#endif
- m_lock_mode = NoLock;
+ 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&).
+ 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()
+ \sa QFile::QFile()
*/
LockedFile::LockedFile(const QString &name)
- : QFile(name)
+ : QFile(name)
{
#ifdef Q_OS_WIN
- wmutex = 0;
- rmutex = 0;
+ wmutex = 0;
+ rmutex = 0;
#endif
- m_lock_mode = NoLock;
+ m_lock_mode = NoLock;
}
/*!
@@ -122,72 +122,72 @@ Returns true if successful; otherwise false.
*/
bool LockedFile::open(OpenMode mode)
{
- if (mode & QIODevice::Truncate) {
- qWarning("QtLockedFile::open(): Truncate mode not allowed.");
- return false;
- }
- return QFile::open(mode);
+ if (mode & QIODevice::Truncate) {
+ qWarning("QtLockedFile::open(): Truncate mode not allowed.");
+ return false;
+ }
+ return QFile::open(mode);
}
/*!
- Returns \e true if this object has a in read or write lock;
- otherwise returns \e false.
+ Returns \e true if this object has a in read or write lock;
+ otherwise returns \e false.
- \sa lockMode()
+ \sa lockMode()
*/
bool LockedFile::isLocked() const
{
- return m_lock_mode != NoLock;
+ return m_lock_mode != NoLock;
}
/*!
- Returns the type of lock currently held by this object, or \e
- QtLockedFile::NoLock.
+ Returns the type of lock currently held by this object, or \e
+ QtLockedFile::NoLock.
- \sa isLocked()
+ \sa isLocked()
*/
LockedFile::LockMode LockedFile::lockMode() const
{
- return m_lock_mode;
+ return m_lock_mode;
}
/*!
- \fn bool QtLockedFile::lock(LockMode mode, bool block = true)
+ \fn bool QtLockedFile::lock(LockMode mode, bool block = true)
- Obtains a lock of type \a mode. The file must be opened before it
- can be locked.
+ Obtains a lock of type \a mode. The file must be opened before it
+ can be locked.
- 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 \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.
+ 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.
+ This function returns \e true if, after it executes, the file is
+ locked by this object, and \e false otherwise.
- \sa unlock(), isLocked(), lockMode()
+ \sa unlock(), isLocked(), lockMode()
*/
/*!
- \fn bool QtLockedFile::unlock()
+ \fn bool QtLockedFile::unlock()
- Releases a lock.
+ Releases a lock.
- If the object has no lock, this function returns immediately.
+ 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.
+ 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()
+ \sa lock(), isLocked(), lockMode()
*/
/*!
- \fn QtLockedFile::~QtLockedFile()
+ \fn QtLockedFile::~QtLockedFile()
- Destroys the \e QtLockedFile object. If any locks were held, they
- are released.
+ Destroys the \e QtLockedFile object. If any locks were held, they
+ are released.
*/
diff --git a/libraries/LocalPeer/src/LockedFile.h b/libraries/LocalPeer/src/LockedFile.h
index 8c178250..2f29ee20 100644
--- a/libraries/LocalPeer/src/LockedFile.h
+++ b/libraries/LocalPeer/src/LockedFile.h
@@ -48,30 +48,30 @@
class LockedFile : public QFile
{
public:
- enum LockMode { NoLock = 0, ReadLock, WriteLock };
+ enum LockMode { NoLock = 0, ReadLock, WriteLock };
- LockedFile();
- LockedFile(const QString &name);
- ~LockedFile();
+ LockedFile();
+ LockedFile(const QString &name);
+ ~LockedFile();
- bool open(OpenMode mode);
+ bool open(OpenMode mode);
- bool lock(LockMode mode, bool block = true);
- bool unlock();
- bool isLocked() const;
- LockMode lockMode() const;
+ bool lock(LockMode mode, bool block = true);
+ bool unlock();
+ bool isLocked() const;
+ LockMode lockMode() const;
- private:
+ private:
#ifdef Q_OS_WIN
- Qt::HANDLE wmutex;
- Qt::HANDLE rmutex;
- QVector<Qt::HANDLE> rmutexes;
- QString mutexname;
+ Qt::HANDLE wmutex;
+ Qt::HANDLE rmutex;
+ QVector<Qt::HANDLE> rmutexes;
+ QString mutexname;
- Qt::HANDLE getMutexHandle(int idx, bool doCreate);
- bool waitMutex(Qt::HANDLE mutex, bool doBlock);
+ Qt::HANDLE getMutexHandle(int idx, bool doCreate);
+ bool waitMutex(Qt::HANDLE mutex, bool doBlock);
#endif
- LockMode m_lock_mode;
+ LockMode m_lock_mode;
};
diff --git a/libraries/LocalPeer/src/LockedFile_unix.cpp b/libraries/LocalPeer/src/LockedFile_unix.cpp
index 4b68916c..6becc89e 100644
--- a/libraries/LocalPeer/src/LockedFile_unix.cpp
+++ b/libraries/LocalPeer/src/LockedFile_unix.cpp
@@ -47,68 +47,68 @@
bool LockedFile::lock(LockMode mode, bool block)
{
- if (!isOpen()) {
- qWarning("QtLockedFile::lock(): file is not opened");
- return false;
- }
+ if (!isOpen()) {
+ qWarning("QtLockedFile::lock(): file is not opened");
+ return false;
+ }
- if (mode == NoLock)
- return unlock();
+ if (mode == NoLock)
+ return unlock();
- if (mode == m_lock_mode)
- return true;
+ if (mode == m_lock_mode)
+ return true;
- if (m_lock_mode != NoLock)
- unlock();
+ 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);
+ 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;
- }
+ if (ret == -1) {
+ if (errno != EINTR && errno != EAGAIN)
+ qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno));
+ return false;
+ }
- m_lock_mode = mode;
- return true;
+ m_lock_mode = mode;
+ return true;
}
bool LockedFile::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;
+ 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;
}
LockedFile::~LockedFile()
{
- if (isOpen())
- unlock();
+ if (isOpen())
+ unlock();
}
diff --git a/libraries/LocalPeer/src/LockedFile_win.cpp b/libraries/LocalPeer/src/LockedFile_win.cpp
index f93ef27f..93d2c73b 100644
--- a/libraries/LocalPeer/src/LockedFile_win.cpp
+++ b/libraries/LocalPeer/src/LockedFile_win.cpp
@@ -48,158 +48,158 @@
Qt::HANDLE LockedFile::getMutexHandle(int idx, bool doCreate)
{
- if (mutexname.isEmpty()) {
- QFileInfo fi(*this);
- mutexname = QString::fromLatin1(MUTEX_PREFIX)
- + fi.absoluteFilePath().toLower();
- }
- QString mname(mutexname);
- if (idx >= 0)
- mname += QString::number(idx);
-
- Qt::HANDLE mutex;
- if (doCreate) {
- mutex = CreateMutexW(NULL, FALSE, (LPCWSTR)mname.utf16());
- if (!mutex) {
- qErrnoWarning("QtLockedFile::lock(): CreateMutex failed");
- return 0;
- }
- }
- else {
- OpenMutexW(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, (LPCWSTR)mname.utf16());
- if (!mutex) {
- if (GetLastError() != ERROR_FILE_NOT_FOUND)
- qErrnoWarning("QtLockedFile::lock(): OpenMutex failed");
- return 0;
- }
- }
- return mutex;
+ if (mutexname.isEmpty()) {
+ QFileInfo fi(*this);
+ mutexname = QString::fromLatin1(MUTEX_PREFIX)
+ + fi.absoluteFilePath().toLower();
+ }
+ QString mname(mutexname);
+ if (idx >= 0)
+ mname += QString::number(idx);
+
+ Qt::HANDLE mutex;
+ if (doCreate) {
+ mutex = CreateMutexW(NULL, FALSE, (LPCWSTR)mname.utf16());
+ if (!mutex) {
+ qErrnoWarning("QtLockedFile::lock(): CreateMutex failed");
+ return 0;
+ }
+ }
+ else {
+ mutex = OpenMutexW(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, (LPCWSTR)mname.utf16());
+ if (!mutex) {
+ if (GetLastError() != ERROR_FILE_NOT_FOUND)
+ qErrnoWarning("QtLockedFile::lock(): OpenMutex failed");
+ return 0;
+ }
+ }
+ return mutex;
}
bool LockedFile::waitMutex(Qt::HANDLE mutex, bool doBlock)
{
- Q_ASSERT(mutex);
- DWORD res = WaitForSingleObject(mutex, doBlock ? INFINITE : 0);
- switch (res) {
- case WAIT_OBJECT_0:
- case WAIT_ABANDONED:
- return true;
- break;
- case WAIT_TIMEOUT:
- break;
- default:
- qErrnoWarning("QtLockedFile::lock(): WaitForSingleObject failed");
- }
- return false;
+ Q_ASSERT(mutex);
+ DWORD res = WaitForSingleObject(mutex, doBlock ? INFINITE : 0);
+ switch (res) {
+ case WAIT_OBJECT_0:
+ case WAIT_ABANDONED:
+ return true;
+ break;
+ case WAIT_TIMEOUT:
+ break;
+ default:
+ qErrnoWarning("QtLockedFile::lock(): WaitForSingleObject failed");
+ }
+ return false;
}
bool LockedFile::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();
-
- if (!wmutex && !(wmutex = getMutexHandle(-1, true)))
- return false;
-
- if (!waitMutex(wmutex, block))
- return false;
-
- if (mode == ReadLock) {
- int idx = 0;
- for (; idx < MAX_READERS; idx++) {
- rmutex = getMutexHandle(idx, false);
- if (!rmutex || waitMutex(rmutex, false))
- break;
- CloseHandle(rmutex);
- }
- bool ok = true;
- if (idx >= MAX_READERS) {
- qWarning("QtLockedFile::lock(): too many readers");
- rmutex = 0;
- ok = false;
- }
- else if (!rmutex) {
- rmutex = getMutexHandle(idx, true);
- if (!rmutex || !waitMutex(rmutex, false))
- ok = false;
- }
- if (!ok && rmutex) {
- CloseHandle(rmutex);
- rmutex = 0;
- }
- ReleaseMutex(wmutex);
- if (!ok)
- return false;
- }
- else {
- Q_ASSERT(rmutexes.isEmpty());
- for (int i = 0; i < MAX_READERS; i++) {
- Qt::HANDLE mutex = getMutexHandle(i, false);
- if (mutex)
- rmutexes.append(mutex);
- }
- if (rmutexes.size()) {
- DWORD res = WaitForMultipleObjects(rmutexes.size(), rmutexes.constData(),
- TRUE, block ? INFINITE : 0);
- if (res != WAIT_OBJECT_0 && res != WAIT_ABANDONED) {
- if (res != WAIT_TIMEOUT)
- qErrnoWarning("QtLockedFile::lock(): WaitForMultipleObjects failed");
- m_lock_mode = WriteLock; // trick unlock() to clean up - semiyucky
- unlock();
- return false;
- }
- }
- }
-
- m_lock_mode = mode;
- return true;
+ 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();
+
+ if (!wmutex && !(wmutex = getMutexHandle(-1, true)))
+ return false;
+
+ if (!waitMutex(wmutex, block))
+ return false;
+
+ if (mode == ReadLock) {
+ int idx = 0;
+ for (; idx < MAX_READERS; idx++) {
+ rmutex = getMutexHandle(idx, false);
+ if (!rmutex || waitMutex(rmutex, false))
+ break;
+ CloseHandle(rmutex);
+ }
+ bool ok = true;
+ if (idx >= MAX_READERS) {
+ qWarning("QtLockedFile::lock(): too many readers");
+ rmutex = 0;
+ ok = false;
+ }
+ else if (!rmutex) {
+ rmutex = getMutexHandle(idx, true);
+ if (!rmutex || !waitMutex(rmutex, false))
+ ok = false;
+ }
+ if (!ok && rmutex) {
+ CloseHandle(rmutex);
+ rmutex = 0;
+ }
+ ReleaseMutex(wmutex);
+ if (!ok)
+ return false;
+ }
+ else {
+ Q_ASSERT(rmutexes.isEmpty());
+ for (int i = 0; i < MAX_READERS; i++) {
+ Qt::HANDLE mutex = getMutexHandle(i, false);
+ if (mutex)
+ rmutexes.append(mutex);
+ }
+ if (rmutexes.size()) {
+ DWORD res = WaitForMultipleObjects(rmutexes.size(), rmutexes.constData(),
+ TRUE, block ? INFINITE : 0);
+ if (res != WAIT_OBJECT_0 && res != WAIT_ABANDONED) {
+ if (res != WAIT_TIMEOUT)
+ qErrnoWarning("QtLockedFile::lock(): WaitForMultipleObjects failed");
+ m_lock_mode = WriteLock; // trick unlock() to clean up - semiyucky
+ unlock();
+ return false;
+ }
+ }
+ }
+
+ m_lock_mode = mode;
+ return true;
}
bool LockedFile::unlock()
{
- if (!isOpen()) {
- qWarning("QtLockedFile::unlock(): file is not opened");
- return false;
- }
-
- if (!isLocked())
- return true;
-
- if (m_lock_mode == ReadLock) {
- ReleaseMutex(rmutex);
- CloseHandle(rmutex);
- rmutex = 0;
- }
- else {
- foreach(Qt::HANDLE mutex, rmutexes) {
- ReleaseMutex(mutex);
- CloseHandle(mutex);
- }
- rmutexes.clear();
- ReleaseMutex(wmutex);
- }
-
- m_lock_mode = LockedFile::NoLock;
- return true;
+ if (!isOpen()) {
+ qWarning("QtLockedFile::unlock(): file is not opened");
+ return false;
+ }
+
+ if (!isLocked())
+ return true;
+
+ if (m_lock_mode == ReadLock) {
+ ReleaseMutex(rmutex);
+ CloseHandle(rmutex);
+ rmutex = 0;
+ }
+ else {
+ foreach(Qt::HANDLE mutex, rmutexes) {
+ ReleaseMutex(mutex);
+ CloseHandle(mutex);
+ }
+ rmutexes.clear();
+ ReleaseMutex(wmutex);
+ }
+
+ m_lock_mode = LockedFile::NoLock;
+ return true;
}
LockedFile::~LockedFile()
{
- if (isOpen())
- unlock();
- if (wmutex)
- CloseHandle(wmutex);
+ if (isOpen())
+ unlock();
+ if (wmutex)
+ CloseHandle(wmutex);
}