*/
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;
}
}
+/* 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;
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);
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");
/* 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);
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);
}
-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;
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;
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);
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));