Removed dbus support.

Added unix signals support.
This commit is contained in:
codestation
2015-03-14 23:55:56 -04:30
parent c162b91b00
commit da6ad50759
17 changed files with 242 additions and 122 deletions

View File

@@ -22,20 +22,29 @@
#include "sqlitedb.h"
#include "qlistdb.h"
#include "headlessmanager.h"
#include "headlessmanager_adaptor.h"
#include <QCoreApplication>
#include <QSettings>
#include <sys/socket.h>
#include <unistd.h>
#include <vitamtp.h>
int HeadlessManager::sighup_fd[2];
int HeadlessManager::sigterm_fd[2];
HeadlessManager::HeadlessManager(QObject *obj_parent) :
QObject(obj_parent), dbus_conn(QDBusConnection::sessionBus())
QObject(obj_parent)
{
new HeadlessManagerAdaptor(this);
QDBusConnection dbus = QDBusConnection::sessionBus();
// expose qcma over dbus so the database update can be triggered
dbus.registerObject("/HeadlessManager", this);
dbus.registerService("org.qcma.HeadlessManager");
if (::socketpair(AF_UNIX, SOCK_STREAM, 0, sighup_fd))
qFatal("Couldn't create HUP socketpair");
if (::socketpair(AF_UNIX, SOCK_STREAM, 0, sigterm_fd))
qFatal("Couldn't create TERM socketpair");
sn_hup = new QSocketNotifier(sighup_fd[1], QSocketNotifier::Read, this);
connect(sn_hup, SIGNAL(activated(int)), this, SLOT(handleSigHup()));
sn_term = new QSocketNotifier(sigterm_fd[1], QSocketNotifier::Read, this);
connect(sn_term, SIGNAL(activated(int)), this, SLOT(handleSigTerm()));
}
HeadlessManager::~HeadlessManager()
@@ -71,7 +80,7 @@ void HeadlessManager::start()
// initializing database for the first use
refreshDatabase();
// send a signal over dbus of the connected peers knows when the update is finished
// send a signal when the update is finished
connect(m_db, SIGNAL(updated(int)), this, SIGNAL(databaseUpdated(int)));
thread_count = 0;
@@ -134,3 +143,37 @@ void HeadlessManager::threadStopped()
}
mutex.unlock();
}
void HeadlessManager::hupSignalHandler(int)
{
char a = 1;
::write(sighup_fd[0], &a, sizeof(a));
}
void HeadlessManager::termSignalHandler(int)
{
char a = 1;
::write(sigterm_fd[0], &a, sizeof(a));
}
void HeadlessManager::handleSigTerm()
{
sn_term->setEnabled(false);
char tmp;
::read(sigterm_fd[1], &tmp, sizeof(tmp));
stop();
sn_term->setEnabled(true);
}
void HeadlessManager::handleSigHup()
{
sn_hup->setEnabled(false);
char tmp;
::read(sighup_fd[1], &tmp, sizeof(tmp));
refreshDatabase();
sn_hup->setEnabled(true);
}

View File

@@ -24,12 +24,11 @@
#include <QObject>
#include <QThread>
#include <QDBusConnection>
#include <QSocketNotifier>
class HeadlessManager : public QObject
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.qcma.HeadlessManager")
public:
explicit HeadlessManager(QObject *parent = 0);
@@ -37,6 +36,10 @@ public:
void start();
// unix signal handlers
static void hupSignalHandler(int);
static void termSignalHandler(int);
private:
int thread_count;
QMutex mutex;
@@ -45,16 +48,26 @@ private:
QThread *usb_thread;
QThread *wireless_thread;
QDBusConnection dbus_conn;
// signal handling
static int sighup_fd[2];
static int sigterm_fd[2];
QSocketNotifier *sn_hup;
QSocketNotifier *sn_term;
signals:
void stopped();
Q_SCRIPTABLE void databaseUpdated(int count);
void databaseUpdated(int count);
public slots:
void refreshDatabase();
void stop();
// Qt signal handlers
void handleSigHup();
void handleSigTerm();
private slots:
void threadStopped();
};

View File

@@ -47,20 +47,47 @@ static void noMessageOutput(QtMsgType type, const char *msg)
Q_UNUSED(msg);
}
static bool setup_handlers()
{
struct sigaction hup, term;
hup.sa_handler = HeadlessManager::hupSignalHandler;
sigemptyset(&hup.sa_mask);
hup.sa_flags = 0;
hup.sa_flags |= SA_RESTART;
if (sigaction(SIGHUP, &hup, NULL) != 0) {
qCritical("SIGHUP signal handle failed");
return false;
}
term.sa_handler = HeadlessManager::termSignalHandler;
sigemptyset(&term.sa_mask);
term.sa_flags |= SA_RESTART;
if (sigaction(SIGTERM, &term, NULL) != 0) {
qCritical("SIGTERM signal handle failed");
return false;
}
return true;
}
int main(int argc, char *argv[])
{
if(SingleCoreApplication::sendMessage(QObject::tr("A instance of QCMA is already running"))) {
if(SingleCoreApplication::sendMessage(QObject::tr("An instance of Qcma is already running"))) {
return 0;
}
SingleCoreApplication app(argc, argv);
#ifndef Q_OS_WIN32
// FIXME: libmtp sends SIGPIPE if a socket write fails crashing the whole app
// the proper fix is to libmtp to handle the cancel properly or ignoring
// SIGPIPE on the socket
signal(SIGPIPE, SIG_IGN);
#endif
if(!setup_handlers())
return 1;
if(app.arguments().contains("--with-debug")) {
VitaMTP_Set_Logging(VitaMTP_DEBUG);
@@ -79,7 +106,7 @@ int main(int argc, char *argv[])
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
#endif
qDebug("Starting QCMA %s", QCMA_VER);
QTextStream(stdout) << "Starting Qcma " << QCMA_VER << endl;
QTranslator translator;
QString locale = QLocale().system().name();