Divide logic to invoke some focus functions within main context 45/113645/4
authorSangchul Lee <sc11.lee@samsung.com>
Wed, 8 Feb 2017 05:29:50 +0000 (14:29 +0900)
committerSangchul Lee <sc11.lee@samsung.com>
Thu, 9 Feb 2017 07:07:04 +0000 (16:07 +0900)
This is applied to mm_sound_unset_focus_watch_callback()/mm_sound_unregister_focus()

[Version] 0.10.89
[Profile] Common
[Issue Type] Enhancement

Change-Id: I19dc2cc6b4b980c4d02efbc69ef7c35dd1cd21b7
Signed-off-by: Sangchul Lee <sc11.lee@samsung.com>
include/mm_sound_client.h
mm_sound_client.c
mm_sound_focus.c
packaging/libmm-sound.spec

index 486711a..cd777ca 100644 (file)
 #include "mm_sound_device.h"
 #ifdef USE_FOCUS
 #include "mm_sound_focus.h"
+typedef enum {
+       IDLE_EVENT_TYPE_UNSET_FOCUS_WATCH_CB,
+       IDLE_EVENT_TYPE_UNREGISTER_FOCUS,
+       IDLE_EVENT_TYPE_MAX
+} focus_idle_event_type_e;
 #endif
 
 //#define MEMTYPE_TRANS_PER_MAX (1024 * 1024) /* 1MB */
@@ -62,6 +67,7 @@ int mm_sound_client_acquire_focus(int id, mm_sound_focus_type_e type, int option
 int mm_sound_client_release_focus(int id, mm_sound_focus_type_e type, int option, const char *ext_info);
 int mm_sound_client_set_focus_watch_callback(int pid, mm_sound_focus_type_e type, mm_sound_focus_changed_watch_cb callback, bool is_for_session, void* user_data, int *id);
 int mm_sound_client_unset_focus_watch_callback(int id);
+int mm_sound_client_execute_focus_func_in_main_context(focus_idle_event_type_e type, int data);
 #endif
 
 int mm_sound_client_add_test_callback(mm_sound_test_cb func, void* user_data, unsigned int *subs_id);
index 6c46fe2..1b9b59f 100644 (file)
@@ -120,7 +120,9 @@ GMainLoop *g_focus_loop;
 focus_sound_info_t g_focus_sound_handle[FOCUS_HANDLE_MAX];
 focus_session_interrupt_info_t g_focus_session_interrupt_info = {NULL, NULL};
 static pthread_mutex_t g_index_mutex = PTHREAD_MUTEX_INITIALIZER;
-guint g_focus_signal_handle = 0;
+static pthread_mutex_t g_event_mutex = PTHREAD_MUTEX_INITIALIZER;
+guint g_focus_signal_handle;
+guint g_idle_event_src;
 #endif
 
 gboolean g_need_emergent_exit = FALSE;
@@ -132,6 +134,11 @@ typedef struct {
        unsigned subs_id;
 } play_sound_end_callback_data_t;
 
+typedef struct _focus_idle_event {
+       focus_idle_event_type_e type;
+       int data;
+} focus_idle_event_t;
+
 void _system_signal_handler(int signo)
 {
        int ret = MM_ERROR_NONE;
@@ -193,6 +200,7 @@ int mm_sound_client_initialize(void)
        debug_fenter();
 
        mm_sound_proxy_initialize();
+       g_idle_event_src = 0;
 
 
        struct sigaction system_action;
@@ -246,6 +254,12 @@ int mm_sound_client_finalize(void)
                g_focus_thread = NULL;
        }
 
+       if (g_idle_event_src > 0) {
+               MMSOUND_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_event_mutex, MM_ERROR_SOUND_INTERNAL);
+               g_source_remove(g_idle_event_src);
+               MMSOUND_LEAVE_CRITICAL_SECTION(&g_event_mutex);
+       }
+
 #endif
 
        debug_fleave();
@@ -1959,6 +1973,63 @@ cleanup:
        debug_fleave();
        return ret;
 }
+
+static gboolean _idle_event_callback(void *data)
+{
+       focus_idle_event_t *idle_event_data = (focus_idle_event_t*)data;
+       int ret = MM_ERROR_NONE;
+
+       if (data == NULL) {
+               debug_error("data is null");
+               return FALSE;
+       }
+
+       debug_msg("idle_event_data(%p): type(%d), data(%d)",
+               idle_event_data, idle_event_data->type, idle_event_data->data);
+
+       switch (idle_event_data->type) {
+       case IDLE_EVENT_TYPE_UNSET_FOCUS_WATCH_CB:
+               if ((ret = mm_sound_client_unset_focus_watch_callback(idle_event_data->data)))
+                       debug_error("Could not unset focus watch callback, id(%d), ret = %x\n", idle_event_data->data, ret);
+               break;
+       case IDLE_EVENT_TYPE_UNREGISTER_FOCUS:
+               if ((ret = mm_sound_client_unregister_focus(idle_event_data->data)))
+                       debug_error("Could not unregister focus, id(%d), ret = %x\n", idle_event_data->data, ret);
+               break;
+       default:
+               debug_warning("invalid type(%d)", idle_event_data->type);
+               break;
+       }
+
+       g_free(idle_event_data);
+
+       g_idle_event_src = 0;
+
+       MMSOUND_LEAVE_CRITICAL_SECTION(&g_event_mutex);
+
+       return FALSE;
+}
+
+int mm_sound_client_execute_focus_func_in_main_context(focus_idle_event_type_e type, int data)
+{
+       focus_idle_event_t *idle_event_data = NULL;
+
+       if (IDLE_EVENT_TYPE_UNSET_FOCUS_WATCH_CB > type || IDLE_EVENT_TYPE_MAX < type)
+               return MM_ERROR_INVALID_ARGUMENT;
+
+       MMSOUND_ENTER_CRITICAL_SECTION_WITH_RETURN(&g_event_mutex, MM_ERROR_SOUND_INTERNAL);
+
+       idle_event_data = g_new0(focus_idle_event_t, 1);
+       idle_event_data->type = type;
+       idle_event_data->data = data;
+
+       g_idle_event_src = g_idle_add_full(G_PRIORITY_HIGH,
+                               (GSourceFunc)_idle_event_callback,
+                               (gpointer)idle_event_data,
+                               NULL);
+
+       return MM_ERROR_NONE;
+}
 #endif
 
 
index 4dccbbc..9cec2e9 100644 (file)
@@ -165,19 +165,21 @@ EXPORT_API
 int mm_sound_unregister_focus(int id)
 {
        int ret = MM_ERROR_NONE;
+       bool result = false;
 
        debug_fenter();
 
-       RETURN_ERROR_IF_FOCUS_CB_THREAD(g_thread_self());
-
        if (id < 0) {
                debug_error("argument is not valid\n");
                return MM_ERROR_INVALID_ARGUMENT;
        }
 
-       ret = mm_sound_client_unregister_focus(id);
-       if (ret) {
-               debug_error("Could not unregister focus, ret = %x\n", ret);
+       mm_sound_client_is_focus_cb_thread(g_thread_self(), &result);
+       if (!result) {
+               if ((ret = mm_sound_client_unregister_focus(id)))
+                       debug_error("Could not unregister focus, ret = %x\n", ret);
+       } else {
+               ret = mm_sound_client_execute_focus_func_in_main_context(IDLE_EVENT_TYPE_UNREGISTER_FOCUS, id);
        }
 
        debug_fleave();
@@ -425,14 +427,21 @@ EXPORT_API
 int mm_sound_unset_focus_watch_callback(int id)
 {
        int ret = MM_ERROR_NONE;
+       bool result = false;
 
        debug_fenter();
 
-       RETURN_ERROR_IF_FOCUS_CB_THREAD(g_thread_self());
+       if (id < 0) {
+               debug_error("argument is not valid\n");
+               return MM_ERROR_INVALID_ARGUMENT;
+       }
 
-       ret = mm_sound_client_unset_focus_watch_callback(id);
-       if (ret) {
-               debug_error("Could not unset focus watch callback, id(%d), ret = %x\n", id, ret);
+       mm_sound_client_is_focus_cb_thread(g_thread_self(), &result);
+       if (!result) {
+               if ((ret = mm_sound_client_unset_focus_watch_callback(id)))
+                       debug_error("Could not unset focus watch callback, id(%d), ret = %x\n", id, ret);
+       } else {
+               ret = mm_sound_client_execute_focus_func_in_main_context(IDLE_EVENT_TYPE_UNSET_FOCUS_WATCH_CB, id);
        }
 
        debug_fleave();
index 46d9b7c..3e02c49 100644 (file)
@@ -1,6 +1,6 @@
 Name:       libmm-sound
 Summary:    MMSound Package contains client lib and sound_server binary
-Version:    0.10.88
+Version:    0.10.89
 Release:    0
 Group:      System/Libraries
 License:    Apache-2.0