heart : sync thread no more reply D-Bus message 29/108329/5
authorKichan Kwon <k_c.kwon@samsung.com>
Wed, 4 Jan 2017 05:27:51 +0000 (14:27 +0900)
committerKichan Kwon <k_c.kwon@samsung.com>
Thu, 5 Jan 2017 04:02:45 +0000 (13:02 +0900)
- D-Bus methods using same path are not thread-safe
- Sync thread will invoke main thread to finish its work by using pipe

Change-Id: I81f917a7abc905aa483b19e465564012744f4e5d
Signed-off-by: Kichan Kwon <k_c.kwon@samsung.com>
src/heart/heart-cpu.c
src/heart/include/logging.h
src/heart/logging.c

index f6a6aff..f34d8ff 100644 (file)
@@ -1418,10 +1418,9 @@ static DBusMessage *edbus_heart_sync_cpu_data(E_DBus_Object *obj, DBusMessage *m
 
        reply = dbus_message_new_method_return(msg);
 
-       ret = logging_sync_and_reply(reply);
+       ret = logging_sync(reply);
        if (!ret)
                return NULL;
-       ret = -ret;
 
        dbus_message_iter_init_append(reply, &iter);
        dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
index f9862ac..d855ff5 100644 (file)
@@ -131,7 +131,7 @@ int logging_read_foreach(char *name, char *appid, char *pkgid,
                time_t start_time, time_t end_time, logging_info_cb callback, void *user_data);
 void logging_update(int force);
 void logging_save_to_storage(int force);
-int logging_sync_and_reply(DBusMessage *reply);
+int logging_sync(DBusMessage *reply);
 int logging_leveldb_put(char *key, unsigned int key_len, char *value, unsigned int value_len);
 int logging_leveldb_putv(char *key, unsigned int key_len, const char *fmt, ...);
 int logging_leveldb_read(char *key, unsigned int key_len, char *value, unsigned int value_len);
index 0617b5b..6f5c44e 100644 (file)
@@ -138,6 +138,10 @@ static leveldb_writeoptions_t *woptions;
 
 static struct logging_object *logging_instance = NULL;
 
+Ecore_Fd_Handler *sync_efd;
+static DBusMessage *sync_reply;
+static int sync_pipes[2] = {-1, -1};
+
 time_t logging_get_time(int clk_id)
 {
        struct timespec ts;
@@ -1307,11 +1311,43 @@ void logging_save_to_storage(int force)
        }
 }
 
+static Eina_Bool logging_sync_reply(void *arg, Ecore_Fd_Handler *fd_handler)
+{
+       int pipe_fd;
+       int ret = -1;
+       DBusMessageIter iter;
+
+       if (!ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ)) {
+               _E("ecore_main_fd_handler_active_get failed");
+               goto reply;
+       }
+
+       pipe_fd = ecore_main_fd_handler_fd_get(fd_handler);
+       if (pipe_fd < 0) {
+               _E("ecore_main_fd_handler_fd_get failed");
+               goto reply;
+       }
+
+       if (read(pipe_fd, &ret, sizeof(ret)) != sizeof(ret)) {
+               _E("Failed to read the return value of sync thread");
+               ret = -1;
+       }
+
+reply:
+       dbus_message_iter_init_append(sync_reply, &iter);
+       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
+
+       if (dbus_message_reply(sync_reply) != RESOURCED_ERROR_NONE)
+               _E("Failed to reply sync request");
+
+       dbus_message_unref(sync_reply);
+
+       return ECORE_CALLBACK_RENEW;
+}
+
 static void *logging_sync_thread_main(void *arg)
 {
        int ret = 0;
-       DBusMessage *reply = (DBusMessage *)arg;
-       DBusMessageIter iter;
 
        ret = pthread_mutex_lock(&logging_update_mutex);
        if (ret) {
@@ -1331,26 +1367,29 @@ static void *logging_sync_thread_main(void *arg)
        }
 
 reply:
+       if (write(sync_pipes[1], &ret, sizeof(ret)) != sizeof(ret))
+               _E("Failed to write the return value of sync thread");
 
        logging_sync_thread = 0;
 
-       dbus_message_iter_init_append(reply, &iter);
-       dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
-
-       if (dbus_message_reply(reply) != RESOURCED_ERROR_NONE)
-               _E("Failed to reply sync request");
-
-       return NULL;
+       pthread_exit(NULL);
 }
 
-int logging_sync_and_reply(DBusMessage *reply)
+int logging_sync(DBusMessage *reply)
 {
+       if (sync_pipes[1] < 0) {
+               _E("Pipe for sync function is not ready");
+               return -1;
+       }
+
        if (logging_sync_thread) {
                _I("logging sync thread %u is already running", (unsigned)logging_sync_thread);
                return logging_sync_thread;
        }
 
-       if (!pthread_create(&logging_sync_thread, NULL, (void *)logging_sync_thread_main, reply))
+       sync_reply = reply;
+
+       if (!pthread_create(&logging_sync_thread, NULL, (void *)logging_sync_thread_main, NULL))
                return 0;
 
        _E("Failed to create logging sync thread");
@@ -1497,6 +1536,9 @@ static void logging_thread_stop(void)
        ecore_timer_del(logging_update_timer);
        logging_update_timer = NULL;
 
+       /* Delete fd handler for sync thread */
+       ecore_main_fd_handler_del(sync_efd);
+
        /* Wait thread for working
         *
         * We can wait thread for finishing work by requesting lock
@@ -1589,6 +1631,19 @@ int logging_init(void *data)
        woptions = leveldb_writeoptions_create();
        leveldb_writeoptions_set_sync(woptions, 1);
 
+       /* Create and register pipe for sync function */
+       if (pipe(sync_pipes)) {
+               _E("Failed to create pipe");
+               return RESOURCED_ERROR_FAIL;
+       }
+       sync_efd = ecore_main_fd_handler_add(sync_pipes[0], ECORE_FD_READ,
+                       (Ecore_Fd_Cb)logging_sync_reply, NULL, NULL, NULL);
+       if (!sync_efd) {
+               _E("Failed to add pipe handler");
+               return RESOURCED_ERROR_FAIL;
+       }
+
+       /* Register notifier and timer */
        register_notifier(RESOURCED_NOTIFIER_LOGGING_START, logging_start);
        register_notifier(RESOURCED_NOTIFIER_POWER_OFF, logging_poweroff);
 
@@ -1611,6 +1666,9 @@ int logging_exit(void *data)
        unregister_notifier(RESOURCED_NOTIFIER_LOGGING_START, logging_start);
        unregister_notifier(RESOURCED_NOTIFIER_POWER_OFF, logging_poweroff);
 
+       close(sync_pipes[0]);
+       close(sync_pipes[1]);
+
        /* flush module cache */
        logging_save_to_storage(true);