From d7ae42d3775f88d5cd63fa2f8860bd31e18f981e Mon Sep 17 00:00:00 2001 From: isanae <14251494+isanae@users.noreply.github.com> Date: Sun, 8 Nov 2020 22:09:42 -0500 Subject: renamed singleinstance.h/cpp to multiprocess.h/cpp --- src/CMakeLists.txt | 2 +- src/main.cpp | 2 +- src/moapplication.cpp | 2 +- src/multiprocess.cpp | 102 +++++++++++++++++++++++++++++++++++++++++++++++++ src/multiprocess.h | 70 +++++++++++++++++++++++++++++++++ src/singleinstance.cpp | 102 ------------------------------------------------- src/singleinstance.h | 70 --------------------------------- 7 files changed, 175 insertions(+), 175 deletions(-) create mode 100644 src/multiprocess.cpp create mode 100644 src/multiprocess.h delete mode 100644 src/singleinstance.cpp delete mode 100644 src/singleinstance.h (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 30614e59..bb4b151f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -15,9 +15,9 @@ add_filter(NAME src/application GROUPS main moapplication moshortcut + multiprocess sanitychecks selfupdater - singleinstance ) add_filter(NAME src/browser GROUPS diff --git a/src/main.cpp b/src/main.cpp index 440489d3..554ed006 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,4 +1,4 @@ -#include "singleinstance.h" +#include "multiprocess.h" #include "loglist.h" #include "moapplication.h" #include "organizercore.h" diff --git a/src/moapplication.cpp b/src/moapplication.cpp index db559421..9139acbb 100644 --- a/src/moapplication.cpp +++ b/src/moapplication.cpp @@ -25,7 +25,7 @@ along with Mod Organizer. If not, see . #include "organizercore.h" #include "thread_utils.h" #include "loglist.h" -#include "singleinstance.h" +#include "multiprocess.h" #include "nexusinterface.h" #include "nxmaccessmanager.h" #include "tutorialmanager.h" diff --git a/src/multiprocess.cpp b/src/multiprocess.cpp new file mode 100644 index 00000000..4ce58718 --- /dev/null +++ b/src/multiprocess.cpp @@ -0,0 +1,102 @@ +#include "multiprocess.h" +#include "utility.h" +#include +#include +#include + +static const char s_Key[] = "mo-43d1a3ad-eeb0-4818-97c9-eda5216c29b5"; +static const int s_Timeout = 5000; + +using MOBase::reportError; + +MOMultiProcess::MOMultiProcess(bool allowMultiple, QObject *parent) : + QObject(parent), m_Ephemeral(false), m_OwnsSM(false) +{ + m_SharedMem.setKey(s_Key); + + if (!m_SharedMem.create(1)) { + if (m_SharedMem.error() == QSharedMemory::AlreadyExists) { + if (!allowMultiple) { + m_SharedMem.attach(); + m_Ephemeral = true; + } + } + + if ((m_SharedMem.error() != QSharedMemory::NoError) && + (m_SharedMem.error() != QSharedMemory::AlreadyExists)) { + throw MOBase::MyException(tr("SHM error: %1").arg(m_SharedMem.errorString())); + } + } else { + m_OwnsSM = true; + } + + if (m_OwnsSM) { + connect(&m_Server, SIGNAL(newConnection()), this, SLOT(receiveMessage()), Qt::QueuedConnection); + // has to be called before listen + m_Server.setSocketOptions(QLocalServer::WorldAccessOption); + m_Server.listen(s_Key); + } +} + + +void MOMultiProcess::sendMessage(const QString &message) +{ + if (m_OwnsSM) { + // nobody there to receive the message + return; + } + QLocalSocket socket(this); + + bool connected = false; + for(int i = 0; i < 2 && !connected; ++i) { + if (i > 0) { + Sleep(250); + } + + // other process may be just starting up + socket.connectToServer(s_Key, QIODevice::WriteOnly); + connected = socket.waitForConnected(s_Timeout); + } + + if (!connected) { + reportError(tr("failed to connect to running process: %1").arg(socket.errorString())); + return; + } + + socket.write(message.toUtf8()); + if (!socket.waitForBytesWritten(s_Timeout)) { + reportError(tr("failed to communicate with running process: %1").arg(socket.errorString())); + return; + } + + socket.disconnectFromServer(); + socket.waitForDisconnected(); +} + +void MOMultiProcess::receiveMessage() +{ + QLocalSocket *socket = m_Server.nextPendingConnection(); + if (!socket) { + return; + } + + if (!socket->waitForReadyRead(s_Timeout)) { + // check if there are bytes available; if so, it probably means the data was + // already received by the time waitForReadyRead() was called and the + // connection has been closed + const auto av = socket->bytesAvailable(); + + if (av <= 0) { + MOBase::log::error( + "failed to receive data from secondary process: {}", + socket->errorString()); + + reportError(tr("failed to receive data from secondary process: %1").arg(socket->errorString())); + return; + } + } + + QString message = QString::fromUtf8(socket->readAll().constData()); + emit messageSent(message); + socket->disconnectFromServer(); +} diff --git a/src/multiprocess.h b/src/multiprocess.h new file mode 100644 index 00000000..810e63d2 --- /dev/null +++ b/src/multiprocess.h @@ -0,0 +1,70 @@ +#ifndef MODORGANIZER_MOMULTIPROCESS_INCLUDED +#define MODORGANIZER_MOMULTIPROCESS_INCLUDED + +#include +#include +#include + + +/** + * used to ensure only a single process of Mod Organizer is started and to + * allow ephemeral processes to send messages to the primary (visible) one. + * This way, other processes can start a download in the primary one + **/ +class MOMultiProcess : public QObject +{ + Q_OBJECT + +public: + // `allowMultiple`: if another process is running, run this one + // disconnected from the shared memory + explicit MOMultiProcess(bool allowMultiple, QObject *parent = 0); + + /** + * @return true if this process's job is to forward data to the primary + * process through shared memory + **/ + bool ephemeral() const + { + return m_Ephemeral; + } + + // returns true if this is not the primary process, but was allowed because + // of the AllowMultiple flag + // + bool secondary() const + { + return !m_Ephemeral && !m_OwnsSM; + } + + /** + * send a message to the primary process. This can be used to transmit download urls + * + * @param message message to send + **/ + void sendMessage(const QString &message); + +signals: + + /** + * @brief emitted when an ephemeral process has sent a message (to us) + * + * @param message the message we received + **/ + void messageSent(const QString &message); + +public slots: + +private slots: + + void receiveMessage(); + +private: + bool m_Ephemeral; + bool m_OwnsSM; + QSharedMemory m_SharedMem; + QLocalServer m_Server; + +}; + +#endif // MODORGANIZER_MOMULTIPROCESS_INCLUDED diff --git a/src/singleinstance.cpp b/src/singleinstance.cpp deleted file mode 100644 index 401381fd..00000000 --- a/src/singleinstance.cpp +++ /dev/null @@ -1,102 +0,0 @@ -#include "singleinstance.h" -#include "utility.h" -#include -#include -#include - -static const char s_Key[] = "mo-43d1a3ad-eeb0-4818-97c9-eda5216c29b5"; -static const int s_Timeout = 5000; - -using MOBase::reportError; - -MOMultiProcess::MOMultiProcess(bool allowMultiple, QObject *parent) : - QObject(parent), m_Ephemeral(false), m_OwnsSM(false) -{ - m_SharedMem.setKey(s_Key); - - if (!m_SharedMem.create(1)) { - if (m_SharedMem.error() == QSharedMemory::AlreadyExists) { - if (!allowMultiple) { - m_SharedMem.attach(); - m_Ephemeral = true; - } - } - - if ((m_SharedMem.error() != QSharedMemory::NoError) && - (m_SharedMem.error() != QSharedMemory::AlreadyExists)) { - throw MOBase::MyException(tr("SHM error: %1").arg(m_SharedMem.errorString())); - } - } else { - m_OwnsSM = true; - } - - if (m_OwnsSM) { - connect(&m_Server, SIGNAL(newConnection()), this, SLOT(receiveMessage()), Qt::QueuedConnection); - // has to be called before listen - m_Server.setSocketOptions(QLocalServer::WorldAccessOption); - m_Server.listen(s_Key); - } -} - - -void MOMultiProcess::sendMessage(const QString &message) -{ - if (m_OwnsSM) { - // nobody there to receive the message - return; - } - QLocalSocket socket(this); - - bool connected = false; - for(int i = 0; i < 2 && !connected; ++i) { - if (i > 0) { - Sleep(250); - } - - // other process may be just starting up - socket.connectToServer(s_Key, QIODevice::WriteOnly); - connected = socket.waitForConnected(s_Timeout); - } - - if (!connected) { - reportError(tr("failed to connect to running process: %1").arg(socket.errorString())); - return; - } - - socket.write(message.toUtf8()); - if (!socket.waitForBytesWritten(s_Timeout)) { - reportError(tr("failed to communicate with running process: %1").arg(socket.errorString())); - return; - } - - socket.disconnectFromServer(); - socket.waitForDisconnected(); -} - -void MOMultiProcess::receiveMessage() -{ - QLocalSocket *socket = m_Server.nextPendingConnection(); - if (!socket) { - return; - } - - if (!socket->waitForReadyRead(s_Timeout)) { - // check if there are bytes available; if so, it probably means the data was - // already received by the time waitForReadyRead() was called and the - // connection has been closed - const auto av = socket->bytesAvailable(); - - if (av <= 0) { - MOBase::log::error( - "failed to receive data from secondary process: {}", - socket->errorString()); - - reportError(tr("failed to receive data from secondary process: %1").arg(socket->errorString())); - return; - } - } - - QString message = QString::fromUtf8(socket->readAll().constData()); - emit messageSent(message); - socket->disconnectFromServer(); -} diff --git a/src/singleinstance.h b/src/singleinstance.h deleted file mode 100644 index 810e63d2..00000000 --- a/src/singleinstance.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef MODORGANIZER_MOMULTIPROCESS_INCLUDED -#define MODORGANIZER_MOMULTIPROCESS_INCLUDED - -#include -#include -#include - - -/** - * used to ensure only a single process of Mod Organizer is started and to - * allow ephemeral processes to send messages to the primary (visible) one. - * This way, other processes can start a download in the primary one - **/ -class MOMultiProcess : public QObject -{ - Q_OBJECT - -public: - // `allowMultiple`: if another process is running, run this one - // disconnected from the shared memory - explicit MOMultiProcess(bool allowMultiple, QObject *parent = 0); - - /** - * @return true if this process's job is to forward data to the primary - * process through shared memory - **/ - bool ephemeral() const - { - return m_Ephemeral; - } - - // returns true if this is not the primary process, but was allowed because - // of the AllowMultiple flag - // - bool secondary() const - { - return !m_Ephemeral && !m_OwnsSM; - } - - /** - * send a message to the primary process. This can be used to transmit download urls - * - * @param message message to send - **/ - void sendMessage(const QString &message); - -signals: - - /** - * @brief emitted when an ephemeral process has sent a message (to us) - * - * @param message the message we received - **/ - void messageSent(const QString &message); - -public slots: - -private slots: - - void receiveMessage(); - -private: - bool m_Ephemeral; - bool m_OwnsSM; - QSharedMemory m_SharedMem; - QLocalServer m_Server; - -}; - -#endif // MODORGANIZER_MOMULTIPROCESS_INCLUDED -- cgit v1.3.1