Used timer for thread safety 79/128679/1 accepted/tizen/unified/20170511.173129 submit/tizen/20170511.053128 tizen_4.0.m1_release
authorSomin Kim <somin926.kim@samsung.com>
Mon, 8 May 2017 07:52:08 +0000 (16:52 +0900)
committerSomin Kim <somin926.kim@samsung.com>
Thu, 11 May 2017 05:10:35 +0000 (05:10 +0000)
Change-Id: I30cbcc1174d5cad65caeb4a1917545eeaab57703
Signed-off-by: Somin Kim <somin926.kim@samsung.com>
(cherry picked from commit b1c7a3f527e32d95eefc2494bf6b12d0dcfbe008)

13 files changed:
src/server/AppHistoryService.cpp
src/server/battery-stats/BatteryMonitor.cpp
src/server/battery-stats/BatteryMonitor.h
src/server/battery-stats/BatteryStatsLogger.cpp
src/server/battery-stats/BatteryStatsLogger.h
src/server/battery-stats/BatteryStatsManager.cpp
src/server/battery-stats/BatteryStatsManager.h
src/server/usage-stats/ActiveWindowMonitor.cpp
src/server/usage-stats/ActiveWindowMonitor.h
src/server/usage-stats/AppStatsLogger.cpp
src/server/usage-stats/AppStatsLogger.h
src/server/usage-stats/UsageStatsManager.cpp
src/server/usage-stats/UsageStatsManager.h

index 1acb181..85dd541 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <AppHistoryTypesPrivate.h>
 #include <AppHistoryService.h>
+#include <Timer.h>
 #include "AppHistoryClient.h"
 #include "battery-stats/BatteryStatsManager.h"
 #include "usage-stats/UsageStatsManager.h"
@@ -23,6 +24,7 @@
 
 using namespace ctx;
 
+static Timer* __timer = NULL;
 static StatsManager* __batteryMgr = NULL;
 static StatsManager* __usageMgr = NULL;
 
@@ -46,11 +48,14 @@ bool AppHistoryService::prepare()
        bool ret = DatabaseManager::initialize(getActiveUser());
        IF_FAIL_RETURN_TAG(ret, false, _E, "%s", "Failed to initialize DatabaseManager");
 
+       /* Create timer */
+       __timer = new Timer(getMainContext());
+
        /* Create battery stats manager */
-       __batteryMgr = new BatteryStatsManager();
+       __batteryMgr = new BatteryStatsManager(__timer);
 
        /* Create usage stats manager */
-       __usageMgr = new UsageStatsManager(getConnection());
+       __usageMgr = new UsageStatsManager(getConnection(), __timer);
 
        return true;
 }
@@ -69,6 +74,12 @@ void AppHistoryService::cleanup()
                __usageMgr = NULL;
        }
 
+       /* Delete timer */
+       if (__timer) {
+               delete __timer;
+               __timer = NULL;
+       }
+
        /* Close databse */
        DatabaseManager::destroy();
 }
index 41b540b..541e73f 100644 (file)
@@ -21,8 +21,9 @@
 #include <device/battery.h>
 #include <Json.h>
 #include <Tuple.h>
-#include "../DatabaseManager.h"
+#include <Timer.h>
 #include <AppHistoryTypesPrivate.h>
+#include "../DatabaseManager.h"
 #include "BatteryMonitor.h"
 
 #define DEFAULT_ROW_ID_STR "1"
@@ -64,8 +65,11 @@ void BatteryMonitor::destroy()
        __instance = NULL;
 }
 
-void BatteryMonitor::initialize()
+void BatteryMonitor::initialize(Timer* timer)
 {
+       /* Set timer */
+       __timer = timer;
+
        /* Set database */
        __database = DatabaseManager::getInstance();
 
@@ -135,7 +139,6 @@ void BatteryMonitor::__chargerChangeCb(device_callback_e type, void* value, void
 
        bool isCharging = intptr_t(value);
        IF_FAIL_VOID(!isCharging);
-       BatteryMonitor* instance = static_cast<BatteryMonitor*>(userData);
 
        int percent;
        int error = device_battery_get_percent(&percent);
@@ -143,38 +146,63 @@ void BatteryMonitor::__chargerChangeCb(device_callback_e type, void* value, void
 
        // If charger is disconnected after 100% charged
        if (percent == 100) {
-               __needSync = true;
+               Timer* timer = static_cast<Timer*>(userData);
+               timer->addIdle(__threadSwitchedChargerChangeCb, NULL);
+       }
+}
 
-               instance->__lastFullTime = CURRENT_TIME;
-               _I("Charger is disconnected after fully charged. Last fully charged time: %d", instance->__lastFullTime);
+gboolean BatteryMonitor::__threadSwitchedChargerChangeCb(gpointer data)
+{
+       BatteryMonitor* instance = getInstance();
 
-               bool ret = instance->__updateLastInfo();
-               IF_FAIL_VOID_TAG(ret, _E, "Failed to update last reset time and last percent time");
-       }
+       __needSync = true;
+
+       instance->__lastFullTime = CURRENT_TIME;
+       _I("Charger is disconnected after fully charged. Last fully charged time: %d", instance->__lastFullTime);
+
+       if (!instance->__updateLastInfo())
+               _E("Failed to update last reset time and last percent time");
+
+       return FALSE;
 }
 
 void BatteryMonitor::__timeChangeCb(keynode_t* node, void* userData)
 {
-       int timeDiff = vconf_keynode_get_int(node);
-       IF_FAIL_VOID(timeDiff != 0);
+       int val = vconf_keynode_get_int(node);
+       IF_FAIL_VOID(val != 0);
+
+       int *timeDiff = new int(val);
 
-       _I("Time changed(diff: %d). Related timestamps will be modified.", timeDiff);
+       Timer* timer = static_cast<Timer*>(userData);
+       timer->addIdle(__threadSwitchedTimeChangeCb, timeDiff);
+}
+
+gboolean BatteryMonitor::__threadSwitchedTimeChangeCb(gpointer data)
+{
+       int* timeDiff = static_cast<int*>(data);
+       _I("Time changed(diff: %d). Related timestamps will be modified.", *timeDiff);
+
+       BatteryMonitor* instance = getInstance();
 
-       BatteryMonitor* instance = static_cast<BatteryMonitor*>(userData);
        __needSync = true;
-       instance->__lastFullTime = instance->__lastFullTime + timeDiff;
-       instance->__lastHeartAccessTime = instance->__lastHeartAccessTime + timeDiff;
 
-       bool ret = instance->__updateLastInfo();
-       IF_FAIL_VOID_TAG(ret, _E, "Failed to update last reset time and last percent time");
+       instance->__lastFullTime = instance->__lastFullTime + *timeDiff;
+       instance->__lastHeartAccessTime = instance->__lastHeartAccessTime + *timeDiff;
+
+       if (instance->__updateLastInfo()) {
+               __instance->__modifyLastCpuUsage(*timeDiff);
+       } else {
+               _E("Failed to update last reset time and last percent time");
+       }
+
+       delete timeDiff;
 
-       __instance->__modifyLastCpuUsage(timeDiff);
+       return FALSE;
 }
 
 gboolean BatteryMonitor::__timeoutCb(gpointer data)
 {
-       BatteryMonitor* instance = static_cast<BatteryMonitor*>(data);
-       instance->__processBatteryUsage();
+       BatteryMonitor::getInstance()->__processBatteryUsage();
 
        return TRUE;
 }
@@ -185,14 +213,14 @@ int BatteryMonitor::start()
 
        __loadLastInfo();
 
-       int error = device_add_callback(DEVICE_CALLBACK_BATTERY_CHARGING, __chargerChangeCb, this);
+       int error = device_add_callback(DEVICE_CALLBACK_BATTERY_CHARGING, __chargerChangeCb, __timer);
        IF_FAIL_RETURN_TAG(error == DEVICE_ERROR_NONE, E_FAILED, _E, "Failed to set battery charging change cb");
 
-       error = vconf_notify_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED, __timeChangeCb, this);
+       error = vconf_notify_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED, __timeChangeCb, __timer);
        IF_FAIL_RETURN_TAG(error == VCONF_OK, E_FAILED, _E, "Failed to set time changed cb");
 
        _D("Start timer to request HEART data");
-       g_timeout_add(HEART_DB_QUERY_INTERVAL, __timeoutCb, this);
+       __timer->addTimeout(HEART_DB_QUERY_INTERVAL, __timeoutCb, NULL);
 
        return E_NONE;
 }
index a20e408..dc1a472 100644 (file)
@@ -25,6 +25,8 @@
 
 namespace ctx {
 
+       class Timer;
+
        class BatteryMonitor {
        public:
                BatteryMonitor();
@@ -33,7 +35,7 @@ namespace ctx {
                static BatteryMonitor* getInstance();
                static void destroy();
 
-               void initialize();
+               void initialize(Timer* timer);
                int start();
                int stop();
                int getLastFullTime();
@@ -51,14 +53,17 @@ namespace ctx {
 
                static void __chargerChangeCb(device_callback_e type, void* value, void* userData);
                static void __timeChangeCb(keynode_t* node, void* userData);
-               static int __timeoutCb(void* data);
+               static gboolean __threadSwitchedChargerChangeCb(gpointer data);
+               static gboolean __threadSwitchedTimeChangeCb(gpointer data);
+               static gboolean __timeoutCb(gpointer data);
 
                static BatteryMonitor* __instance;
                int64_t __lastFullTime;
                int64_t __lastHeartAccessTime;
 
                Database* __database;
-               HeartDbReader *__heartReader;
+               HeartDbReader* __heartReader;
+               Timer* __timer;
        };
 
 }      /* namespace ctx */
index 057a024..1b07e90 100644 (file)
@@ -19,9 +19,9 @@
 
 using namespace ctx;
 
-BatteryStatsLogger::BatteryStatsLogger()
+BatteryStatsLogger::BatteryStatsLogger(Timer* timer)
 {
-       BatteryMonitor::getInstance()->initialize();
+       BatteryMonitor::getInstance()->initialize(timer);
 }
 
 BatteryStatsLogger::~BatteryStatsLogger()
index 0bd4b51..f8c24e1 100644 (file)
 
 namespace ctx {
 
+       class Timer;
+
        class BatteryStatsLogger : public StatsLogger {
        public:
-               BatteryStatsLogger();
+               BatteryStatsLogger(Timer* timer);
                ~BatteryStatsLogger();
 
                int start();
index 22b7f5e..f722b87 100644 (file)
 
 using namespace ctx;
 
-BatteryStatsManager::BatteryStatsManager()
+BatteryStatsManager::BatteryStatsManager(Timer* timer)
 {
        /* Create battery stats logger */
-       __logger = new BatteryStatsLogger();
+       __logger = new BatteryStatsLogger(timer);
        __logger->start();
 
        /* Create stats providers */
index 3b7210d..c3dd73d 100644 (file)
 
 namespace ctx {
 
-       class BatteryStatsLogger;
+       class Timer;
 
        class BatteryStatsManager : public StatsManager {
        public:
-               BatteryStatsManager();
+               BatteryStatsManager(Timer* timer);
                ~BatteryStatsManager();
 
        };
index 5f78bac..95796a7 100644 (file)
@@ -22,6 +22,7 @@
 #include <app_manager.h>
 #include <AppHistoryTypes.h>
 #include <AppHistoryTypesPrivate.h>
+#include <Timer.h>
 
 #include "../DatabaseManager.h"
 #include "AppStatisticsTypes.h"
 #define DEFAULT_CACHE_SIZE 10
 #define TOP_TIER_LIMIT 2
 
+struct TimeDiffInfo {
+       ctx::AppUseMonitor* monitor;
+       int timeDiff;
+       TimeDiffInfo() : monitor(NULL), timeDiff(0) {}
+};
+
 class AppDisplayTypeCache {
 private:
        unsigned int __size;
@@ -76,12 +83,13 @@ public:
        }
 };
 
-ctx::AppUseMonitor::AppUseMonitor(GDBusConnection* conn) :
+ctx::AppUseMonitor::AppUseMonitor(GDBusConnection* conn, Timer* timer) :
        __signalId(-1),
        __lastCleanupTime(0),
        __dbusMonitor(conn),
        __timeDiff(0)
 {
+       __timer = timer;
        __startLogging();
        vconf_notify_key_changed(VCONFKEY_SYSTEM_TIME_CHANGED, __timeChangeCb, this);
        __database = DatabaseManager::getInstance();
@@ -200,8 +208,20 @@ void ctx::AppUseMonitor::__timeChangeCb(keynode_t* node, void* userData)
        int timeDiff = vconf_keynode_get_int(node);
        IF_FAIL_VOID(timeDiff != 0);
 
-       _D("Time changed. Related timestamps will be modified.");
+       TimeDiffInfo* info = new TimeDiffInfo();
+       info->monitor = static_cast<AppUseMonitor*>(userData);
+       info->timeDiff = timeDiff;
+
+       info->monitor->__timer->addIdle(__threadSwitchedTimeChangeCb, info);
+}
+
+gboolean ctx::AppUseMonitor::__threadSwitchedTimeChangeCb(gpointer data)
+{
+       TimeDiffInfo* info = static_cast<TimeDiffInfo*>(data);
+       _I("Time changed(diff: %d). Related timestamps will be modified.", info->timeDiff);
+
+       info->monitor->__timeDiff += info->timeDiff;
+       delete info;
 
-       AppUseMonitor* instance = static_cast<AppUseMonitor*>(userData);
-       instance->__timeDiff = instance->__timeDiff + timeDiff;
+       return FALSE;
 }
index 2e5fef9..27b7e9d 100644 (file)
@@ -25,6 +25,7 @@
 namespace ctx {
 
        class Database;
+       class Timer;
 
        class AppUseMonitor : public IDBusSignalListener {
        private:
@@ -33,6 +34,7 @@ namespace ctx {
                DBusMonitor __dbusMonitor;
                Database* __database;
                int __timeDiff;
+               Timer* __timer;
 
                bool __startLogging(void);
                void __stopLogging(void);
@@ -45,9 +47,10 @@ namespace ctx {
                                        const std::string& interface, const std::string& signalName, GVariant* param);
 
                static void __timeChangeCb(keynode_t* node, void* userData);
+               static gboolean __threadSwitchedTimeChangeCb(gpointer data);
 
        public:
-               AppUseMonitor(GDBusConnection* conn);
+               AppUseMonitor(GDBusConnection* conn, Timer* timer);
                ~AppUseMonitor();
        };      /* class AppUseMonitor */
 
index 99ab7d8..90de800 100644 (file)
 
 using namespace ctx;
 
-AppStatsLogger::AppStatsLogger(GDBusConnection* conn) :
+AppStatsLogger::AppStatsLogger(GDBusConnection* conn, Timer* timer) :
        __installMon(NULL),
        __launchMon(NULL)
 {
        AppDbInitializer initializer;
 
        __installMon = new AppInstallMonitor();
-       __launchMon = new AppUseMonitor(conn);
+       __launchMon = new AppUseMonitor(conn, timer);
 }
 
 AppStatsLogger::~AppStatsLogger()
index 6da8c88..8bdd2e2 100644 (file)
@@ -23,10 +23,11 @@ namespace ctx {
 
        class AppInstallMonitor;
        class AppUseMonitor;
+       class Timer;
 
        class AppStatsLogger : public StatsLogger {
        public:
-               AppStatsLogger(GDBusConnection* conn);
+               AppStatsLogger(GDBusConnection* conn, Timer* timer);
                ~AppStatsLogger();
 
        private:
index 07ea63d..c7728cc 100644 (file)
 
 using namespace ctx;
 
-UsageStatsManager::UsageStatsManager(GDBusConnection* conn)
+UsageStatsManager::UsageStatsManager(GDBusConnection* conn, Timer* timer)
 {
        /* Create usage stats logger */
-       __logger = new AppStatsLogger(conn);
+       __logger = new AppStatsLogger(conn, timer);
 
        /* Create stats providers */
        addStatsProvider(SUBJ_APP_RECENTLY_USED, new RecentAppProvider());
index 02661a6..72f84d7 100644 (file)
 namespace ctx {
 
        class AppStatsLogger;
+       class Timer;
 
        class UsageStatsManager : public StatsManager {
        public:
-               UsageStatsManager(GDBusConnection* conn);
+               UsageStatsManager(GDBusConnection* conn, Timer* timer);
                ~UsageStatsManager();
 
        };