Support gcov build for coverage check
[platform/core/multimedia/libmm-sound.git] / mm_sound_focus_private.c
index 98b06a7..933b025 100644 (file)
@@ -28,6 +28,7 @@
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <unistd.h>
+#include <stdlib.h>
 
 #include <mm_debug.h>
 #include <mm_error.h>
 
 focus_sound_info_t g_focus_sound_handle[FOCUS_HANDLE_MAX];
 
+static void unlink_if_symbolic_link(const char *path)
+{
+       int ret = 0;
+       char *resolved_path = NULL;
+
+       if (path == NULL)
+               return;
+
+       /* return if it does not exist */
+       if ((ret = access(path, F_OK)))
+               return;
+
+       if ((resolved_path = realpath(path, NULL))) {
+               /* assume that the path paramether is an absolute path */
+               if (strcmp(path, resolved_path)) {
+                       debug_warning("unexpected symbolic link!, unlink the symbolic link(%s) to the resolved path(%s)", path, resolved_path);
+                       unlink(path);
+               }
+               free(resolved_path);
+       } else {
+               char str_error[256];
+               strerror_r(errno, str_error, sizeof(str_error));
+               debug_warning("failed to realpath() for path:%s, err:%s", path, str_error);
+       }
+}
+
 static gpointer _focus_thread_func(gpointer data)
 {
        unsigned int thread_id = (unsigned int)pthread_self();
@@ -137,6 +164,8 @@ static gboolean _focus_callback_handler(gpointer user_data)
                        int tmpfd = -1;
                        unsigned int buf = 0;
                        char *filename2 = g_strdup_printf("/tmp/FOCUS.%d.%dr", focus_handle->focus_pid, cb_data.handle);
+
+                       unlink_if_symbolic_link(filename2);
                        tmpfd = open(filename2, O_WRONLY | O_NONBLOCK);
                        if (tmpfd < 0) {
                                char str_error[256];
@@ -224,6 +253,8 @@ SKIP_CB_AND_RET:
                        int tmpfd = -1;
                        int buf = -1;
                        char *filename2 = g_strdup_printf("/tmp/FOCUS.%d.%d.wchr", focus_handle->focus_pid, cb_data.handle);
+
+                       unlink_if_symbolic_link(filename2);
                        tmpfd = open(filename2, O_WRONLY | O_NONBLOCK);
                        if (tmpfd < 0) {
                                char str_error[256];
@@ -231,7 +262,8 @@ SKIP_CB_AND_RET:
                                debug_warning("[RETCB][Failed(May Server Close First)]tid(%d) fd(%d) %s errno=%d(%s)",
                                                        tid, tmpfd, filename2, errno, str_error);
                                g_free(filename2);
-                               g_mutex_unlock(&focus_handle->focus_lock);
+                               if (focus_handle->is_used)
+                                       g_mutex_unlock(&focus_handle->focus_lock);
                                return G_SOURCE_CONTINUE;
                        }
                        buf = cb_data.handle;
@@ -296,6 +328,7 @@ static void _focus_open_callback(int index, bool is_for_watching)
                                                                g_focus_sound_handle[index].focus_pid,
                                                                g_focus_sound_handle[index].handle);
        }
+       unlink_if_symbolic_link(filename);
        pre_mask = umask(0);
        if (mknod(filename, S_IFIFO|0666, 0))
                debug_error("mknod() failure, errno(%d)", errno);
@@ -538,10 +571,12 @@ int focus_watch_find_index_by_handle(int handle)
 }
 
 #define LOOP_RUNNING_WAIT_TIME_MS 2500
-int focus_init_context(int index)
+int focus_init_context(int index, bool is_for_watching)
 {
        int ret = MM_ERROR_NONE;
        GMainContext *focus_context;
+       GThread **focus_cb_thread = NULL;
+       char *focus_cb_thread_name;
 
        debug_fenter();
 
@@ -558,16 +593,24 @@ int focus_init_context(int index)
                goto ERROR;
        }
 
-       g_focus_sound_handle[index].focus_cb_thread = g_thread_new("focus-cb-thread",
+       if (is_for_watching) {
+               focus_cb_thread = &g_focus_sound_handle[index].focus_watch_cb_thread;
+               focus_cb_thread_name = "focus-watch-cb-thread";
+       } else {
+               focus_cb_thread = &g_focus_sound_handle[index].focus_cb_thread;
+               focus_cb_thread_name = "focus-cb-thread";
+       }
+
+       *focus_cb_thread = g_thread_new(focus_cb_thread_name,
                                                                        _focus_thread_func,
                                                                        g_focus_sound_handle[index].focus_loop);
-       if (g_focus_sound_handle[index].focus_cb_thread == NULL) {
+       if (*focus_cb_thread == NULL) {
                debug_error("could not create thread..");
                goto ERROR;
        }
 
-       debug_warning("focus cb thread[%p] with mainloop[%p] is created for index(%d)",
-                               g_focus_sound_handle[index].focus_cb_thread, g_focus_sound_handle[index].focus_loop, index);
+       debug_warning("focus cb thread[%p] with mainloop[%p] is created for index(%d), is_for_watching(%d)",
+                       *focus_cb_thread, g_focus_sound_handle[index].focus_loop, index, is_for_watching);
 
        if ((ret = _focus_loop_is_running_timed_wait(g_focus_sound_handle[index].focus_loop, LOOP_RUNNING_WAIT_TIME_MS))) {
                debug_error("failed to _focus_loop_is_running_timed_wait(), ret[0x%x]", ret);
@@ -580,12 +623,12 @@ int focus_init_context(int index)
 
 ERROR:
        if (g_focus_sound_handle[index].focus_loop) {
-               if (g_focus_sound_handle[index].focus_cb_thread) {
+               if (*focus_cb_thread) {
                        g_main_loop_quit(g_focus_sound_handle[index].focus_loop);
-                       g_thread_join(g_focus_sound_handle[index].focus_cb_thread);
-                       debug_warning("after thread join, thread[%p], mainloop[%p] for index(%d)",
-                                       g_focus_sound_handle[index].focus_cb_thread, g_focus_sound_handle[index].focus_loop, index);
-                       g_focus_sound_handle[index].focus_cb_thread = NULL;
+                       g_thread_join(*focus_cb_thread);
+                       debug_warning("after thread join, thread[%p], mainloop[%p] for index(%d), is_for_watching(%d)",
+                                       *focus_cb_thread, g_focus_sound_handle[index].focus_loop, index, is_for_watching);
+                       *focus_cb_thread = NULL;
                }
                g_main_loop_unref(g_focus_sound_handle[index].focus_loop);
                g_focus_sound_handle[index].focus_loop = NULL;
@@ -593,8 +636,10 @@ ERROR:
        return MM_ERROR_SOUND_INTERNAL;
 }
 
-void focus_deinit_context(int index)
+void focus_deinit_context(int index, bool is_for_watching)
 {
+       GThread **focus_cb_thread = NULL;
+
        debug_fenter();
 
        if (index < 0 || index >= FOCUS_HANDLE_MAX) {
@@ -602,19 +647,28 @@ void focus_deinit_context(int index)
                return;
        }
 
-       if (!g_focus_sound_handle[index].focus_loop || !g_focus_sound_handle[index].focus_cb_thread) {
-               debug_error("focus_loop[%p] or focus_cb_thread[%p] is null",
-                               g_focus_sound_handle[index].focus_loop, g_focus_sound_handle[index].focus_cb_thread);
+       if (!g_focus_sound_handle[index].focus_loop ||
+           (!is_for_watching && !g_focus_sound_handle[index].focus_cb_thread) ||
+               (is_for_watching && !g_focus_sound_handle[index].focus_watch_cb_thread)) {
+               debug_error("focus_loop[%p] or focus_cb_thread[%p] or focus_watch_cb_thread[%p] is null",
+                               g_focus_sound_handle[index].focus_loop, g_focus_sound_handle[index].focus_cb_thread,
+                               g_focus_sound_handle[index].focus_watch_cb_thread);
                return;
        }
 
        g_main_loop_quit(g_focus_sound_handle[index].focus_loop);
-       g_thread_join(g_focus_sound_handle[index].focus_cb_thread);
-       debug_warning("after thread join, thread[%p], mainloop[%p] for index(%d)",
-                       g_focus_sound_handle[index].focus_cb_thread, g_focus_sound_handle[index].focus_loop, index);
+
+       if (is_for_watching)
+               focus_cb_thread = &g_focus_sound_handle[index].focus_watch_cb_thread;
+       else
+               focus_cb_thread = &g_focus_sound_handle[index].focus_cb_thread;
+       g_thread_join(*focus_cb_thread);
+
+       debug_warning("after thread join, thread[%p], mainloop[%p] for index(%d), is_for_watching(%d)",
+                       *focus_cb_thread, g_focus_sound_handle[index].focus_loop, index, is_for_watching);
        g_main_loop_unref(g_focus_sound_handle[index].focus_loop);
        g_focus_sound_handle[index].focus_loop = NULL;
-       g_focus_sound_handle[index].focus_cb_thread = NULL;
+       *focus_cb_thread = NULL;
 
        debug_fleave();
 }