Add mainloop state checking routines to ServiceBase 80/118780/1
authorMu-Woong Lee <muwoong.lee@samsung.com>
Tue, 14 Mar 2017 05:03:39 +0000 (14:03 +0900)
committerMu-Woong Lee <muwoong.lee@samsung.com>
Tue, 14 Mar 2017 05:03:39 +0000 (14:03 +0900)
Change-Id: I2033801f35699fc07ce24fb8c9a424a926a3f39a
Signed-off-by: Mu-Woong Lee <muwoong.lee@samsung.com>
include/ServiceBase.h
src/server/ServiceBase.cpp

index 7e72df4..b70daaa 100644 (file)
@@ -17,6 +17,7 @@
 #ifndef __CONTEXT_SERVICE_BASE_H__
 #define __CONTEXT_SERVICE_BASE_H__
 
+#include <atomic>
 #include <string>
 #include <map>
 #include <ContextTypes.h>
@@ -91,7 +92,8 @@ namespace ctx {
                unsigned int __watch(const std::string& busName, ClientBase* client);
                void __unwatch(unsigned int watchId);
 
-               bool __running;
+               bool __started;
+               std::atomic_bool __threadRunning;
                const char* __serviceName;
 
                GMainContext* __mainContext;
index a20539e..4d7da12 100644 (file)
@@ -27,7 +27,8 @@ static std::atomic_uint __activeUid;
 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),
@@ -54,31 +55,31 @@ GDBusConnection* ServiceBase::getConnection()
 
 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.
@@ -134,20 +135,32 @@ void ServiceBase::onUserDeactivated()
 
 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)
@@ -174,14 +187,18 @@ gpointer ServiceBase::__threadFunc(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();
 }