cache app_unique_name to improve performance 93/93393/9
authorJiwoong Im <jiwoong.im@samsung.com>
Mon, 24 Oct 2016 05:48:52 +0000 (14:48 +0900)
committerJiwoong Im <jiwoong.im@samsung.com>
Tue, 25 Oct 2016 08:35:25 +0000 (17:35 +0900)
Change-Id: If090e3b8504cf0b6ad888a40f3181269c0fb3c4a
Signed-off-by: Jiwoong Im <jiwoong.im@samsung.com>
alarm-manager.c
include/alarm-internal.h
src/alarm-lib.c

index 9ed2047..25058d3 100644 (file)
@@ -153,7 +153,7 @@ static bool __initialize_db();
 static void __initialize();
 void on_bus_name_owner_changed(GDBusConnection *connection, const gchar *sender_name, const gchar *object_path,
                const gchar *interface_name, const gchar *signal_name, GVariant *parameters, gpointer user_data);
-bool __get_caller_unique_name(int pid, char *unique_name, uid_t uid);
+bool __get_caller_unique_name(int pid, char *unique_name, bool *is_app, uid_t uid);
 
 #ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG
 static void __initialize_module_log(void);
@@ -170,6 +170,59 @@ struct filtered_alarm_app_s {
        uid_t uid;
 };
 
+GHashTable* appid_cache_table = NULL;
+
+typedef struct {
+       int pid;
+       bool is_app;
+       char *unique_name;
+} appid_cache_t;
+
+static bool __get_cached_unique_name(int pid, char *unique_name, bool *is_app, uid_t uid)
+{
+       appid_cache_t *data = NULL;
+       data = (appid_cache_t *)g_hash_table_lookup(appid_cache_table, &pid);
+       if (data) {
+               snprintf(unique_name, MAX_APP_ID, "%s", data->unique_name);
+               if (is_app)
+                       *is_app = data->is_app;
+               ALARM_MGR_LOG_PRINT("Get cached unique_name: %s, pid:%d", unique_name, pid);
+               return true;
+       }
+
+       ALARM_MGR_LOG_PRINT("There is no cached unique_name for pid(%d)", pid);
+       return __get_caller_unique_name(pid, unique_name, is_app, uid);
+}
+
+gboolean __hash_table_remove_cb(gpointer key, gpointer value, gpointer user_data)
+{
+       char *target_name = user_data;
+       appid_cache_t *data = value;
+       if (target_name && data && strcmp(target_name, data->unique_name) == 0) {
+               ALARM_MGR_LOG_PRINT("Remove cached data of [%s]", target_name);
+               return true;
+       }
+       return false;
+}
+
+void __hashtable_foreach_cb(gpointer key, gpointer value, gpointer user_data)
+{
+       appid_cache_t *data = value;
+       if (data)
+               ALARM_MGR_LOG_PRINT("# %s(%d) - %s - %d", data->unique_name, data->pid, data->is_app);
+}
+
+void __free_cached_value(gpointer data)
+{
+       appid_cache_t* value = data;
+
+       if (value) {
+               if (value->unique_name)
+                       free(value->unique_name);
+               free(value);
+       }
+}
+
 static void __rtc_set()
 {
 #ifdef _APPFW_FEATURE_WAKEUP_USING_RTC
@@ -694,7 +747,6 @@ static bool __alarm_create_appsvc(alarm_info_t *alarm_info, alarm_id_t *alarm_id
        char due_time_r[100] = { 0 };
        char app_name[512] = { 0 };
        bundle *b;
-       char caller_appid[256] = { 0 };
        const char* callee_appid = NULL;
        char* caller_pkgid = NULL;
        char* callee_pkgid = NULL;
@@ -702,6 +754,7 @@ static bool __alarm_create_appsvc(alarm_info_t *alarm_info, alarm_id_t *alarm_id
        pkgmgrinfo_pkginfo_h callee_handle;
        bundle_raw *b_data = NULL;
        int datalen = 0;
+       bool caller_is_app = false;
 
        __alarm_info_t *__alarm_info = NULL;
 
@@ -718,19 +771,18 @@ static bool __alarm_create_appsvc(alarm_info_t *alarm_info, alarm_id_t *alarm_id
        __alarm_info->requested_interval = requested_interval;
        __alarm_info->global = false;
 
-       if (!__get_caller_unique_name(pid, app_name, uid)) {
+       if (__get_cached_unique_name(pid, app_name, &caller_is_app, uid) == false) {
                *error_code = ERR_ALARM_SYSTEM_FAIL;
                free(__alarm_info);
                return false;
        }
        __alarm_info->quark_app_unique_name = g_quark_from_string(app_name);
 
-       /* Get caller_appid and callee_appid to get each package id */
        /* caller */
        __alarm_info->quark_caller_pkgid = g_quark_from_string("null");
 
-       if (aul_app_get_appid_bypid_for_uid(pid, caller_appid, 256, uid) == AUL_R_OK) {
-               if (pkgmgrinfo_appinfo_get_usr_appinfo(caller_appid, uid, &caller_handle) == PMINFO_R_OK) {
+       if (caller_is_app) {
+               if (pkgmgrinfo_appinfo_get_usr_appinfo(app_name, uid, &caller_handle) == PMINFO_R_OK) {
                        if (pkgmgrinfo_appinfo_get_pkgid(caller_handle, &caller_pkgid) == PMINFO_R_OK) {
                                if (caller_pkgid)
                                        __alarm_info->quark_caller_pkgid = g_quark_from_string(caller_pkgid);
@@ -831,10 +883,10 @@ static bool __alarm_create(alarm_info_t *alarm_info, alarm_id_t *alarm_id, uid_t
 {
        time_t current_time;
        time_t due_time;
-       char app_name[512] = { 0 };
-       char caller_appid[256] = { 0 };
+       char unique_name[MAX_APP_ID] = { 0 };
        char* caller_pkgid = NULL;
        pkgmgrinfo_pkginfo_h caller_handle;
+       bool caller_is_app = false;
 
        __alarm_info_t *__alarm_info = NULL;
 
@@ -854,9 +906,15 @@ static bool __alarm_create(alarm_info_t *alarm_info, alarm_id_t *alarm_id, uid_t
        __alarm_info->is_ref = is_ref;
        __alarm_info->global = false;
 
+       if (__get_cached_unique_name(pid, unique_name, &caller_is_app, uid) == false) {
+               *error_code = ERR_ALARM_SYSTEM_FAIL;
+               free(__alarm_info);
+               return false;
+       }
+
        /* Get caller_appid to get caller's package id. There is no callee. */
-       if (aul_app_get_appid_bypid_for_uid(pid, caller_appid, 256, uid) == AUL_R_OK) {
-               if (pkgmgrinfo_appinfo_get_usr_appinfo(caller_appid, uid, &caller_handle) == PMINFO_R_OK) {
+       if (caller_is_app) {
+               if (pkgmgrinfo_appinfo_get_usr_appinfo(unique_name, uid, &caller_handle) == PMINFO_R_OK) {
                        if (pkgmgrinfo_appinfo_get_pkgid(caller_handle, &caller_pkgid) == PMINFO_R_OK) {
                                if (caller_pkgid)
                                        __alarm_info->quark_caller_pkgid = g_quark_from_string(caller_pkgid);
@@ -868,13 +926,7 @@ static bool __alarm_create(alarm_info_t *alarm_info, alarm_id_t *alarm_id, uid_t
        __alarm_info->quark_callee_pkgid = g_quark_from_string("null");
        SECURE_LOGD("caller_pkgid = %s, callee_pkgid = null", g_quark_to_string(__alarm_info->quark_caller_pkgid));
 
-       if (!__get_caller_unique_name(pid, app_name, uid)) {
-               *error_code = ERR_ALARM_SYSTEM_FAIL;
-               free(__alarm_info);
-               return false;
-       }
-
-       __alarm_info->quark_app_unique_name = g_quark_from_string(app_name);
+       __alarm_info->quark_app_unique_name = g_quark_from_string(unique_name);
        __alarm_info->quark_app_service_name = g_quark_from_string(app_service_name);
        __alarm_info->quark_app_service_name_mod = g_quark_from_string(app_service_name_mod);
        __alarm_info->quark_dst_service_name = g_quark_from_string(dst_service_name);
@@ -1702,12 +1754,12 @@ static int __on_app_uninstalled(uid_t target_uid, int req_id, const char *pkg_ty
 
        if (strncmp(key, "end", 3) == 0 && strncmp(val, "ok", 2) == 0) {
                for (gs_iter = alarm_context.alarms; gs_iter != NULL;) {
-                       bool is_found = false;
                        entry = gs_iter->data;
 
                        const char* caller_pkgid = g_quark_to_string(entry->quark_caller_pkgid);
                        const char* callee_pkgid = g_quark_to_string(entry->quark_callee_pkgid);
 
+                       gs_iter = g_slist_next(gs_iter);
                        if ((caller_pkgid && strncmp(pkgid, caller_pkgid, strlen(pkgid)) == 0) ||
                                        (callee_pkgid && strncmp(pkgid, callee_pkgid, strlen(pkgid)) == 0)) {
                                if (_remove_from_scheduled_alarm_list(entry->uid, entry->alarm_id))
@@ -1718,30 +1770,28 @@ static int __on_app_uninstalled(uid_t target_uid, int req_id, const char *pkg_ty
                                        if (!_delete_alarms(entry->alarm_id))
                                                SECURE_LOGE("_delete_alarms() is failed. pkgid[%s], alarm_id[%d]", pkgid, entry->alarm_id);
                                }
-                               is_found = true;
-                       }
 
-                       gs_iter = g_slist_next(gs_iter);
+                               if (g_hash_table_remove(appid_cache_table, &entry->pid) == true)
+                                       ALARM_MGR_LOG_PRINT("Remove cachd data of pid[%d]", entry->pid);
 
-                       if (is_found) {
                                SECURE_LOGD("Remove pkgid[%s], alarm_id[%d]", pkgid, entry->alarm_id);
                                alarm_context.alarms = g_slist_remove(alarm_context.alarms, entry);
                                g_free(entry);
+
                        }
                }
 
                if (is_deleted && (g_slist_length(g_scheduled_alarm_list) == 0)) {
                        _alarm_disable_timer(alarm_context);
                        _alarm_schedule();
+                       __rtc_set();
                }
        }
 
-       __rtc_set();
-
        return ALARMMGR_RESULT_SUCCESS;
 }
 
-bool __get_caller_unique_name(int pid, char *unique_name, uid_t uid)
+bool __get_caller_unique_name(int pid, char *unique_name, bool *is_app, uid_t uid)
 {
        char caller_appid[256] = {0,};
 
@@ -1753,6 +1803,8 @@ bool __get_caller_unique_name(int pid, char *unique_name, uid_t uid)
        if (aul_app_get_appid_bypid_for_uid(pid, caller_appid,
                                sizeof(caller_appid), uid) == AUL_R_OK) {
                /* When a caller is an application, the unique name is appID. */
+               if (is_app)
+                       *is_app = true;
                strncpy(unique_name, caller_appid, strlen(caller_appid));
        } else {
                /* Otherwise, the unique name is /proc/pid/cmdline. */
@@ -1761,6 +1813,9 @@ bool __get_caller_unique_name(int pid, char *unique_name, uid_t uid)
                int fd = 0;
                int i = 0;
 
+               if (is_app)
+                       *is_app = false;
+
                snprintf(proc_file, 512, "/proc/%d/cmdline", pid);
 
                fd = open(proc_file, O_RDONLY);
@@ -1786,6 +1841,13 @@ bool __get_caller_unique_name(int pid, char *unique_name, uid_t uid)
                        strncpy(unique_name, process_name, strlen(process_name));
                }
        }
+       appid_cache_t* entry = (appid_cache_t*)calloc(1, sizeof(appid_cache_t));
+
+       entry->unique_name = strdup(unique_name);
+       entry->is_app = is_app;
+       entry->pid = pid;
+       g_hash_table_foreach_remove(appid_cache_table, __hash_table_remove_cb, (gpointer)unique_name);
+       g_hash_table_insert(appid_cache_table, &entry->pid, (gpointer)entry);
 
        SECURE_LOGD("unique_name= %s", unique_name);
        return true;
@@ -2578,7 +2640,7 @@ gboolean alarm_manager_alarm_delete_all(AlarmManager *obj, GDBusMethodInvocation
                return true;
        }
 
-       if (!__get_caller_unique_name(pid, app_name, uid)) {
+       if (__get_cached_unique_name(pid, app_name, NULL, uid) == false) {
                return_code = ERR_ALARM_SYSTEM_FAIL;
                g_dbus_method_invocation_return_value(invoc, g_variant_new("(i)", return_code));
 #ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG
@@ -2721,7 +2783,7 @@ gboolean alarm_manager_alarm_get_number_of_ids(AlarmManager *pObject, GDBusMetho
                return true;
        }
 
-       if (!__get_caller_unique_name(pid, app_name, uid)) {
+       if (__get_cached_unique_name(pid, app_name, NULL, uid) == false) {
                return_code = ERR_ALARM_SYSTEM_FAIL;
                g_dbus_method_invocation_return_value(invoc, g_variant_new("(ii)", num_of_ids, return_code));
                return true;
@@ -2773,7 +2835,7 @@ gboolean alarm_manager_alarm_get_list_of_ids(AlarmManager *pObject, GDBusMethodI
                return true;
        }
 
-       if (!__get_caller_unique_name(pid, app_name, uid)) {
+       if (__get_cached_unique_name(pid, app_name, NULL, uid) == false) {
                return_code = ERR_ALARM_SYSTEM_FAIL;
                g_dbus_method_invocation_return_value(invoc, g_variant_new("(@aiii)", g_variant_new("ai", NULL), num_of_ids, return_code));
                return true;
@@ -3455,6 +3517,11 @@ static void __initialize()
        __initialize_db();
        __initialize_alarm_list();
        __initialize_noti();
+
+       if (!appid_cache_table) {
+               appid_cache_table = g_hash_table_new_full(g_int_hash, g_int_equal,
+                               NULL, __free_cached_value);
+       }
 }
 
 int main()
index 18231b3..1ffb966 100644 (file)
@@ -44,6 +44,7 @@
 #define MAX_PKG_ID_LEN 256
 #define MIN_INEXACT_INTERVAL 600
 #define REGULAR_UID_MIN 5000
+#define MAX_APP_ID 256
 
 #define SYSTEM_TIME_CHANGED "setting_time_changed"
 
index e98e376..673ea2b 100644 (file)
@@ -39,6 +39,9 @@
 #define EXPORT_API __attribute__ ((visibility("default")))
 #endif
 
+static char g_appid[MAX_APP_ID];
+static int flag_appid_checked;
+
 static alarm_context_t alarm_context = { NULL, NULL, NULL, 0, NULL, NULL, -1 };
 
 static bool b_initialized = false;
@@ -1189,12 +1192,17 @@ EXPORT_API int alarmmgr_add_alarm_withcb(int alarm_type, time_t trigger_at_time,
        struct tm duetime_tm;
        alarm_info_t alarm_info;
        int ret = 0;
-       char appid[256] = {0,};
 
-       if (aul_app_get_appid_bypid(getpid(), appid, sizeof(appid)) != AUL_R_OK)
-               ALARM_MGR_EXCEPTION_PRINT("aul_app_get_appid_bypid() is failed. PID %d may not be app.", getpid());
+       if (flag_appid_checked == 0) {
+               if (aul_app_get_appid_bypid(getpid(), g_appid, sizeof(g_appid)) != AUL_R_OK) {
+                       ALARM_MGR_EXCEPTION_PRINT("PID[%d] may not be app. Please call alarmmgr_init(caller name) in advance.", getpid());
+               } else {
+                       ALARM_MGR_LOG_PRINT("Get appid only once. appid[%s]", g_appid);
+               }
+               flag_appid_checked = 1;
+       }
 
-       ret = alarmmgr_init(appid);
+       ret = alarmmgr_init(g_appid);
        if (ret < 0)
                return ret;
 
@@ -1525,14 +1533,17 @@ EXPORT_API int alarmmgr_add_periodic_alarm_withcb(int interval, periodic_method_
        int error_code = 0;
        alarm_info_t alarm_info;
        int ret = 0;
-       char appid[256] = {0,};
 
-       if (aul_app_get_appid_bypid(getpid(), appid, sizeof(appid)) != AUL_R_OK) {
-               ALARM_MGR_EXCEPTION_PRINT("aul_app_get_appid_bypid() is failed. PID %d may not be app.",
-                               getpid());
+       if (flag_appid_checked == 0) {
+               if (aul_app_get_appid_bypid(getpid(), g_appid, sizeof(g_appid)) != AUL_R_OK) {
+                       ALARM_MGR_EXCEPTION_PRINT("PID[%d] may not be app. Please call alarmmgr_init(caller name) in advance.", getpid());
+               } else {
+                       ALARM_MGR_LOG_PRINT("Get appid only once. appid[%s]", g_appid);
+               }
+               flag_appid_checked = 1;
        }
 
-       ret = alarmmgr_init(appid);
+       ret = alarmmgr_init(g_appid);
        if (ret < 0)
                return ret;
 
@@ -1555,14 +1566,17 @@ EXPORT_API int alarmmgr_add_reference_periodic_alarm_withcb(int interval,
        int error_code = 0;
        alarm_info_t alarm_info;
        int ret = 0;
-       char appid[256] = {0,};
 
-       if (aul_app_get_appid_bypid(getpid(), appid, sizeof(appid)) != AUL_R_OK) {
-               ALARM_MGR_EXCEPTION_PRINT("aul_app_get_appid_bypid() is failed. PID %d may not be app.",
-                               getpid());
+       if (flag_appid_checked == 0) {
+               if (aul_app_get_appid_bypid(getpid(), g_appid, sizeof(g_appid)) != AUL_R_OK) {
+                       ALARM_MGR_EXCEPTION_PRINT("PID[%d] may not be app. Please call alarmmgr_init(caller name) in advance.", getpid());
+               } else {
+                       ALARM_MGR_LOG_PRINT("Get appid only once. appid[%s]", g_appid);
+               }
+               flag_appid_checked = 1;
        }
 
-       ret = alarmmgr_init(appid);
+       ret = alarmmgr_init(g_appid);
        if (ret < 0)
                return ret;