mirror of
https://github.com/Mahdi-zarei/nekoray.git
synced 2025-12-24 10:33:15 +08:00
Fix some IPC issues
This commit is contained in:
parent
4034b19f85
commit
6751493c0f
98
3rdparty/RunGuard.hpp
vendored
98
3rdparty/RunGuard.hpp
vendored
@ -1,98 +0,0 @@
|
|||||||
#ifndef RUNGUARD_H
|
|
||||||
#define RUNGUARD_H
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QSharedMemory>
|
|
||||||
#include <QSystemSemaphore>
|
|
||||||
#include <QCryptographicHash>
|
|
||||||
|
|
||||||
class RunGuard {
|
|
||||||
public:
|
|
||||||
RunGuard(const QString &key);
|
|
||||||
|
|
||||||
~RunGuard();
|
|
||||||
|
|
||||||
bool isAnotherRunning(quint64 *data_out);
|
|
||||||
|
|
||||||
bool tryToRun(quint64 *data_in);
|
|
||||||
|
|
||||||
void release();
|
|
||||||
|
|
||||||
private:
|
|
||||||
const QString key;
|
|
||||||
const QString memLockKey;
|
|
||||||
const QString sharedmemKey;
|
|
||||||
|
|
||||||
QSharedMemory sharedMem;
|
|
||||||
QSystemSemaphore memLock;
|
|
||||||
|
|
||||||
Q_DISABLE_COPY(RunGuard)
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
QString generateKeyHash(const QString &key, const QString &salt) {
|
|
||||||
QByteArray data;
|
|
||||||
|
|
||||||
data.append(key.toUtf8());
|
|
||||||
data.append(salt.toUtf8());
|
|
||||||
data = QCryptographicHash::hash(data, QCryptographicHash::Sha1).toHex();
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
RunGuard::RunGuard(const QString &key)
|
|
||||||
: key(key), memLockKey(generateKeyHash(key, "_memLockKey")), sharedmemKey(generateKeyHash(key, "_sharedmemKey")), sharedMem(sharedmemKey), memLock(memLockKey, 1) {
|
|
||||||
memLock.acquire();
|
|
||||||
{
|
|
||||||
QSharedMemory fix(sharedmemKey); // Fix for *nix: http://habrahabr.ru/post/173281/
|
|
||||||
fix.attach();
|
|
||||||
}
|
|
||||||
memLock.release();
|
|
||||||
}
|
|
||||||
|
|
||||||
RunGuard::~RunGuard() {
|
|
||||||
release();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RunGuard::isAnotherRunning(quint64 *data_out) {
|
|
||||||
if (sharedMem.isAttached())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
memLock.acquire();
|
|
||||||
const bool isRunning = sharedMem.attach();
|
|
||||||
if (isRunning) {
|
|
||||||
if (data_out != nullptr) {
|
|
||||||
memcpy(data_out, sharedMem.data(), sizeof(quint64));
|
|
||||||
}
|
|
||||||
sharedMem.detach();
|
|
||||||
}
|
|
||||||
memLock.release();
|
|
||||||
|
|
||||||
return isRunning;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RunGuard::tryToRun(quint64 *data_in) {
|
|
||||||
memLock.acquire();
|
|
||||||
const bool result = sharedMem.create(sizeof(quint64));
|
|
||||||
if (result) memcpy(sharedMem.data(), data_in, sizeof(quint64));
|
|
||||||
memLock.release();
|
|
||||||
|
|
||||||
if (!result) {
|
|
||||||
release();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunGuard::release() {
|
|
||||||
memLock.acquire();
|
|
||||||
if (sharedMem.isAttached())
|
|
||||||
sharedMem.detach();
|
|
||||||
memLock.release();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // RUNGUARD_H
|
|
||||||
@ -11,10 +11,6 @@
|
|||||||
inline QString software_name = "NekoRay";
|
inline QString software_name = "NekoRay";
|
||||||
inline QString software_core_name = "Xray";
|
inline QString software_core_name = "Xray";
|
||||||
|
|
||||||
// Main Functions
|
|
||||||
|
|
||||||
inline std::function<void()> MF_release_runguard;
|
|
||||||
|
|
||||||
// MainWindow functions
|
// MainWindow functions
|
||||||
class QWidget;
|
class QWidget;
|
||||||
inline QWidget *mainwindow;
|
inline QWidget *mainwindow;
|
||||||
|
|||||||
54
src/main.cpp
54
src/main.cpp
@ -10,7 +10,6 @@
|
|||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <3rdparty/WinCommander.hpp>
|
#include <3rdparty/WinCommander.hpp>
|
||||||
|
|
||||||
#include "3rdparty/RunGuard.hpp"
|
|
||||||
#include "include/global/NekoGui.hpp"
|
#include "include/global/NekoGui.hpp"
|
||||||
|
|
||||||
#include "include/ui/mainwindow_interface.h"
|
#include "include/ui/mainwindow_interface.h"
|
||||||
@ -117,30 +116,6 @@ int main(int argc, char* argv[]) {
|
|||||||
DS_cores = new QThread;
|
DS_cores = new QThread;
|
||||||
DS_cores->start();
|
DS_cores->start();
|
||||||
|
|
||||||
// RunGuard
|
|
||||||
RunGuard guard("nekoray" + wd.absolutePath());
|
|
||||||
quint64 guard_data_in = GetRandomUint64();
|
|
||||||
quint64 guard_data_out = 0;
|
|
||||||
if (!NekoGui::dataStore->flag_many && !guard.tryToRun(&guard_data_in)) {
|
|
||||||
// Some Good System
|
|
||||||
if (guard.isAnotherRunning(&guard_data_out)) {
|
|
||||||
// Wake up a running instance
|
|
||||||
QLocalSocket socket;
|
|
||||||
socket.connectToServer(LOCAL_SERVER_PREFIX + Int2String(guard_data_out));
|
|
||||||
qDebug() << socket.fullServerName();
|
|
||||||
if (!socket.waitForConnected(500)) {
|
|
||||||
qDebug() << "Failed to wake a running instance.";
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
qDebug() << "connected to local server, try to raise another program";
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
// Some Bad System
|
|
||||||
QMessageBox::warning(nullptr, "NekoRay", "RunGuard disallow to run, use -many to force start.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
MF_release_runguard = [&] { guard.release(); };
|
|
||||||
|
|
||||||
// icons
|
// icons
|
||||||
QIcon::setFallbackSearchPaths(QStringList{
|
QIcon::setFallbackSearchPaths(QStringList{
|
||||||
":/nekoray",
|
":/nekoray",
|
||||||
@ -241,15 +216,30 @@ int main(int argc, char* argv[]) {
|
|||||||
signal(SIGTERM, signal_handler);
|
signal(SIGTERM, signal_handler);
|
||||||
signal(SIGINT, signal_handler);
|
signal(SIGINT, signal_handler);
|
||||||
|
|
||||||
|
// Check if another instance is running
|
||||||
|
QLocalSocket socket;
|
||||||
|
socket.connectToServer(LOCAL_SERVER_PREFIX + wd.absolutePath());
|
||||||
|
if (socket.waitForConnected(500))
|
||||||
|
{
|
||||||
|
qDebug() << "Another instance is running, let's wake it up and quit";
|
||||||
|
socket.write("Wake up!");
|
||||||
|
socket.disconnectFromServer();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// QLocalServer
|
// QLocalServer
|
||||||
QLocalServer server;
|
QLocalServer server(qApp);
|
||||||
auto server_name = LOCAL_SERVER_PREFIX + Int2String(guard_data_in);
|
auto server_name = LOCAL_SERVER_PREFIX + wd.absolutePath();
|
||||||
QLocalServer::removeServer(server_name);
|
QLocalServer::removeServer(server_name);
|
||||||
server.listen(server_name);
|
server.setSocketOptions(QLocalServer::WorldAccessOption);
|
||||||
QObject::connect(&server, &QLocalServer::newConnection, &a, [&] {
|
if (!server.listen(server_name)) {
|
||||||
auto socket = server.nextPendingConnection();
|
qWarning() << "Failed to start QLocalServer! Error:" << server.errorString();
|
||||||
qDebug() << "nextPendingConnection:" << server_name << socket;
|
return 1;
|
||||||
socket->deleteLater();
|
}
|
||||||
|
QObject::connect(&server, &QLocalServer::newConnection, qApp, [&] {
|
||||||
|
auto s = server.nextPendingConnection();
|
||||||
|
qDebug() << "Another instance tried to wake us up on " << server_name << s;
|
||||||
|
s->deleteLater();
|
||||||
// raise main window
|
// raise main window
|
||||||
MW_dialog_message("", "Raise");
|
MW_dialog_message("", "Raise");
|
||||||
});
|
});
|
||||||
|
|||||||
@ -606,7 +606,8 @@ void MainWindow::dialog_message_impl(const QString &sender, const QString &info)
|
|||||||
if (info == "RestartProgram") {
|
if (info == "RestartProgram") {
|
||||||
this->exit_reason = 2;
|
this->exit_reason = 2;
|
||||||
on_menu_exit_triggered();
|
on_menu_exit_triggered();
|
||||||
} else if (info == "Raise") {
|
}
|
||||||
|
if (info == "Raise") {
|
||||||
ActivateWindow(this);
|
ActivateWindow(this);
|
||||||
}
|
}
|
||||||
if (info == "NeedAdmin") {
|
if (info == "NeedAdmin") {
|
||||||
@ -750,7 +751,6 @@ void MainWindow::on_menu_exit_triggered() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
MF_release_runguard();
|
|
||||||
if (exit_reason == 1) {
|
if (exit_reason == 1) {
|
||||||
QDir::setCurrent(QApplication::applicationDirPath());
|
QDir::setCurrent(QApplication::applicationDirPath());
|
||||||
QProcess::startDetached("./updater", QStringList{});
|
QProcess::startDetached("./updater", QStringList{});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user