Skip to content

Commit

Permalink
qt: daemon now operates in the background thread; added Quit GUI button
Browse files Browse the repository at this point in the history
  • Loading branch information
hypnosis-i2p committed Jun 17, 2016
1 parent 3e912c6 commit 1b35f68
Show file tree
Hide file tree
Showing 12 changed files with 360 additions and 43 deletions.
10 changes: 9 additions & 1 deletion Daemon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,5 +265,13 @@ namespace i2p

return true;
}
}

bool DaemonQT::init(int argc, char* argv[])
{
#if 0
m_Impl = std::make_shared<DaemonQTImpl> (argc, argv);
#endif
return Daemon_Singleton::init(argc, argv);
}
}
}
14 changes: 9 additions & 5 deletions Daemon.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@ namespace i2p

#if defined(QT_GUI_LIB) // check if QT
#define Daemon i2p::util::DaemonQT::Instance()
class DaemonQTImpl;
class DaemonQT: public i2p::util::Daemon_Singleton
#if 0
class DaemonQTImpl;
#endif
class DaemonQT: public i2p::util::Daemon_Singleton
{
public:

Expand All @@ -45,12 +47,14 @@ namespace i2p
}

bool init(int argc, char* argv[]);
void run ();
#if 0
void run ();

private:
private:

std::shared_ptr<DaemonQTImpl> m_Impl;
};
#endif
};

#elif defined(_WIN32)
#define Daemon i2p::util::DaemonWin32::Instance()
Expand Down
45 changes: 42 additions & 3 deletions i2pd.cpp
Original file line number Diff line number Diff line change
@@ -1,15 +1,54 @@
#include <stdlib.h>
#include "Daemon.h"
#ifndef ANDROID
# include <stdlib.h>
# include "Daemon.h"
#else
# include "qt/i2pd_qt/i2pd_qt_gui.h"
# include <QMessageBox>
# include <QApplication>
# include "DaemonQT.h"
# include "mainwindow.h"
# include <QThread>
#endif

int main( int argc, char* argv[] )
{
if (Daemon.init(argc, argv))
#ifdef ANDROID
//int result = runGUI(argc, argv);
//QMessageBox::information(0,"Debug","runGUI completed");
QApplication app(argc, argv);
qDebug("Initialising the daemon...");
bool daemonInitSuccess = i2p::util::DaemonQt::DaemonQTImpl::init(argc, argv);
if(!daemonInitSuccess) {
QMessageBox::critical(0, "Error", "Daemon init failed");
return 1;
}
qDebug("Initialised, creating the main window...");
MainWindow w;
qDebug("Before main window.show()...");
w.show ();
int result;
{
i2p::util::DaemonQt::Controller daemonQtController;
qDebug("Starting the daemon...");
emit daemonQtController.startDaemon();
qDebug("Starting gui event loop...");
result = app.exec();
//QMessageBox::information(&w, "Debug", "exec finished");
}
i2p::util::DaemonQt::DaemonQTImpl::deinit();
//QMessageBox::information(&w, "Debug", "demon stopped");
//exit(result); //return from main() causes intermittent sigsegv bugs in some Androids. exit() is a workaround for this
qDebug("Exiting the application");
return result;
#else
if (Daemon.init(argc, argv))
{
if (Daemon.start())
Daemon.run ();
Daemon.stop();
}
return EXIT_SUCCESS;
#endif
}

#ifdef _WIN32
Expand Down
83 changes: 82 additions & 1 deletion qt/i2pd_qt/DaemonQT.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,83 @@
#include "DaemonQT.h"
#include "../../Daemon.h"
#include <QMutex>
#include <QMutexLocker>

namespace i2p
{
namespace util
{
namespace DaemonQt
{

void Worker::startDaemon() {
qDebug("Performing daemon start...");
DaemonQTImpl::start();
qDebug("Daemon started.");
emit resultReady();
}
void Worker::restartDaemon() {
qDebug("Performing daemon restart...");
DaemonQTImpl::restart();
qDebug("Daemon restarted.");
emit resultReady();
}
void Worker::stopDaemon() {
qDebug("Performing daemon stop...");
DaemonQTImpl::stop();
qDebug("Daemon stopped.");
emit resultReady();
}

Controller::Controller() {
Worker *worker = new Worker;
worker->moveToThread(&workerThread);
connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
connect(this, &Controller::startDaemon, worker, &Worker::startDaemon);
connect(this, &Controller::stopDaemon, worker, &Worker::stopDaemon);
connect(this, &Controller::restartDaemon, worker, &Worker::restartDaemon);
connect(worker, &Worker::resultReady, this, &Controller::handleResults);
workerThread.start();
}
Controller::~Controller() {
qDebug("Closing and waiting for daemon worker thread...");
workerThread.quit();
workerThread.wait();
qDebug("Waiting for daemon worker thread finished.");
if(i2p::util::DaemonQt::DaemonQTImpl::isRunning()) {
qDebug("Stopping the daemon...");
i2p::util::DaemonQt::DaemonQTImpl::stop();
qDebug("Stopped the daemon.");
}
}



static DaemonQTImpl::runningChangedCallback DaemonQTImpl_runningChanged;
static bool DaemonQTImpl_running;
static QMutex* mutex;

bool DaemonQTImpl::init(int argc, char* argv[]){mutex=new QMutex(QMutex::Recursive);setRunningCallback(0);DaemonQTImpl_running=false;return Daemon.init(argc,argv);}
void DaemonQTImpl::deinit(){delete mutex;}
void DaemonQTImpl::start(){QMutexLocker locker(mutex);setRunning(true);Daemon.start();}
void DaemonQTImpl::stop(){QMutexLocker locker(mutex);Daemon.stop();setRunning(false);}
void DaemonQTImpl::restart(){QMutexLocker locker(mutex);stop();start();}

void DaemonQTImpl::setRunningCallback(runningChangedCallback cb){DaemonQTImpl_runningChanged=cb;}
bool DaemonQTImpl::isRunning(){return DaemonQTImpl_running;}
void DaemonQTImpl::setRunning(bool newValue){
bool oldValue = DaemonQTImpl_running;
if(oldValue!=newValue) {
DaemonQTImpl_running = newValue;
if(DaemonQTImpl_runningChanged!=0)DaemonQTImpl_runningChanged();
}
}

}
}
}

#if 0
#include <memory>
#include "mainwindow.h"
#include <QApplication>
Expand All @@ -19,7 +99,7 @@ namespace util

void Run ()
{
MainWindow w;
MainWindow w(m_App);
w.show ();
m_App.exec();
}
Expand Down Expand Up @@ -62,3 +142,4 @@ namespace util
}
}
}
#endif
62 changes: 62 additions & 0 deletions qt/i2pd_qt/DaemonQT.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,66 @@
#ifndef DAEMONQT_H
#define DAEMONQT_H

#include <QObject>
#include <QThread>

namespace i2p
{
namespace util
{
namespace DaemonQt
{
class Worker : public QObject
{
Q_OBJECT

public slots:
void startDaemon();
void restartDaemon();
void stopDaemon();

signals:
void resultReady();
};

class DaemonQTImpl
{
public:
typedef void (*runningChangedCallback)();

/**
* @brief init
* @param argc
* @param argv
* @return success
*/
bool static init(int argc, char* argv[]);
void static deinit();
void static start();
void static stop();
void static restart();
void static setRunningCallback(runningChangedCallback cb);
bool static isRunning();
private:
void static setRunning(bool running);
};

class Controller : public QObject
{
Q_OBJECT
QThread workerThread;
public:
Controller();
~Controller();
public slots:
void handleResults(){}
signals:
void startDaemon();
void stopDaemon();
void restartDaemon();
};
}
}
}

#endif // DAEMONQT_H
4 changes: 2 additions & 2 deletions qt/i2pd_qt/android/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<manifest package="org.purplei2p.i2pd" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="2.8.0" android:versionCode="1" android:installLocation="auto">
<application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="-- %%INSERT_APP_NAME%% --">
<application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="i2pd">
<activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation" android:name="org.qtproject.qt5.android.bindings.QtActivity" android:label="-- %%INSERT_APP_NAME%% --" android:screenOrientation="unspecified" android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
Expand Down Expand Up @@ -46,7 +46,7 @@
<!-- auto screen scale factor -->
</activity>
</application>
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="19"/>
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="23"/>
<supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>

<!-- The following comment will be replaced upon deployment with default permissions based on the dependencies of the application.
Expand Down
30 changes: 12 additions & 18 deletions qt/i2pd_qt/i2pd_qt.pro
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ QMAKE_CXXFLAGS *= -std=c++11

# git clone https://github.com/PurpleI2P/Boost-for-Android-Prebuilt.git
# git clone https://github.com/PurpleI2P/OpenSSL-for-Android-Prebuilt
# git clone https://github.com/PuerpleI2P/android-ifaddrs.git
# git clone https://github.com/PurpleI2P/android-ifaddrs.git
# change to your own
BOOST_PATH = /mnt/media/android/Boost-for-Android-Prebuilt
OPENSSL_PATH = /mnt/media/android/OpenSSL-for-Android-Prebuilt
Expand Down Expand Up @@ -66,9 +66,10 @@ SOURCES += DaemonQT.cpp\
../../TunnelPool.cpp \
../../util.cpp \
../../i2pd.cpp \
$$IFADDRS_PATH/ifaddrs.c
$$IFADDRS_PATH/ifaddrs.c \
i2pd_qt_gui.cpp

HEADERS += mainwindow.h \
HEADERS += DaemonQT.h mainwindow.h \
../../HTTPServer.h ../../I2PControl.h ../../UPnP.h ../../Daemon.h ../../Config.h \
../../AddressBook.h \
../../api.h \
Expand Down Expand Up @@ -119,7 +120,9 @@ HEADERS += mainwindow.h \
../../TunnelPool.h \
../../util.h \
../../version.h \
$$IFADDRS_PATH/ifaddrs.h
$$IFADDRS_PATH/ifaddrs.h \
i2pd_qt_gui.h


FORMS += mainwindow.ui

Expand All @@ -135,11 +138,14 @@ DEFINES += ANDROID=1
INCLUDEPATH += $$BOOST_PATH/boost_1_53_0/include \
$$OPENSSL_PATH/openssl-1.0.2/include \
$$IFADDRS_PATH
DISTFILES += \
android/AndroidManifest.xml

ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android

equals(ANDROID_TARGET_ARCH, armeabi-v7a){
# http://stackoverflow.com/a/30235934/529442
LIBS += -L$$BOOST_PATH/boost_1_53_0/armeabi-v7a/lib \
#/home/anon5/git/OpenSSL-for-Android-Prebuilt/openssl-1.0.2/armeabi-v7a/lib/libcrypto.a \
#/home/anon5/git/OpenSSL-for-Android-Prebuilt/openssl-1.0.2/armeabi-v7a/lib/libssl.a \
-lboost_system-gcc-mt-1_53 \
-lboost_date_time-gcc-mt-1_53 \
-lboost_filesystem-gcc-mt-1_53 \
Expand All @@ -157,8 +163,6 @@ ANDROID_EXTRA_LIBS += $$OPENSSL_PATH/openssl-1.0.2/armeabi-v7a/lib/libcrypto_1_0
equals(ANDROID_TARGET_ARCH, x86){
# http://stackoverflow.com/a/30235934/529442
LIBS += -L$$BOOST_PATH/boost_1_53_0/x86/lib \
#/home/anon5/git/OpenSSL-for-Android-Prebuilt/openssl-1.0.2/armeabi-v7a/lib/libcrypto.a \
#/home/anon5/git/OpenSSL-for-Android-Prebuilt/openssl-1.0.2/armeabi-v7a/lib/libssl.a \
-lboost_system-gcc-mt-1_53 \
-lboost_date_time-gcc-mt-1_53 \
-lboost_filesystem-gcc-mt-1_53 \
Expand All @@ -180,13 +184,3 @@ message("Using Linux settings")
LIBS += -lcrypto -lssl -lboost_system -lboost_date_time -lboost_filesystem -lboost_program_options -lpthread
}


unix:!macx:

DISTFILES += \
android/AndroidManifest.xml

ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android



24 changes: 24 additions & 0 deletions qt/i2pd_qt/i2pd_qt_gui.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#if 0
#include "i2pd_qt_gui.h"
#include <QApplication>
#include <QMessageBox>
#include "mainwindow.h"
#include "DaemonQT.h"

int runGUI( int argc, char* argv[] ) {
QApplication app(argc, argv);
bool daemonInitSuccess = i2p::util::DaemonQTImpl::init(argc, argv);
if(!daemonInitSuccess) {
QMessageBox::critical(0, "Error", "Daemon init failed");
return 1;
}
MainWindow w;
w.show ();
i2p::util::DaemonQTImpl::start();
int result = app.exec();
//QMessageBox::information(&w, "Debug", "exec finished");
i2p::util::DaemonQTImpl::stop();
//QMessageBox::information(&w, "Debug", "demon stopped");
return result;
}
#endif
2 changes: 2 additions & 0 deletions qt/i2pd_qt/i2pd_qt_gui.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#ifndef IQPD_QT_GUI_H
#define IQPD_QT_GUI_H

int runGUI( int argc, char* argv[] );

#endif // IQPD_QT_GUI_H
Loading

0 comments on commit 1b35f68

Please sign in to comment.