Skycoder42 / QtService

A platform independent library to easily create system services and use some of their features

Home Page:https://skycoder42.github.io/QtService/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

WindowsServiceBackend can't start.

stephenlang84 opened this issue · comments

Sometimes Windows can't start a backend service, the status is always Starting.
There are logs at that time.

qt.service.plugin.windows.backend: waiting for control thread...
qt.service.plugin.windows.backend: entered control thread
qt.service.plugin.windows.backend: registering service
qt.service.plugin.windows.backend: passing start arguments to main thread
qt.service.plugin.windows.backend: setting status to start pending
qt.service.backend: Running pre start service routine
qt.service.plugin.windows.backend: continuing control thread
qt.service.plugin.windows.backend: running application
qt.service.plugin.windows.backend: wait for main thread to finish startup 

And compare with a normal log.

qt.service.plugin.windows.backend: waiting for control thread...
qt.service.plugin.windows.backend: entered control thread
qt.service.plugin.windows.backend: registering service
qt.service.plugin.windows.backend: passing start arguments to main thread
qt.service.plugin.windows.backend: wait for main thread to finish startup
qt.service.plugin.windows.backend: setting status to start pending
qt.service.backend: Running pre start service routine
qt.service.plugin.windows.backend: continuing control thread
qt.service.plugin.windows.backend: running application
qt.service.plugin.windows.backend: handle service start event

Maybe the control thread is deadlock because the below line in function WindowsServiceBackend::serviceMain
_backendInstance->_startCondition.wait(&_backendInstance->_svcLock);

I tried a simple test to reproduce.
I see when runService of main thread is completed before serviceMain of control thread, a same issue is occurred.

#ifndef WORKERS_H
#define WORKERS_H
#include <QThread>
#include <QDebug>
#include <QWaitCondition>
#include <QMutexLocker>
#include <QMutex>
#include <QCoreApplication>

static QMutex _svcLock;
static QWaitCondition _startCondition;

class SvcControlThread : public QThread {
public:
    void run() {
        qDebug() << "entered control thread";
        qDebug() << "registering service";
        qDebug() << "passing start arguments to main thread";
        QMutexLocker lock(&_svcLock);
        _startCondition.wakeAll();
        lock.unlock();

        QThread::sleep(10);
        // wait for the mainthread to finish startup, then register the service handler
        lock.relock();
        qDebug() << "wait for main thread to finish startup";
        qDebug() << _startCondition.wait(&_svcLock);
        lock.unlock();

        // handle the start event
        qDebug() << "handle service start event";
    }
};

class WindowsServiceBackend {
public:
    void runService(int &argc, char **argv) {
        SvcControlThread controlThread;
        qDebug() << "waiting for control thread...";
        controlThread.start(QThread::LowestPriority);
        QMutexLocker lock(&_svcLock);
        if(!_startCondition.wait(&_svcLock, 20000))
            return;
        lock.unlock();
        qDebug() << "setting status to start pending";
        QCoreApplication app(argc, argv);

        lock.relock();
        qDebug() << "continuing control thread";
        _startCondition.wakeAll();
        lock.unlock();

        //execute the app
        qDebug() << "running application";
        app.exec();

    }
};

#endif // WORKERS_H
#include <QCoreApplication>
#include <Workers.h>

int main(int argc, char *argv[])
{
    WindowsServiceBackend wsb;
    wsb.runService(argc, argv);
}

Do you have a plan to solve it ? @Skycoder42

I am currently very busy. I might find the time someday, but don't expect a fix very soon. If you want, you can create a PR.