diff --git a/Utilities/qtsingleapplication/qtlockedfile_win.cpp b/Utilities/qtsingleapplication/qtlockedfile_win.cpp index 5e2126204b..a44620b3b3 100644 --- a/Utilities/qtsingleapplication/qtlockedfile_win.cpp +++ b/Utilities/qtsingleapplication/qtlockedfile_win.cpp @@ -1,211 +1,211 @@ /**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Solutions component. ** ** $QT_BEGIN_LICENSE:BSD$ ** You may use this file under the terms of the BSD license as follows: ** ** "Redistribution and use in source and binary forms, with or without ** modification, are permitted provided that the following conditions are ** met: ** * Redistributions of source code must retain the above copyright ** notice, this list of conditions and the following disclaimer. ** * Redistributions in binary form must reproduce the above copyright ** notice, this list of conditions and the following disclaimer in ** the documentation and/or other materials provided with the ** distribution. ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names ** of its contributors may be used to endorse or promote products derived ** from this software without specific prior written permission. ** ** ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "qtlockedfile.h" #include #include #define MUTEX_PREFIX "QtLockedFile mutex " // Maximum number of concurrent read locks. Must not be greater than MAXIMUM_WAIT_OBJECTS #define MAX_READERS MAXIMUM_WAIT_OBJECTS #if QT_VERSION >= 0x050000 #define QT_WA(unicode, ansi) unicode #endif Qt::HANDLE QtLockedFile::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) { - QT_WA( { mutex = CreateMutexW(NULL, FALSE, (TCHAR*)mname.utf16()); }, + QT_WA( { mutex = CreateMutexW(NULL, FALSE, reinterpret_cast(mname.utf16())); }, { mutex = CreateMutexA(NULL, FALSE, mname.toLocal8Bit().constData()); } ); if (!mutex) { qErrnoWarning("QtLockedFile::lock(): CreateMutex failed"); return 0; } } else { - QT_WA( { mutex = OpenMutexW(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, (TCHAR*)mname.utf16()); }, + QT_WA( { mutex = OpenMutexW(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, reinterpret_cast(mname.utf16())); }, { mutex = OpenMutexA(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, mname.toLocal8Bit().constData()); } ); if (!mutex) { if (GetLastError() != ERROR_FILE_NOT_FOUND) qErrnoWarning("QtLockedFile::lock(): OpenMutex failed"); return 0; } } return mutex; } bool QtLockedFile::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; } 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(); 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 QtLockedFile::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 = QtLockedFile::NoLock; return true; } QtLockedFile::~QtLockedFile() { if (isOpen()) unlock(); if (wmutex) CloseHandle(wmutex); } diff --git a/Utilities/qtsingleapplication/qtsingleapplication.patch b/Utilities/qtsingleapplication/qtsingleapplication.patch index 655ae6e280..5991034f7d 100644 --- a/Utilities/qtsingleapplication/qtsingleapplication.patch +++ b/Utilities/qtsingleapplication/qtsingleapplication.patch @@ -1,166 +1,188 @@ diff --git a/Utilities/qtsingleapplication/qtlocalpeer.cpp b/Utilities/qtsingleapplication/qtlocalpeer.cpp index 332b064..dd0143b 100644 --- a/Utilities/qtsingleapplication/qtlocalpeer.cpp +++ b/Utilities/qtsingleapplication/qtlocalpeer.cpp @@ -132,7 +132,7 @@ bool QtLocalPeer::isClient() } -bool QtLocalPeer::sendMessage(const QString &message, int timeout) +bool QtLocalPeer::sendMessage(const QByteArray &message, int timeout) { if (!isClient()) return false; @@ -156,9 +156,8 @@ bool QtLocalPeer::sendMessage(const QString &message, int timeout) if (!connOk) return false; - QByteArray uMsg(message.toUtf8()); QDataStream ds(&socket); - ds.writeBytes(uMsg.constData(), uMsg.size()); + ds.writeBytes(message.constData(), message.size()); bool res = socket.waitForBytesWritten(timeout); if (res) { res &= socket.waitForReadyRead(timeout); // wait for ack @@ -194,10 +193,9 @@ void QtLocalPeer::receiveConnection() 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) + emit messageReceived(uMsg); //### (might take a long time to return) } diff --git a/Utilities/qtsingleapplication/qtlocalpeer.h b/Utilities/qtsingleapplication/qtlocalpeer.h index 1b533b1..07374d9 100644 --- a/Utilities/qtsingleapplication/qtlocalpeer.h +++ b/Utilities/qtsingleapplication/qtlocalpeer.h @@ -54,12 +54,12 @@ class QtLocalPeer : public QObject public: QtLocalPeer(QObject *parent = 0, const QString &appId = QString()); bool isClient(); - bool sendMessage(const QString &message, int timeout); + bool sendMessage(const QByteArray &message, int timeout); QString applicationId() const { return id; } Q_SIGNALS: - void messageReceived(const QString &message); + void messageReceived(const QByteArray &message); protected Q_SLOTS: void receiveConnection(); +diff --git a/Utilities/qtsingleapplication/qtlockedfile_win.cpp b/Utilities/qtsingleapplication/qtlockedfile_win.cpp +index 5e21262..a44620b 100644 +--- a/Utilities/qtsingleapplication/qtlockedfile_win.cpp ++++ b/Utilities/qtsingleapplication/qtlockedfile_win.cpp +@@ -63,7 +63,7 @@ Qt::HANDLE QtLockedFile::getMutexHandle(int idx, bool doCreate) + + Qt::HANDLE mutex; + if (doCreate) { +- QT_WA( { mutex = CreateMutexW(NULL, FALSE, (TCHAR*)mname.utf16()); }, ++ QT_WA( { mutex = CreateMutexW(NULL, FALSE, reinterpret_cast(mname.utf16())); }, + { mutex = CreateMutexA(NULL, FALSE, mname.toLocal8Bit().constData()); } ); + if (!mutex) { + qErrnoWarning("QtLockedFile::lock(): CreateMutex failed"); +@@ -71,7 +71,7 @@ Qt::HANDLE QtLockedFile::getMutexHandle(int idx, bool doCreate) + } + } + else { +- QT_WA( { mutex = OpenMutexW(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, (TCHAR*)mname.utf16()); }, ++ QT_WA( { mutex = OpenMutexW(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, reinterpret_cast(mname.utf16())); }, + { mutex = OpenMutexA(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, mname.toLocal8Bit().constData()); } ); + if (!mutex) { + if (GetLastError() != ERROR_FILE_NOT_FOUND) diff --git a/Utilities/qtsingleapplication/qtsingleapplication.cpp b/Utilities/qtsingleapplication/qtsingleapplication.cpp index d0fb15d..b2f2058 100644 --- a/Utilities/qtsingleapplication/qtsingleapplication.cpp +++ b/Utilities/qtsingleapplication/qtsingleapplication.cpp @@ -137,7 +137,7 @@ void QtSingleApplication::sysInit(const QString &appId) { actWin = 0; peer = new QtLocalPeer(this, appId); - connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&))); + connect(peer, SIGNAL(messageReceived(const QByteArray&)), SIGNAL(messageReceived(const QByteArray&))); } @@ -256,7 +256,7 @@ bool QtSingleApplication::isRunning() \sa isRunning(), messageReceived() */ -bool QtSingleApplication::sendMessage(const QString &message, int timeout) +bool QtSingleApplication::sendMessage(const QByteArray &message, int timeout) { return peer->sendMessage(message, timeout); } @@ -288,9 +288,9 @@ void QtSingleApplication::setActivationWindow(QWidget* aw, bool activateOnMessag { actWin = aw; if (activateOnMessage) - connect(peer, SIGNAL(messageReceived(const QString&)), this, SLOT(activateWindow())); + connect(peer, SIGNAL(messageReceived(const QByteArray&)), this, SLOT(activateWindow())); else - disconnect(peer, SIGNAL(messageReceived(const QString&)), this, SLOT(activateWindow())); + disconnect(peer, SIGNAL(messageReceived(const QByteArray&)), this, SLOT(activateWindow())); } diff --git a/Utilities/qtsingleapplication/qtsingleapplication.h b/Utilities/qtsingleapplication/qtsingleapplication.h index 049406f..4acf5f5 100644 --- a/Utilities/qtsingleapplication/qtsingleapplication.h +++ b/Utilities/qtsingleapplication/qtsingleapplication.h @@ -43,6 +43,8 @@ #include +#include + class QtLocalPeer; #if defined(Q_OS_WIN) @@ -88,12 +90,12 @@ public: { isRunning(); Q_UNUSED(dummy) } public Q_SLOTS: - bool sendMessage(const QString &message, int timeout = 5000); + bool sendMessage(const QByteArray &message, int timeout = 5000); void activateWindow(); Q_SIGNALS: - void messageReceived(const QString &message); + void messageReceived(const QByteArray &message); private: diff --git a/Utilities/qtsingleapplication/qtsinglecoreapplication.cpp b/Utilities/qtsingleapplication/qtsinglecoreapplication.cpp index 5634537..a7cbf77 100644 --- a/Utilities/qtsingleapplication/qtsinglecoreapplication.cpp +++ b/Utilities/qtsingleapplication/qtsinglecoreapplication.cpp @@ -74,7 +74,7 @@ QtSingleCoreApplication::QtSingleCoreApplication(int &argc, char **argv) : QCoreApplication(argc, argv) { peer = new QtLocalPeer(this); - connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&))); + connect(peer, SIGNAL(messageReceived(const QByteArray&)), SIGNAL(messageReceived(const QByteArray&))); } @@ -87,7 +87,7 @@ QtSingleCoreApplication::QtSingleCoreApplication(const QString &appId, int &argc : QCoreApplication(argc, argv) { peer = new QtLocalPeer(this, appId); - connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&))); + connect(peer, SIGNAL(messageReceived(const QByteArray&)), SIGNAL(messageReceived(const QByteArray&))); } @@ -122,7 +122,7 @@ bool QtSingleCoreApplication::isRunning() \sa isRunning(), messageReceived() */ -bool QtSingleCoreApplication::sendMessage(const QString &message, int timeout) +bool QtSingleCoreApplication::sendMessage(const QByteArray &message, int timeout) { return peer->sendMessage(message, timeout); } diff --git a/Utilities/qtsingleapplication/qtsinglecoreapplication.h b/Utilities/qtsingleapplication/qtsinglecoreapplication.h index b87fffe..593915a 100644 --- a/Utilities/qtsingleapplication/qtsinglecoreapplication.h +++ b/Utilities/qtsingleapplication/qtsinglecoreapplication.h @@ -57,11 +57,11 @@ public: QString id() const; public Q_SLOTS: - bool sendMessage(const QString &message, int timeout = 5000); + bool sendMessage(const QByteArray &message, int timeout = 5000); Q_SIGNALS: - void messageReceived(const QString &message); + void messageReceived(const QByteArray &message); private: