#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();
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];
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];
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;
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);
return -1;
}
-#define LOOP_RUNNING_WAIT_TIME_MS 200
-int focus_init_context(int index)
+#define LOOP_RUNNING_WAIT_TIME_MS 2500
+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();
focus_context = g_main_context_new();
g_focus_sound_handle[index].focus_loop = g_main_loop_new(focus_context, FALSE);
- g_main_context_unref(focus_context);
+ g_main_context_unref(focus_context); /* FYI, this context resource will be released when calling g_main_loop_unref() */
if (g_focus_sound_handle[index].focus_loop == NULL) {
debug_error("could not create mainloop..");
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);
ERROR:
if (g_focus_sound_handle[index].focus_loop) {
+ if (*focus_cb_thread) {
+ g_main_loop_quit(g_focus_sound_handle[index].focus_loop);
+ 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;
}
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) {
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();
}