Changes: get rid of monitor booster

pull/1/head
Alexey Shilov 15 years ago
parent 69b7ebba63
commit 0c9adf06e2

@ -7,8 +7,8 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_HOME_DIRECTORY}/src/comm
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
# Set sources
set(SRC appdata.cpp booster.cpp boosterfactory.cpp monitorbooster.cpp connection.cpp daemon.cpp mbooster.cpp logger.cpp main.cpp qtbooster.cpp wrtbooster.cpp)
set(MOC_HDRS monitorbooster.h mbooster.h)
set(SRC appdata.cpp booster.cpp boosterfactory.cpp connection.cpp daemon.cpp mbooster.cpp logger.cpp main.cpp qtbooster.cpp wrtbooster.cpp)
set(MOC_HDRS mbooster.h wrtbooster.h)
qt4_wrap_cpp(MOC_SRC ${MOC_HDRS})
# Use webruntime if found

@ -22,7 +22,6 @@
#include "mbooster.h"
#include "qtbooster.h"
#include "wrtbooster.h"
#include "monitorbooster.h"
BoosterFactory::BoosterFactory()
{}
@ -41,10 +40,6 @@ Booster * BoosterFactory::create(char type)
{
return new WRTBooster();
}
else if (type == MonitorBooster::type())
{
return new MonitorBooster();
}
else
{
return NULL;
@ -65,10 +60,6 @@ void BoosterFactory::setProcessIdToBooster(char type, pid_t pid)
{
WRTBooster::setProcessId(pid);
}
else if (type == MonitorBooster::type())
{
MonitorBooster::setProcessId(pid);
}
}
char BoosterFactory::getBoosterTypeForPid(pid_t pid)
@ -85,10 +76,6 @@ char BoosterFactory::getBoosterTypeForPid(pid_t pid)
{
return WRTBooster::type();
}
else if (pid == MonitorBooster::processId())
{
return MonitorBooster::type();
}
else
{
return 0;
@ -111,7 +98,6 @@ pid_t BoosterFactory::getBoosterPidForType(char type)
}
else
{
// not used for MonitorBooster
return 0;
}
}

@ -24,7 +24,6 @@
#include "mbooster.h"
#include "qtbooster.h"
#include "wrtbooster.h"
#include "monitorbooster.h"
#include "boosterfactory.h"
#include <cstdlib>
@ -148,7 +147,6 @@ void Daemon::run()
forkBooster(MBooster::type());
forkBooster(QtBooster::type());
forkBooster(WRTBooster::type());
forkBooster(MonitorBooster::type());
// Main loop
while (true)
@ -159,10 +157,6 @@ void Daemon::run()
char msg;
ssize_t count = read(m_pipefd[0], reinterpret_cast<void *>(&msg), 1);
if (count)
{
// Read and store the pid of invoker if the message was not from
// a monitor booster it won't send the pid.
if (msg != MonitorBooster::type())
{
// Read pid of peer invoker
pid_t invokerPid;
@ -204,15 +198,6 @@ void Daemon::run()
forkBooster(msg, delay);
}
// It was from a monitor booster, that means that theme / language has
// changed so we need to reset (kill) MBooster and WRTBooster.
else
{
// Kill MBooster and WRTBooster
killProcess(BoosterFactory::getBoosterPidForType(MBooster::type()));
killProcess(BoosterFactory::getBoosterPidForType(WRTBooster::type()));
}
}
else
{
Logger::logWarning("Daemon: Nothing read from the pipe\n");

@ -35,7 +35,7 @@ int MBooster::m_ProcessID = 0;
int MBooster::m_sighupFd[2];
struct sigaction MBooster::m_oldSigAction;
MBooster::MBooster()
MBooster::MBooster() : m_item(0)
{
// Install signals handler e.g. to exit cleanly if launcher dies.
// This is a problem because MBooster runs a Qt event loop.
@ -149,12 +149,22 @@ bool MBooster::readCommand()
// exit from event loop when invoker is ready to connect
connect(this, SIGNAL(connectionAccepted()), MApplication::instance() , SLOT(quit()));
// enable theme change handler
m_item = new MGConfItem(MEEGOTOUCH_THEME_GCONF_KEY, 0);
connect(m_item, SIGNAL(valueChanged()), this, SLOT(notifyThemeChange()));
// start another thread to listen connection from invoker
QtConcurrent::run(this, &MBooster::accept);
// Run event loop so MApplication and MApplicationWindow objects can receive notifications
MApplication::exec();
// disable theme change handler
disconnect(m_item, 0, this, 0);
delete m_item;
m_item = NULL;
// Restore signal handlers to previous values
restoreUnixSignalHandlers();
@ -174,6 +184,13 @@ bool MBooster::readCommand()
return true;
}
void MBooster::notifyThemeChange()
{
MApplication::quit();
::_exit(EXIT_SUCCESS);
}
void MBooster::accept()
{
if (m_conn->accept(m_app))

@ -23,6 +23,7 @@
#include "booster.h"
#include <QObject>
#include <QSocketNotifier>
#include <MGConfItem>
#include <tr1/memory>
using std::tr1::shared_ptr;
@ -118,6 +119,7 @@ private:
//! yet transformed into a running application
static const string m_temporaryProcessName;
//! wait for socket connection
void accept();
//! Socket pair used to get SIGHUP
@ -129,11 +131,18 @@ private:
//! Old sigaction struct
static struct sigaction m_oldSigAction;
//! GConf item to listen theme change
MGConfItem* m_item;
private slots:
//! Qt signal handler for SIGHUP.
void handleSigHup();
//! Qt signal handler for theme change
void notifyThemeChange();
signals:
void connectionAccepted();

@ -1,116 +0,0 @@
/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of applauncherd
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/
#include <QCoreApplication>
#include <QObject>
#include <cstdlib>
#include "monitorbooster.h"
#include "mbooster.h"
#include "wrtbooster.h"
#include "logger.h"
const string MonitorBooster::m_socketId = "";
int MonitorBooster::m_ProcessID = 0;
const string MonitorBooster::m_temporaryProcessName = "booster-monitor";
MonitorBooster::MonitorBooster()
{
// Add keys to listen to.
addKey(MEEGOTOUCH_THEME_GCONF_KEY);
addKey(MEEGOTOUCH_LANGUAGE_GCONF_KEY);
}
void MonitorBooster::addKey(const QString & key)
{
MGConfItem * item = new MGConfItem(key, 0);
m_gConfItems << QSharedPointer<MGConfItem>(item);
QObject::connect(item, SIGNAL(valueChanged()),
this, SLOT(notifyKeyChange()));
}
void MonitorBooster::run()
{
int argc = 0;
QCoreApplication(argc, 0).exec();
}
void MonitorBooster::initialize(int initialArgc, char ** initialArgv, int newPipeFd[2])
{
setPipeFd(newPipeFd);
// Clean-up all the env variables
clearenv();
// Rename process to temporary booster process name
renameProcess(initialArgc, initialArgv);
}
void MonitorBooster::notifyKeyChange()
{
// Signal the parent process that it can create a new
// waiting booster process and close write end
const char msg = boosterType();
ssize_t ret = write(pipeFd(1), reinterpret_cast<const void *>(&msg), 1);
if (ret == -1) {
Logger::logError("MonitorBooster: Couldn't send type message to launcher process\n");
}
}
char MonitorBooster::type()
{
return 'k';
}
const string & MonitorBooster::socketName()
{
return m_socketId;
}
const string & MonitorBooster::socketId() const
{
return m_socketId;
}
void MonitorBooster::setProcessId(int pid)
{
m_ProcessID = pid;
}
int MonitorBooster::processId()
{
return m_ProcessID;
}
const string & MonitorBooster::temporaryProcessName()
{
return m_temporaryProcessName;
}
const string & MonitorBooster::boosterTemporaryProcessName() const
{
return temporaryProcessName();
}
char MonitorBooster::boosterType() const
{
return type();
}

@ -1,107 +0,0 @@
/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of applauncherd
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/
#ifndef MONITORBOOSTER_H
#define MONITORBOOSTER_H
#include <QObject>
#include <QSharedPointer>
#include <MGConfItem>
#include "booster.h"
class QString;
/*! \class MonitorBooster
*
* MonitorBooster kills certain boosters e.g. when themeing or language changes.
* Daemon will then restart the boosters.
*/
class MonitorBooster : public QObject, public Booster
{
Q_OBJECT
public:
//! Constructor.
MonitorBooster();
/*!
* \brief Return the empty strung (not used in MonitorBooster).
* \return empty string.
*/
static const string & socketName();
//! Add a GConf key to trigger booster process termination
void addKey(const QString & key);
/*! Starts the killer. This will initialize a QCoreApplication, does
* not return. reimp.
*/
virtual void run();
//! \reimp
virtual char boosterType() const;
//! \reimp
virtual void initialize(int initialArgc, char ** initialArgv, int pipeFd[2]);
/*!
* \brief Return a unique character ('k') represtenting the type of MonitorBooster.
* \return Type character.
*/
static char type();
/*!
* \brief Keep booster pid, should be reset before booster run application's main() function
*/
static void setProcessId(int pid);
/*!
* \brief Return booster pid
*/
static int processId();
//! Return the artificial process name
static const string & temporaryProcessName();
//! \reimp
virtual const string & boosterTemporaryProcessName() const;
protected:
//! \reimp
virtual const string & socketId() const;
private Q_SLOTS:
//! Send message to main process that something has changed
void notifyKeyChange();
private:
static const string m_socketId;
static int m_ProcessID;
//! Process name to be used for booster
static const string m_temporaryProcessName;
QList<QSharedPointer<MGConfItem> > m_gConfItems;
};
#endif // MONITORBOOSTER_H

@ -19,6 +19,12 @@
#include "wrtbooster.h"
#include "logger.h"
#include "connection.h"
#include <QtConcurrentRun>
#include <MApplication>
#include <sys/socket.h>
#ifdef HAVE_MCOMPONENTCACHE
#include <mcomponentcache.h>
@ -31,6 +37,69 @@
const string WRTBooster::m_socketId = "/tmp/boostw";
const string WRTBooster::m_temporaryProcessName = "booster-w";
int WRTBooster::m_ProcessID = 0;
int WRTBooster::m_sighupFd[2];
struct sigaction WRTBooster::m_oldSigAction;
WRTBooster::WRTBooster() : m_item(0)
{
// Install signals handler e.g. to exit cleanly if launcher dies.
// This is a problem because WRTBooster runs a Qt event loop.
setupUnixSignalHandlers();
// Create socket pair for SIGTERM
if (::socketpair(AF_UNIX, SOCK_STREAM, 0, m_sighupFd))
{
Logger::logError("Couldn't create HUP socketpair");
}
else
{
// Install a socket notifier on the socket
m_snHup.reset(new QSocketNotifier(m_sighupFd[1], QSocketNotifier::Read, this));
connect(m_snHup.get(), SIGNAL(activated(int)), this, SLOT(handleSigHup()));
}
}
//
// All this signal handling code is taken from Qt's Best Practices:
// http://doc.qt.nokia.com/latest/unix-signals.html
//
void WRTBooster::hupSignalHandler(int)
{
char a = 1;
::write(m_sighupFd[0], &a, sizeof(a));
}
void WRTBooster::handleSigHup()
{
::_exit(EXIT_SUCCESS);
}
bool WRTBooster::setupUnixSignalHandlers()
{
struct sigaction hup;
hup.sa_handler = WRTBooster::hupSignalHandler;
sigemptyset(&hup.sa_mask);
hup.sa_flags |= SA_RESTART;
if (sigaction(SIGHUP, &hup, &m_oldSigAction) > 0)
{
return false;
}
return true;
}
bool WRTBooster::restoreUnixSignalHandlers()
{
if (sigaction(SIGHUP, &m_oldSigAction, 0) > 0)
{
return false;
}
return true;
}
const string & WRTBooster::socketId() const
{
@ -78,3 +147,61 @@ int WRTBooster::processId()
{
return m_ProcessID;
}
bool WRTBooster::readCommand()
{
// Setup the conversation channel with the invoker.
m_conn = new Connection(socketId());
// exit from event loop when invoker is ready to connect
connect(this, SIGNAL(connectionAccepted()), MApplication::instance() , SLOT(quit()));
// enable theme change handler
m_item = new MGConfItem(MEEGOTOUCH_THEME_GCONF_KEY, 0);
connect(m_item, SIGNAL(valueChanged()), this, SLOT(notifyThemeChange()));
// start another thread to listen connection from invoker
QtConcurrent::run(this, &WRTBooster::accept);
// Run event loop so MApplication and MApplicationWindow objects can receive notifications
MApplication::exec();
// disable theme change handler
disconnect(m_item, 0, this, 0);
delete m_item;
m_item = NULL;
// Restore signal handlers to previous values
restoreUnixSignalHandlers();
// Receive application data from the invoker
if(!m_conn->receiveApplicationData(m_app))
{
m_conn->close();
return false;
}
// Close the connection if exit status doesn't need
// to be sent back to invoker
if (!m_conn->isReportAppExitStatusNeeded())
{
m_conn->close();
}
return true;
}
void WRTBooster::notifyThemeChange()
{
MApplication::quit();
::_exit(EXIT_SUCCESS);
}
void WRTBooster::accept()
{
if (m_conn->accept(m_app))
{
emit connectionAccepted();
}
}

@ -21,6 +21,14 @@
#define WRTBOOSTER_H
#include "booster.h"
#include <MGConfItem>
#include <QObject>
#include <QSocketNotifier>
#include <tr1/memory>
using std::tr1::shared_ptr;
#include <signal.h>
/*!
\class WRTBooster
@ -30,12 +38,14 @@
similarly to MBooster. However, the cache content is optimized for
web runtime's use.
*/
class WRTBooster : public Booster
class WRTBooster : public QObject, public Booster
{
Q_OBJECT
public:
//! \brief Constructor
WRTBooster() {};
WRTBooster();
//! \brief Destructor
virtual ~WRTBooster() {};
@ -75,11 +85,25 @@ public:
*/
static int processId();
//! UNIX signal handler for SIGHUP
static void hupSignalHandler(int unused);
//! Setup UNIX signal handlers
static bool setupUnixSignalHandlers();
//! Restore UNIX signal handlers to previous values
static bool restoreUnixSignalHandlers();
protected:
//! \reimp
virtual const string & socketId() const;
//! \reimp
virtual bool readCommand();
private:
//! Disable copy-constructor
@ -96,6 +120,35 @@ private:
//! yet transformed into a running application
static const string m_temporaryProcessName;
//! wait for socket connection
void accept();
//! Socket pair used to get SIGHUP
static int m_sighupFd[2];
//! Socket notifier used for m_sighupFd
shared_ptr<QSocketNotifier> m_snHup;
//! Old sigaction struct
static struct sigaction m_oldSigAction;
//! GConf item to listen theme change
MGConfItem* m_item;
private slots:
//! Qt signal handler for SIGHUP.
void handleSigHup();
//! Qt signal handler for theme change
void notifyThemeChange();
signals:
void connectionAccepted();
#ifdef UNIT_TEST
friend class Ut_WRTBooster;
#endif

@ -1,10 +1,10 @@
set(LAUNCHER ${CMAKE_HOME_DIRECTORY}/src/launcherlib)
# Set sources
set(SRC ut_boosterfactory.cpp ${LAUNCHER}/appdata.cpp ${LAUNCHER}/booster.cpp ${LAUNCHER}/mbooster.cpp ${LAUNCHER}/qtbooster.cpp ${LAUNCHER}/monitorbooster.cpp ${LAUNCHER}/wrtbooster.cpp ${LAUNCHER}/boosterfactory.cpp ${LAUNCHER}/connection.cpp ${LAUNCHER}/logger.cpp)
set(SRC ut_boosterfactory.cpp ${LAUNCHER}/appdata.cpp ${LAUNCHER}/booster.cpp ${LAUNCHER}/mbooster.cpp ${LAUNCHER}/qtbooster.cpp ${LAUNCHER}/wrtbooster.cpp ${LAUNCHER}/boosterfactory.cpp ${LAUNCHER}/connection.cpp ${LAUNCHER}/logger.cpp)
# Set moc headers
set(MOC_HDRS ut_boosterfactory.h ${LAUNCHER}/monitorbooster.h ${LAUNCHER}/mbooster.h)
set(MOC_HDRS ut_boosterfactory.h ${LAUNCHER}/mbooster.h ${LAUNCHER}/wrtbooster.h)
# Run moc
qt4_wrap_cpp(MOC_SRC ${MOC_HDRS})

@ -23,7 +23,6 @@
#include "mbooster.h"
#include "qtbooster.h"
#include "wrtbooster.h"
#include "monitorbooster.h"
void Ut_BoosterFactory::initTestCase()
{}
@ -45,14 +44,10 @@ void Ut_BoosterFactory::testCreate()
QVERIFY(dynamic_cast<WRTBooster *>(booster));
delete booster;
booster = BoosterFactory::create('k');
QVERIFY(dynamic_cast<MonitorBooster *>(booster));
delete booster;
for (int i = 0; i < 256; i++)
{
unsigned char t = static_cast<unsigned char>(i);
if (t != 'q' && t != 'm' && t != 'w' && t != 'k')
if (t != 'q' && t != 'm' && t != 'w')
{
QVERIFY(!BoosterFactory::create(t));
}
@ -76,19 +71,17 @@ void Ut_BoosterFactory::testGetBoosterTypeForPid()
BoosterFactory::setProcessIdToBooster('q', 1);
BoosterFactory::setProcessIdToBooster('m', 2);
BoosterFactory::setProcessIdToBooster('w', 3);
BoosterFactory::setProcessIdToBooster('k', 4);
QVERIFY(BoosterFactory::getBoosterTypeForPid(1) == 'q');
QVERIFY(BoosterFactory::getBoosterTypeForPid(2) == 'm');
QVERIFY(BoosterFactory::getBoosterTypeForPid(3) == 'w');
QVERIFY(BoosterFactory::getBoosterTypeForPid(4) == 'k');
QVERIFY(BoosterFactory::getBoosterTypeForPid(0) == 0);
for (int i = 0; i < 256; i++)
{
unsigned char t = static_cast<unsigned char>(i);
if (t != 'q' && t != 'm' && t != 'w' && t != 'k')
if (t != 'q' && t != 'm' && t != 'w')
{
BoosterFactory::setProcessIdToBooster(t, 1000);
QVERIFY(BoosterFactory::getBoosterTypeForPid(1000) == 0);
@ -101,17 +94,15 @@ void Ut_BoosterFactory::testGetBoosterPidForType()
BoosterFactory::setProcessIdToBooster('q', 145);
BoosterFactory::setProcessIdToBooster('m', 245);
BoosterFactory::setProcessIdToBooster('w', 345);
BoosterFactory::setProcessIdToBooster('k', 445);
QVERIFY(BoosterFactory::getBoosterPidForType('q') == 145);
QVERIFY(BoosterFactory::getBoosterPidForType('m') == 245);
QVERIFY(BoosterFactory::getBoosterPidForType('w') == 345);
QVERIFY(BoosterFactory::getBoosterPidForType('k') == 0); // shouldn't be used!!!
for (int i = 0; i < 256; i++)
{
unsigned char t = static_cast<unsigned char>(i);
if (t != 'q' && t != 'm' && t != 'w' && t != 'k')
if (t != 'q' && t != 'm' && t != 'w')
{
QVERIFY(BoosterFactory::getBoosterPidForType(t) == 0);
}

@ -1,10 +1,10 @@
set(LAUNCHER ${CMAKE_HOME_DIRECTORY}/src/launcherlib)
# Set sources
set(SRC ut_connection.cpp ${LAUNCHER}/appdata.cpp ${LAUNCHER}/booster.cpp ${LAUNCHER}/boosterfactory.cpp ${LAUNCHER}/monitorbooster.cpp ${LAUNCHER}/daemon.cpp ${LAUNCHER}/connection.cpp ${LAUNCHER}/logger.cpp ${LAUNCHER}/mbooster.cpp ${LAUNCHER}/qtbooster.cpp ${LAUNCHER}/wrtbooster.cpp)
set(SRC ut_connection.cpp ${LAUNCHER}/appdata.cpp ${LAUNCHER}/booster.cpp ${LAUNCHER}/boosterfactory.cpp ${LAUNCHER}/daemon.cpp ${LAUNCHER}/connection.cpp ${LAUNCHER}/logger.cpp ${LAUNCHER}/mbooster.cpp ${LAUNCHER}/qtbooster.cpp ${LAUNCHER}/wrtbooster.cpp)
# Set moc headers
set(MOC_HDRS ut_connection.h ${LAUNCHER}/monitorbooster.h ${LAUNCHER}/mbooster.h)
set(MOC_HDRS ut_connection.h ${LAUNCHER}/mbooster.h ${LAUNCHER}/wrtbooster.h)
# Set the program name define used in daemon.cpp
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DPROG_NAME_LAUNCHER=\\\"applauncherd\\\"")

@ -1,9 +1,9 @@
# Set sources
set(LAUNCHER ${CMAKE_HOME_DIRECTORY}/src/launcherlib)
set(SRC ut_daemon.cpp ${LAUNCHER}/appdata.cpp ${LAUNCHER}/booster.cpp ${LAUNCHER}/boosterfactory.cpp ${LAUNCHER}/monitorbooster.cpp ${LAUNCHER}/daemon.cpp ${LAUNCHER}/connection.cpp ${LAUNCHER}/logger.cpp ${LAUNCHER}/mbooster.cpp ${LAUNCHER}/qtbooster.cpp ${LAUNCHER}/wrtbooster.cpp)
set(SRC ut_daemon.cpp ${LAUNCHER}/appdata.cpp ${LAUNCHER}/booster.cpp ${LAUNCHER}/boosterfactory.cpp ${LAUNCHER}/daemon.cpp ${LAUNCHER}/connection.cpp ${LAUNCHER}/logger.cpp ${LAUNCHER}/mbooster.cpp ${LAUNCHER}/qtbooster.cpp ${LAUNCHER}/wrtbooster.cpp)
# Set moc headers
set(MOC_HDRS ut_daemon.h ${LAUNCHER}/monitorbooster.h ${LAUNCHER}/mbooster.h)
set(MOC_HDRS ut_daemon.h ${LAUNCHER}/mbooster.h ${LAUNCHER}/wrtbooster.h)
# Set the program name define used in daemon.cpp
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DPROG_NAME_LAUNCHER=\\\"applauncherd\\\"")

@ -5,7 +5,7 @@ set(SRC ut_wrtbooster.cpp ${LAUNCHER}/appdata.cpp ${LAUNCHER}/booster.cpp ${LAUN
${LAUNCHER}/logger.cpp ${LAUNCHER}/wrtbooster.cpp)
# Set moc headers
set(MOC_HDRS ut_wrtbooster.h)
set(MOC_HDRS ut_wrtbooster.h ${LAUNCHER}/wrtbooster.h)
# Run moc
qt4_wrap_cpp(MOC_SRC ${MOC_HDRS})

Loading…
Cancel
Save