Merge pull request #3949 from birarda/master

have ShutdownEventListener handle WM_CLOSE or SIGTERM
This commit is contained in:
Leonardo Murillo 2014-12-11 10:40:02 -08:00
commit c24ccfabc6
8 changed files with 55 additions and 30 deletions

View file

@ -22,6 +22,7 @@
#include <NodeList.h> #include <NodeList.h>
#include <PacketHeaders.h> #include <PacketHeaders.h>
#include <SharedUtil.h> #include <SharedUtil.h>
#include <ShutdownEventListener.h>
#include <SoundCache.h> #include <SoundCache.h>
#include "AssignmentFactory.h" #include "AssignmentFactory.h"
@ -38,7 +39,6 @@ int hifiSockAddrMeta = qRegisterMetaType<HifiSockAddr>("HifiSockAddr");
AssignmentClient::AssignmentClient(int &argc, char **argv) : AssignmentClient::AssignmentClient(int &argc, char **argv) :
QCoreApplication(argc, argv), QCoreApplication(argc, argv),
_shutdownEventListener(this),
_assignmentServerHostname(DEFAULT_ASSIGNMENT_SERVER_HOSTNAME), _assignmentServerHostname(DEFAULT_ASSIGNMENT_SERVER_HOSTNAME),
_localASPortSharedMem(NULL) _localASPortSharedMem(NULL)
{ {
@ -49,8 +49,12 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) :
setApplicationName("assignment-client"); setApplicationName("assignment-client");
QSettings::setDefaultFormat(QSettings::IniFormat); QSettings::setDefaultFormat(QSettings::IniFormat);
installNativeEventFilter(&_shutdownEventListener); // setup a shutdown event listener to handle SIGTERM or WM_CLOSE for us
connect(&_shutdownEventListener, SIGNAL(receivedCloseEvent()), SLOT(quit())); #ifdef _WIN32
installNativeEventFilter(&ShutdownEventListener::getInstance());
#else
ShutdownEventListener::getInstance();
#endif
// set the logging target to the the CHILD_TARGET_NAME // set the logging target to the the CHILD_TARGET_NAME
LogHandler::getInstance().setTargetName(ASSIGNMENT_CLIENT_TARGET_NAME); LogHandler::getInstance().setTargetName(ASSIGNMENT_CLIENT_TARGET_NAME);

View file

@ -14,7 +14,6 @@
#include <QtCore/QCoreApplication> #include <QtCore/QCoreApplication>
#include "ShutdownEventListener.h"
#include "ThreadedAssignment.h" #include "ThreadedAssignment.h"
class QSharedMemory; class QSharedMemory;
@ -34,7 +33,6 @@ private slots:
private: private:
Assignment _requestAssignment; Assignment _requestAssignment;
static SharedAssignmentPointer _currentAssignment; static SharedAssignmentPointer _currentAssignment;
ShutdownEventListener _shutdownEventListener;
QString _assignmentServerHostname; QString _assignmentServerHostname;
HifiSockAddr _assignmentServerSocket; HifiSockAddr _assignmentServerSocket;
QSharedMemory* _localASPortSharedMem; QSharedMemory* _localASPortSharedMem;

View file

@ -12,6 +12,7 @@
#include <signal.h> #include <signal.h>
#include <LogHandler.h> #include <LogHandler.h>
#include <ShutdownEventListener.h>
#include "AssignmentClientMonitor.h" #include "AssignmentClientMonitor.h"
@ -19,24 +20,19 @@ const char* NUM_FORKS_PARAMETER = "-n";
const QString ASSIGNMENT_CLIENT_MONITOR_TARGET_NAME = "assignment-client-monitor"; const QString ASSIGNMENT_CLIENT_MONITOR_TARGET_NAME = "assignment-client-monitor";
void signalHandler(int param){
// get the qApp and cast it to an AssignmentClientMonitor
AssignmentClientMonitor* app = qobject_cast<AssignmentClientMonitor*>(qApp);
// tell it to stop the child processes and then go down
app->stopChildProcesses();
app->quit();
}
AssignmentClientMonitor::AssignmentClientMonitor(int &argc, char **argv, int numAssignmentClientForks) : AssignmentClientMonitor::AssignmentClientMonitor(int &argc, char **argv, int numAssignmentClientForks) :
QCoreApplication(argc, argv) QCoreApplication(argc, argv)
{ {
// be a signal handler for SIGTERM so we can stop our children when we get it
signal(SIGTERM, signalHandler);
// start the Logging class with the parent's target name // start the Logging class with the parent's target name
LogHandler::getInstance().setTargetName(ASSIGNMENT_CLIENT_MONITOR_TARGET_NAME); LogHandler::getInstance().setTargetName(ASSIGNMENT_CLIENT_MONITOR_TARGET_NAME);
// setup a shutdown event listener to handle SIGTERM or WM_CLOSE for us
#ifdef _WIN32
installNativeEventFilter(&ShutdownEventListener::getInstance());
#else
ShutdownEventListener::getInstance();
#endif
_childArguments = arguments(); _childArguments = arguments();
// remove the parameter for the number of forks so it isn't passed to the child forked processes // remove the parameter for the number of forks so it isn't passed to the child forked processes
@ -52,6 +48,10 @@ AssignmentClientMonitor::AssignmentClientMonitor(int &argc, char **argv, int num
} }
} }
AssignmentClientMonitor::~AssignmentClientMonitor() {
stopChildProcesses();
}
void AssignmentClientMonitor::stopChildProcesses() { void AssignmentClientMonitor::stopChildProcesses() {
QList<QPointer<QProcess> >::Iterator it = _childProcesses.begin(); QList<QPointer<QProcess> >::Iterator it = _childProcesses.begin();

View file

@ -24,6 +24,7 @@ class AssignmentClientMonitor : public QCoreApplication {
Q_OBJECT Q_OBJECT
public: public:
AssignmentClientMonitor(int &argc, char **argv, int numAssignmentClientForks); AssignmentClientMonitor(int &argc, char **argv, int numAssignmentClientForks);
~AssignmentClientMonitor();
void stopChildProcesses(); void stopChildProcesses();
private slots: private slots:

View file

@ -29,6 +29,7 @@
#include <LogUtils.h> #include <LogUtils.h>
#include <PacketHeaders.h> #include <PacketHeaders.h>
#include <SharedUtil.h> #include <SharedUtil.h>
#include <ShutdownEventListener.h>
#include <UUID.h> #include <UUID.h>
#include "DomainServerNodeData.h" #include "DomainServerNodeData.h"
@ -41,7 +42,6 @@ const QString ICE_SERVER_DEFAULT_HOSTNAME = "ice.highfidelity.io";
DomainServer::DomainServer(int argc, char* argv[]) : DomainServer::DomainServer(int argc, char* argv[]) :
QCoreApplication(argc, argv), QCoreApplication(argc, argv),
_shutdownEventListener(this),
_httpManager(DOMAIN_SERVER_HTTP_PORT, QString("%1/resources/web/").arg(QCoreApplication::applicationDirPath()), this), _httpManager(DOMAIN_SERVER_HTTP_PORT, QString("%1/resources/web/").arg(QCoreApplication::applicationDirPath()), this),
_httpsManager(NULL), _httpsManager(NULL),
_allAssignments(), _allAssignments(),
@ -70,8 +70,12 @@ DomainServer::DomainServer(int argc, char* argv[]) :
_settingsManager.setupConfigMap(arguments()); _settingsManager.setupConfigMap(arguments());
installNativeEventFilter(&_shutdownEventListener); // setup a shutdown event listener to handle SIGTERM or WM_CLOSE for us
connect(&_shutdownEventListener, SIGNAL(receivedCloseEvent()), SLOT(quit())); #ifdef _WIN32
installNativeEventFilter(&ShutdownEventListener::getInstance());
#else
ShutdownEventListener::getInstance();
#endif
qRegisterMetaType<DomainServerWebSessionData>("DomainServerWebSessionData"); qRegisterMetaType<DomainServerWebSessionData>("DomainServerWebSessionData");
qRegisterMetaTypeStreamOperators<DomainServerWebSessionData>("DomainServerWebSessionData"); qRegisterMetaTypeStreamOperators<DomainServerWebSessionData>("DomainServerWebSessionData");

View file

@ -27,7 +27,6 @@
#include "DomainServerSettingsManager.h" #include "DomainServerSettingsManager.h"
#include "DomainServerWebSessionData.h" #include "DomainServerWebSessionData.h"
#include "ShutdownEventListener.h"
#include "WalletTransaction.h" #include "WalletTransaction.h"
#include "PendingAssignedNodeData.h" #include "PendingAssignedNodeData.h"
@ -125,8 +124,6 @@ private:
QJsonObject jsonForSocket(const HifiSockAddr& socket); QJsonObject jsonForSocket(const HifiSockAddr& socket);
QJsonObject jsonObjectForNode(const SharedNodePointer& node); QJsonObject jsonObjectForNode(const SharedNodePointer& node);
ShutdownEventListener _shutdownEventListener;
HTTPManager _httpManager; HTTPManager _httpManager;
HTTPSManager* _httpsManager; HTTPSManager* _httpsManager;

View file

@ -9,21 +9,43 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// //
#include <QCoreApplication>
#include "ShutdownEventListener.h" #include "ShutdownEventListener.h"
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
#include <Windows.h> #include <Windows.h>
#else
#include <csignal>
#endif #endif
ShutdownEventListener::ShutdownEventListener(QObject* parent) : QObject(parent) { ShutdownEventListener& ShutdownEventListener::getInstance() {
static ShutdownEventListener staticInstance;
return staticInstance;
} }
void signalHandler(int param) {
// tell the qApp it should quit
QMetaObject::invokeMethod(qApp, "quit");
}
ShutdownEventListener::ShutdownEventListener(QObject* parent) :
QObject(parent)
{
#ifndef Q_OS_WIN
// be a signal handler for SIGTERM so we can stop our children when we get it
signal(SIGTERM, signalHandler);
#endif
}
bool ShutdownEventListener::nativeEventFilter(const QByteArray &eventType, void* msg, long* result) { bool ShutdownEventListener::nativeEventFilter(const QByteArray &eventType, void* msg, long* result) {
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
if (eventType == "windows_generic_MSG") { if (eventType == "windows_generic_MSG") {
MSG* message = (MSG*)msg; MSG* message = (MSG*)msg;
if (message->message == WM_CLOSE) { if (message->message == WM_CLOSE) {
emit receivedCloseEvent(); // tell our registered application to quit
QMetaObject::invokeMethod(qApp, "quit");
} }
} }
#endif #endif

View file

@ -18,12 +18,11 @@
class ShutdownEventListener : public QObject, public QAbstractNativeEventFilter { class ShutdownEventListener : public QObject, public QAbstractNativeEventFilter {
Q_OBJECT Q_OBJECT
public: public:
ShutdownEventListener(QObject* parent = NULL); static ShutdownEventListener& getInstance();
virtual bool nativeEventFilter(const QByteArray& eventType, void* message, long* result); virtual bool nativeEventFilter(const QByteArray& eventType, void* message, long* result);
private:
signals: ShutdownEventListener(QObject* parent = 0);
void receivedCloseEvent();
}; };
#endif // hifi_ShutdownEventListener_h #endif // hifi_ShutdownEventListener_h