From 78f29c8baf0e3042395782a24357c57549a4756a Mon Sep 17 00:00:00 2001 From: Eunhae Choi Date: Fri, 3 Feb 2017 12:01:06 +0900 Subject: [PATCH] [v0.3.46] remove the idle ev if the cb is unset Change-Id: I13a21f5f637401fa95ecc405c408ef816def4ff6 --- packaging/capi-media-player.spec | 2 +- src/player.c | 65 +++++++++++++++++++++++++++++----------- 2 files changed, 49 insertions(+), 18 deletions(-) diff --git a/packaging/capi-media-player.spec b/packaging/capi-media-player.spec index 18b2db7..14f8ac9 100644 --- a/packaging/capi-media-player.spec +++ b/packaging/capi-media-player.spec @@ -1,6 +1,6 @@ Name: capi-media-player Summary: A Media Player API -Version: 0.3.45 +Version: 0.3.46 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/player.c b/src/player.c index 386dfff..127cdf4 100755 --- a/src/player.c +++ b/src/player.c @@ -78,12 +78,15 @@ typedef struct { */ static int _player_deinit_memory_buffer(player_cli_s * pc); static void _player_event_queue_add(player_event_queue * ev, _player_cb_data * data); +static bool _player_need_sync_context(int event_id); +static void _player_remove_idle_event(callback_cb_info_s *cb_info, muse_player_event_e event_type, bool remove_all); #ifdef TIZEN_FEATURE_EVAS_RENDERER typedef void (*player_retrieve_buffer_cb)(void *user_data); static void __retrieve_buffer_cb(void *user_data); static int __player_set_retrieve_buffer_cb(player_h player, player_retrieve_buffer_cb callback, void *user_data); static int __player_unset_retrieve_buffer_cb(player_h player); #endif + int _player_media_packet_finalize(media_packet_h pkt, int error_code, void *user_data) { int ret = MEDIA_PACKET_FINALIZE; @@ -431,6 +434,9 @@ static void set_null_user_cb(callback_cb_info_s * cb_info, muse_player_event_e e } } +/* Notice : have to be called via API to avoid deadlock + * to clear the cb setting at the cb thread, set_null_user_cb() have to be called instead. + */ static void set_null_user_cb_lock(callback_cb_info_s * cb_info, muse_player_event_e event) { bool lock = g_thread_self() != cb_info->event_queue.thread; @@ -438,7 +444,10 @@ static void set_null_user_cb_lock(callback_cb_info_s * cb_info, muse_player_even if (lock) g_mutex_lock(&cb_info->event_queue.mutex); - set_null_user_cb(cb_info, event); + if (_player_need_sync_context(event)) + _player_remove_idle_event(cb_info, event, false); + else + set_null_user_cb(cb_info, event); if (lock) g_mutex_unlock(&cb_info->event_queue.mutex); @@ -1126,6 +1135,7 @@ static void (*_user_callbacks[MUSE_PLAYER_EVENT_TYPE_NUM]) (callback_cb_info_s * gboolean _player_event_job_function(void *user_data) { _player_cb_data *data = (_player_cb_data *)user_data; + muse_player_event_e ev; if (data == NULL) { LOGE("data is null"); @@ -1135,8 +1145,13 @@ gboolean _player_event_job_function(void *user_data) /* LOGD("enter ev:%d", data->int_data); */ g_mutex_lock(&data->event_mutex); + ev = data->int_data; - muse_player_event_e ev = data->int_data; + if (data->cb_info == NULL) { + /* tried to remove before at _player_remove_idle_event */ + LOGW("cb_info is NULL. event %d", data->int_data); + goto DONE; + } /* remove event from list */ g_mutex_lock(&data->cb_info->event_queue.idle_ev_mutex); @@ -1151,6 +1166,7 @@ gboolean _player_event_job_function(void *user_data) else LOGW("user callback is unset. type : %d", ev); +DONE: /* unlock and release event */ g_mutex_unlock(&data->event_mutex); g_mutex_clear(&data->event_mutex); @@ -1263,7 +1279,7 @@ static gboolean _player_event_queue_new(callback_cb_info_s * cb_info) } -static void _player_remove_idle_event_all(callback_cb_info_s *cb_info) +static void _player_remove_idle_event(callback_cb_info_s *cb_info, muse_player_event_e event_type, bool remove_all) { g_return_if_fail(cb_info); player_event_queue *ev = &cb_info->event_queue; @@ -1277,6 +1293,8 @@ static void _player_remove_idle_event_all(callback_cb_info_s *cb_info) GList *list = NULL; list = ev->idle_ev_list; + LOGD("remove idle event [%d] or all[%d]", event_type, remove_all); + while (list) { event_data = list->data; @@ -1288,26 +1306,39 @@ static void _player_remove_idle_event_all(callback_cb_info_s *cb_info) bool ret = FALSE; list = g_list_next(list); - ret = g_idle_remove_by_data(event_data); - LOGD("remove idle event [%p], ret[%d]", event_data, ret); + if (remove_all || (event_data->int_data == event_type)) { - if (ret == FALSE) { - event_data->cb_info = NULL; - LOGW("idle callback for event %p will be called later", event_data); - } + LOGD("remove idle event [%p:%d]", event_data, event_data->int_data); - ev->idle_ev_list = g_list_remove(ev->idle_ev_list, (gpointer)event_data); + ret = g_idle_remove_by_data(event_data); + if (ret == FALSE) { + /* will be handled at _player_event_job_function() as an exception */ + event_data->cb_info = NULL; + LOGW("failed to remove, idle callback will be called later"); + } else { + /* set cb to null */ + set_null_user_cb(cb_info, event_data->int_data); + } + + ev->idle_ev_list = g_list_remove(ev->idle_ev_list, (gpointer)event_data); - g_mutex_unlock(&event_data->event_mutex); + g_mutex_unlock(&event_data->event_mutex); - if (ret == TRUE) { - g_mutex_clear(&event_data->event_mutex); + if (ret == TRUE) { + g_mutex_clear(&event_data->event_mutex); - g_free(event_data); - event_data = NULL; + g_free(event_data); + event_data = NULL; - LOGD("remove idle event done"); + LOGD("remove idle event done"); + } /* else : will be handled if the cb is called. */ + + if (!remove_all) { + LOGD("remove idle [%d] event", event_type); + g_mutex_unlock(&ev->idle_ev_mutex); + return; + } } } else { LOGW("event(%d) lock failed. it's being called...", event_data->int_data); @@ -1842,7 +1873,7 @@ int player_destroy(player_h player) if (CALLBACK_INFO(pc)) { __player_remove_tsurf_list(pc); - _player_remove_idle_event_all(CALLBACK_INFO(pc)); + _player_remove_idle_event(CALLBACK_INFO(pc), MUSE_PLAYER_EVENT_TYPE_NUM, true); _player_event_queue_destroy(CALLBACK_INFO(pc)); tbm_bufmgr_deinit(TBM_BUFMGR(pc)); -- 2.7.4