common : userinfo-list refactoring 36/103436/8
authorKichan Kwon <k_c.kwon@samsung.com>
Thu, 8 Dec 2016 06:47:04 +0000 (15:47 +0900)
committerKwon <k_c.kwon@samsung.com>
Mon, 12 Dec 2016 10:25:41 +0000 (02:25 -0800)
- At a time, only one user_list is existed
- Each module using this no more have to worry about memory leak
- Replace from hash table to array because few user is existed in current

Change-Id: I152915072025afd9ecb898a8077bd99f5f281cfc
Signed-off-by: Kichan Kwon <k_c.kwon@samsung.com>
src/common/storage-helper.c
src/common/userinfo-list.c
src/common/userinfo-list.h
src/heart/heart-cpu.c
src/heart/logging.c

index ec43863..42751d4 100644 (file)
@@ -76,34 +76,29 @@ resourced_ret_c get_storage_root_paths(int type, GSList **paths)
 {
        struct rd_storage target;
        char *root_path;
-       GHashTable *user_table = NULL;
-       GHashTableIter iter;
-       gpointer key, value;
-       int *uid;
+       const GArray *user_list = NULL;
 
        switch (type) {
        case INTERNAL:
                _D("Start finding internal root path of all users");
-               if (get_all_users_info(&user_table) != RESOURCED_ERROR_NONE) {
+               user_list = userinfo_get_list();
+               if (!user_list) {
                        _E("Fail to get user list");
                        return RESOURCED_ERROR_FAIL;
                }
 
-               g_hash_table_iter_init(&iter, user_table);
-               while (g_hash_table_iter_next(&iter, &key, &value)) {
-                       uid = (int*)key;
-                       tzplatform_set_user(*uid);
+               userinfo_for_each(elem, user_list) {
+                       tzplatform_set_user(elem->uid);
                        root_path = strdup(tzplatform_getenv(TZ_USER_CONTENT));
                        tzplatform_reset_user();
                        if (!root_path)
-                               _E("Fail to get content path of uid %d", *uid);
+                               _E("Fail to get content path of uid %d", elem->uid);
 
                        if (!access(root_path, R_OK)) {
                                _D("Find new root path : %s", root_path);
                                *paths = g_slist_append(*paths, root_path);
                        }
                }
-               g_hash_table_destroy(user_table);
                break;
        case EXTERNAL:
                _D("Start finding external root path");
index 3a4d96a..57e769b 100644 (file)
  * @desc define helper functions to get user info.
  **/
 
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <gum/gum-user.h>
+#include <gum/gum-user-service.h>
+
 #include "trace.h"
 #include "userinfo-list.h"
 
-void free_user_data(gpointer data)
+static GArray *user_list = NULL;
+
+static void userinfo_free_list(void)
 {
-       if (data)
-               free(data);
+       int i;
+       struct user_info *elem;
+
+       if (user_list) {
+               for (i = 0; i < user_list->len; i++) {
+                       elem = g_array_index(user_list, struct user_info*, i);
+                       free(elem);
+               }
+               g_array_free(user_list, TRUE);
+               user_list = NULL;
+       }
 }
 
-resourced_ret_c get_all_users_info(GHashTable **table)
+static resourced_ret_c userinfo_update_list(void)
 {
        GumUserService *gus = NULL;
        GumUserList *users = NULL;
        GumUserList *iter = NULL;
        GumUser *user = NULL;
        gchar **query;
-       gint *uid = NULL;
+
+       struct user_info *elem;
+       uid_t uid;
        gchar *home_dir = NULL;
 
        /* Get user data by using libgum */
        gus = gum_user_service_create_sync(TRUE);
-       if (!gus) {
-               printf("Fail to create gum user service");
+       if (!gus)
                return RESOURCED_ERROR_FAIL;
-       }
 
        query = g_strsplit("admin,normal", ",", -1);
 
@@ -55,44 +73,31 @@ resourced_ret_c get_all_users_info(GHashTable **table)
 
        if (!users) {
                g_object_unref(gus);
-
-               if (!(*table)) {
-                       _E("Fail to get gum user list");
-                       return RESOURCED_ERROR_FAIL;
-               }
-               _D("Fail to get gum user list. Use existing user list.");
-               return RESOURCED_ERROR_NONE;
+               return RESOURCED_ERROR_FAIL;
        }
 
-       /* Remove old list */
-       if (*table)
-               g_hash_table_destroy(*table);
-
-       /* Initialize user table */
-       *table = g_hash_table_new_full(
-                       g_int_hash,
-                       g_str_equal,
-                       free_user_data,
-                       free_user_data);
+       /* Remove old user list */
+       userinfo_free_list();
 
-       if (!(*table)) {
-               _E("Fail to create hash table");
-               gum_user_service_list_free(users);
-               g_object_unref(gus);
-               return RESOURCED_ERROR_FAIL;
-       }
+       /* Make new user list */
+       user_list = g_array_new(FALSE, FALSE, sizeof(struct user_info*));
+       if (!user_list)
+               return RESOURCED_ERROR_OUT_OF_MEMORY;
 
-       /* Insert user data in the table */
        iter = users;
        for (; iter != NULL; iter = g_list_next(iter)) {
                user = (GumUser*) iter->data;
-               uid = (gint*)malloc(sizeof(gint));
-               g_object_get(G_OBJECT(user), "uid", uid, NULL);
+               g_object_get(G_OBJECT(user), "uid", &uid, NULL);
                g_object_get(G_OBJECT(user), "homedir", &home_dir, NULL);
 
-               g_hash_table_insert(*table,
-                               (gpointer)uid,
-                               g_strndup(home_dir, strlen(home_dir)));
+               elem = malloc(sizeof(struct user_info));
+               elem->uid = uid;
+               snprintf(elem->home_dir, PATH_MAX, "%s", home_dir);
+
+               g_array_append_val(user_list, elem);
+
+               if (home_dir)
+                       free(home_dir);
        }
 
        gum_user_service_list_free(users);
@@ -100,3 +105,33 @@ resourced_ret_c get_all_users_info(GHashTable **table)
 
        return RESOURCED_ERROR_NONE;
 }
+
+const char *userinfo_find_home_dir(uid_t uid)
+{
+       int i;
+       struct user_info *elem;
+
+       if (userinfo_update_list() != RESOURCED_ERROR_NONE)
+               return NULL;
+
+       for (i = 0; i < user_list->len; i++) {
+               elem = g_array_index(user_list, struct user_info*, i);
+
+               if (elem->uid == uid)
+                       return elem->home_dir;
+       }
+       return NULL;
+}
+
+const GArray *userinfo_get_list(void)
+{
+       if (userinfo_update_list() == RESOURCED_ERROR_NONE)
+               return user_list;
+       else
+               return NULL;
+}
+
+static void __attribute__ ((destructor)) userinfo_exit(void)
+{
+       userinfo_free_list();
+}
index e68ca81..ce24113 100644 (file)
 #ifndef __USERINFO_LIST_H__
 #define __USERINFO_LIST_H__
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
+#include <linux/limits.h>
 #include <glib.h>
-#include <gum/gum-user.h>
-#include <gum/gum-user-service.h>
 
 #include "resourced.h"
 
+#define DEFAULT_USER_SIZE  16
+#define USER_BASE_UID      5001
+
+#define userinfo_for_each(elem, list)  \
+       guint _ui_idx;  \
+       struct user_info *elem; \
+       for (_ui_idx = 0;       \
+               _ui_idx < list->len && (elem = g_array_index(list, struct user_info*, _ui_idx));        \
+               _ui_idx++)      \
+
+struct user_info {
+       uid_t uid;
+       char home_dir[PATH_MAX];
+};
+
 /**
- * @brief  Gets all users' information
- *
- * @param[out]  table : hash table of user list (key = uid, value = home directory)
- *
- * @retval  #RESOURCED_ERROR_NONE : successfully called
- * @retval  #RESOURCED_ERROR_FAIL : fail to get user information
+ * @brief          Find home directory
+ * @detail         Return home directory of the user having uid
+ * @param[in] uid  UID of user
+ * @retval NULL    Fail to find
+ * @retval else    Home directory of user
+ */
+const char *userinfo_find_home_dir(uid_t uid);
+
+/**
+ * @brief        Get user_list
+ * @detail       Return user_list(pid, home_dir) after updating
+ * @retval NULL  Fail to get user_list
+ * @retval else  user_list
  */
-resourced_ret_c get_all_users_info(GHashTable **table);
+const GArray *userinfo_get_list(void);
 
 #endif /*__USERINFO_LIST_H__*/
index 788cbdb..90f5a56 100644 (file)
@@ -88,7 +88,6 @@ struct heart_cpu_dat_cache {
 
 static GHashTable *heart_cpu_app_list;
 static pthread_mutex_t heart_cpu_mutex = PTHREAD_MUTEX_INITIALIZER;
-static GHashTable *user_table = NULL;
 
 static void heart_cpu_remove_last_pid_info_exited(struct heart_cpu_table *table)
 {
@@ -625,6 +624,7 @@ static int heart_cpu_hashtable_renew(GHashTable *hashtable, time_t now)
 
 void heart_cpu_update(struct logging_table_form *data, void *user_data)
 {
+       const char *path;
        int ret;
        pid_t pid;
        int state;
@@ -635,22 +635,17 @@ void heart_cpu_update(struct logging_table_form *data, void *user_data)
        struct heart_cpu_info *ci = NULL;
        struct heart_cpu_dat_cache *cache;
        GHashTable *cpu_usage_list = NULL;
-       char *path;
 
        cache = (struct heart_cpu_dat_cache*)g_hash_table_lookup(
                        heart_cpu_app_list, (gconstpointer)(&(data->uid)));
        if (!cache) {
-               if (get_all_users_info(&user_table) != RESOURCED_ERROR_NONE) {
-                       _E("Fail to get user table");
-                       return;
-               }
-               path = (char*)g_hash_table_lookup(user_table, (gconstpointer)(&(data->uid)));
+               path = userinfo_find_home_dir((uid_t)data->uid);
                if (!path) {
                        _E("uid %d doesn't existed", data->uid);
                        return;
                }
                cache = (struct heart_cpu_dat_cache*)malloc(sizeof(struct heart_cpu_dat_cache));
-               cache->path = strndup((char*)path, strlen((char*)path));
+               cache->path = strndup(path, strlen(path));
                cache->list = g_hash_table_new_full(
                                g_str_hash,
                                g_str_equal,
@@ -1455,10 +1450,9 @@ static int heart_cpu_reset(void *data)
 
 static int heart_cpu_init(void *data)
 {
+       const GArray *user_list = NULL;
        int ret;
-       GHashTableIter iter;
-       gpointer key, value;
-       int *uid;
+       uid_t *uid;
        struct heart_cpu_dat_cache *cache;
 
        ret = logging_module_init(CPU_NAME, ONE_DAY, TEN_MINUTE, heart_cpu_update, TEN_MINUTE, USER_DEFAULT);
@@ -1467,7 +1461,8 @@ static int heart_cpu_init(void *data)
                return RESOURCED_ERROR_FAIL;
        }
 
-       if (get_all_users_info(&user_table) != RESOURCED_ERROR_NONE) {
+       user_list = userinfo_get_list();
+       if (!user_list) {
                _E("Fail to get user table");
                return RESOURCED_ERROR_FAIL;
        }
@@ -1479,10 +1474,9 @@ static int heart_cpu_init(void *data)
                                heart_cpu_free_uid,
                                heart_cpu_free_dat_cache);
 
-               g_hash_table_iter_init(&iter, user_table);
-               while (g_hash_table_iter_next(&iter, &key, &value)) {
+               userinfo_for_each(elem, user_list) {
                        cache = (struct heart_cpu_dat_cache*)malloc(sizeof(struct heart_cpu_dat_cache));
-                       cache->path = strndup((char*)value, strlen((char*)value));
+                       cache->path = strndup(elem->home_dir, strlen(elem->home_dir));
                        cache->list = g_hash_table_new_full(
                                        g_str_hash,
                                        g_str_equal,
@@ -1497,8 +1491,8 @@ static int heart_cpu_init(void *data)
 
                        cache->last_file_commit_time = logging_get_time(CLOCK_BOOTTIME);
 
-                       uid = (int*)malloc(sizeof(int));
-                       *uid = *((int*)key);
+                       uid = malloc(sizeof(uid_t));
+                       *uid = elem->uid;
                        g_hash_table_insert(heart_cpu_app_list, (gpointer)uid, (gpointer)cache);
                }
        }
index 6b2d7b2..c48507e 100644 (file)
@@ -141,8 +141,6 @@ static leveldb_writeoptions_t *woptions;
 
 static struct logging_object *logging_instance = NULL;
 
-static GHashTable *user_table = NULL;
-
 time_t logging_get_time(int clk_id)
 {
        struct timespec ts;
@@ -270,15 +268,14 @@ int logging_get_default_db(char *name, sqlite3 *db)
 
 static int logging_update_user_db_list(char *name, enum logging_db_type type, GHashTable **db_list)
 {
-       GHashTableIter iter;
-       gpointer key, value;
-       int *uid;
-       char *home_dir;
+       const GArray *user_list = NULL;
+       uid_t *uid;
        char path[LOGGING_BUF_MAX];
        sqlite3 *file = NULL;
        struct logging_db *db_elem;
 
-       if (get_all_users_info(&user_table) != RESOURCED_ERROR_NONE) {
+       user_list = userinfo_get_list();
+       if (!user_list) {
                _E("Fail to get user table");
                return RESOURCED_ERROR_FAIL;
        }
@@ -292,20 +289,17 @@ static int logging_update_user_db_list(char *name, enum logging_db_type type, GH
                return RESOURCED_ERROR_FAIL;
        }
 
-       g_hash_table_iter_init(&iter, user_table);
-       while (g_hash_table_iter_next(&iter, &key, &value)) {
-               home_dir = (char*)value;
-
+       userinfo_for_each(elem, user_list) {
                switch (type) {
                case USER_DEFAULT:
-                       snprintf(path, LOGGING_BUF_MAX, USER_DEFAULT_DB_NAME, home_dir);
+                       snprintf(path, LOGGING_BUF_MAX, USER_DEFAULT_DB_NAME, elem->home_dir);
                        break;
                case USER_OWN:
                        if (!name) {
                                _E("You must write name to create your own DB");
                                return RESOURCED_ERROR_INVALID_PARAMETER;
                        }
-                       snprintf(path, LOGGING_BUF_MAX, USER_OWN_DB_NAME, home_dir, name);
+                       snprintf(path, LOGGING_BUF_MAX, USER_OWN_DB_NAME, elem->home_dir, name);
                        break;
                default:
                        _E("HEART-%s doesn't use per-user DB", name);
@@ -318,8 +312,8 @@ static int logging_update_user_db_list(char *name, enum logging_db_type type, GH
                        return RESOURCED_ERROR_DB_FAILED;
                }
 
-               uid = (int*)malloc(sizeof(int));
-               *uid = *((int*)key);
+               uid = malloc(sizeof(uid_t));
+               *uid = elem->uid;
                db_elem = (struct logging_db*)malloc(sizeof(struct logging_db));
                db_elem->path = strndup(path, strlen(path));
                db_elem->file = file;
@@ -1435,8 +1429,7 @@ static Eina_Bool logging_send_signal_to_update(void *data)
        int ret;
        DIR *dir_info;
 
-       GHashTableIter iter;
-       gpointer key, value;
+       const GArray *user_list = NULL;
        char path[128];
 
        dir_info = opendir(LOGGING_FILE_PATH);
@@ -1452,14 +1445,14 @@ static Eina_Bool logging_send_signal_to_update(void *data)
                }
        }
 
-       if (get_all_users_info(&user_table) != RESOURCED_ERROR_NONE) {
+       user_list = userinfo_get_list();
+       if (!user_list) {
                _E("Fail to get user table");
                return ECORE_CALLBACK_RENEW;
        }
 
-       g_hash_table_iter_init(&iter, user_table);
-       while (g_hash_table_iter_next(&iter, &key, &value)) {
-               snprintf(path, 128, HEART_USER_FILE_PATH, (char*)value);
+       userinfo_for_each(elem, user_list) {
+               snprintf(path, 128, HEART_USER_FILE_PATH, elem->home_dir);
                dir_info = opendir(path);
 
                if (dir_info)