bool ServiceBase::__singleThreading = false;
ServiceBase::ServiceBase(GDBusConnection* conn, const char* serviceName, const char* methodSpecs) :
- __running(false),
+ __started(false),
+ __threadRunning(false),
__serviceName(serviceName),
__mainContext(NULL),
__mainLoop(NULL),
bool ServiceBase::start()
{
- IF_FAIL_RETURN(!__running, true);
- __running = true;
+ IF_FAIL_RETURN(!__started, true);
_I("Preparing '%s'", __serviceName);
if (__singleThreading) {
_I(CYAN("'%s' runs on the global main loop"), __serviceName);
- IF_FAIL_RETURN(__init(), false);
+ __started = __init();
} else {
__gthread = g_thread_new(__serviceName, __threadFunc, this);
IF_FAIL_RETURN_TAG(__gthread, false, _E, "Thread creation failed");
+ __started = true;
}
- return true;
+ return __started;
}
void ServiceBase::stop()
{
- IF_FAIL_VOID(__running);
- __running = false;
+ IF_FAIL_VOID(__started);
+ __started = false;
if (__singleThreading) {
__release();
} else {
- if (__mainLoop && g_main_loop_is_running(__mainLoop)) {
+ if (__threadRunning.load()) {
GSource *gSrc = g_idle_source_new();
if (gSrc) {
// Tries to stop the main loop within its thread.
void ServiceBase::notifyUserNew()
{
- GSource* gSrc = g_idle_source_new();
- IF_FAIL_VOID_TAG(gSrc, _E, "Memory allocation failed");
+ IF_FAIL_VOID(__started);
- g_source_set_callback(gSrc, __onUserActivated, this, NULL);
- g_source_attach(gSrc, __mainContext);
+ if (__threadRunning.load()) {
+ GSource* gSrc = g_idle_source_new();
+ IF_FAIL_VOID_TAG(gSrc, _E, "Memory allocation failed");
+
+ g_source_set_callback(gSrc, __onUserActivated, this, NULL);
+ g_source_attach(gSrc, __mainContext);
+ } else {
+ __onUserActivated(this);
+ }
}
void ServiceBase::notifyUserRemoved()
{
- GSource* gSrc = g_idle_source_new();
- IF_FAIL_VOID_TAG(gSrc, _E, "Memory allocation failed");
+ IF_FAIL_VOID(__started);
+
+ if (__threadRunning.load()) {
+ GSource* gSrc = g_idle_source_new();
+ IF_FAIL_VOID_TAG(gSrc, _E, "Memory allocation failed");
- g_source_set_callback(gSrc, __onUserDeactivated, this, NULL);
- g_source_attach(gSrc, __mainContext);
+ g_source_set_callback(gSrc, __onUserDeactivated, this, NULL);
+ g_source_attach(gSrc, __mainContext);
+ } else {
+ __onUserDeactivated(this);
+ }
}
gboolean ServiceBase::__onUserActivated(gpointer data)
void ServiceBase::__run()
{
if (!__init()) {
- _E("Starting failed");
+ _E("Starting '%s' failed", __serviceName);
__release();
return;
}
+ __threadRunning.store(true);
+
_I(CYAN("Starting '%s'"), __serviceName);
g_main_loop_run(__mainLoop);
+ __threadRunning.store(false);
+
__release();
}