From: Hyongtaek Lim Date: Fri, 15 Jul 2016 08:58:06 +0000 (+0900) Subject: Apply server ack at handle creation X-Git-Tag: accepted/tizen/common/20160811.145648~1^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=78620e6eec89e3c041218316e6873efd49a83284;p=platform%2Fcore%2Fapi%2Fplayer.git Apply server ack at handle creation Change-Id: I4c852b935950b555be7fa7c7d8aea7a75da5826f Signed-off-by: Hyongtaek Lim --- diff --git a/include/common/player.h b/include/common/player.h old mode 100755 new mode 100644 diff --git a/include/player_private.h b/include/player_private.h index 925cdb7..ed4ccc4 100644 --- a/include/player_private.h +++ b/include/player_private.h @@ -45,8 +45,12 @@ extern "C" { #define PLAYER_NULL_ARG_CHECK(arg) \ PLAYER_CHECK_CONDITION(arg != NULL, PLAYER_ERROR_INVALID_PARAMETER, "PLAYER_ERROR_INVALID_PARAMETER") +#define CONNECTION_RETRY 51 +#define CONNECTION_TIME_OUT 50 /* ms */ +#define CREATE_CB_TIME_OUT 400 /* ms */ #define CALLBACK_TIME_OUT (5*1000) /* ms */ -#define MAX_SERVER_TIME_OUT 35 /* sec */ +#define MAX_SERVER_TIME_OUT 35000 /* ms */ + typedef struct _ret_msg_s { gint api; @@ -90,6 +94,7 @@ typedef struct _callback_cb_info { gpointer user_data[MUSE_PLAYER_EVENT_TYPE_NUM]; GMutex player_mutex; GCond player_cond[MUSE_PLAYER_API_MAX]; + GCond server_ack_cond; GMutex data_mutex; gboolean block_seek_cb; GMutex seek_cb_mutex; diff --git a/src/player.c b/src/player.c index 7207966..6133311 100644 --- a/src/player.c +++ b/src/player.c @@ -1191,6 +1191,11 @@ static void *client_cb_handler(gpointer data) g_mutex_unlock(&cb_info->player_mutex); if (muse_core_msg_json_object_get_value("event", jobj, &event, MUSE_TYPE_INT)) _user_callback_handler(cb_info, event, buffer); + } else if (api == MUSE_PLAYER_CB_CREATE_ACK) { + g_mutex_lock(&cb_info->player_mutex); + cb_info->buff.recved++; + g_cond_signal(&cb_info->server_ack_cond); + g_mutex_unlock(&cb_info->player_mutex); } } else { LOGE("Failed to get value. offset:%d/%d, [msg][ %s ]", offset, len, (recvMsg+offset)); @@ -1230,6 +1235,7 @@ static callback_cb_info_s *callback_new(gint sockfd) g_mutex_init(&cb_info->player_mutex); for (i = 0; i < MUSE_PLAYER_API_MAX; i++) g_cond_init(&cb_info->player_cond[i]); + g_cond_init(&cb_info->server_ack_cond); g_mutex_init(&cb_info->data_mutex); g_mutex_init(&cb_info->seek_cb_mutex); @@ -1268,6 +1274,7 @@ static void callback_destroy(callback_cb_info_s * cb_info) g_mutex_clear(&cb_info->player_mutex); for (i = 0; i < MUSE_PLAYER_API_MAX; i++) g_cond_clear(&cb_info->player_cond[i]); + g_cond_clear(&cb_info->server_ack_cond); g_mutex_clear(&cb_info->data_mutex); g_mutex_clear(&cb_info->seek_cb_mutex); @@ -1336,6 +1343,33 @@ int client_wait_for_cb_return(muse_player_api_e api, callback_cb_info_s * cb_inf return ret; } +int client_wait_for_server_ack(muse_player_api_e api, callback_cb_info_s * cb_info, int time_out) +{ + int ret = PLAYER_ERROR_NONE; + gint64 end_time = g_get_monotonic_time() + time_out * G_TIME_SPAN_MILLISECOND; + msg_buff_s *buff = &cb_info->buff; + + g_mutex_lock(&cb_info->player_mutex); + + if (!buff->recved) { + if (!g_cond_wait_until(&cb_info->server_ack_cond, &cb_info->player_mutex, end_time)) { + LOGW("server ack msg does not received %dms", time_out); + if (!buff->recved) + ret = PLAYER_ERROR_INVALID_OPERATION; + else + LOGD("Another msg is received, continue create handle"); + g_mutex_unlock(&cb_info->player_mutex); + return ret; + } + } + buff->recved--; + + g_mutex_unlock(&cb_info->player_mutex); + + return ret; +} + + /* * Public Implementation */ @@ -1352,64 +1386,84 @@ int player_create(player_h * player) muse_core_api_module_e module = MUSE_PLAYER; player_cli_s *pc = NULL; char *ret_buf = NULL; + int retry_count = CONNECTION_RETRY; + bool retry = false; LOGD("ENTER"); - sock_fd = muse_core_client_new(); - if (sock_fd <= INVALID_SOCKET) { - LOGE("connection failure %d", errno); - ret = PLAYER_ERROR_INVALID_OPERATION; - goto ERROR; - } - player_msg_create_handle(api, sock_fd, INT, module, INT, pid); - pc = g_new0(player_cli_s, 1); - if (pc == NULL) { - ret = PLAYER_ERROR_OUT_OF_MEMORY; - goto ERROR; - } + if (pc == NULL) + return PLAYER_ERROR_OUT_OF_MEMORY; - pc->cb_info = callback_new(sock_fd); - if (!pc->cb_info) { - LOGE("fail to create callback"); - ret = PLAYER_ERROR_INVALID_OPERATION; - goto ERROR; - } - if (!_player_event_queue_new(pc->cb_info)) { - LOGE("fail to create event queue"); - ret = PLAYER_ERROR_INVALID_OPERATION; - goto ERROR; - } + while (--retry_count) { + sock_fd = muse_core_client_new(); + if (sock_fd <= INVALID_SOCKET) { + LOGE("connection failure %d", errno); + ret = PLAYER_ERROR_INVALID_OPERATION; + retry = true; + usleep(CONNECTION_TIME_OUT * G_TIME_SPAN_MILLISECOND); + goto ERROR; + } - ret = client_wait_for_cb_return(api, pc->cb_info, &ret_buf, CALLBACK_TIME_OUT); - if (ret == PLAYER_ERROR_NONE) { - intptr_t module_addr; - *player = (player_h) pc; - if (player_msg_get_type(module_addr, ret_buf, POINTER)) { - pc->cb_info->data_fd = muse_core_client_new_data_ch(); - muse_core_send_module_addr(module_addr, pc->cb_info->data_fd); - LOGD("Data channel fd %d, muse module addr %p", pc->cb_info->data_fd, module_addr); + player_msg_create_handle(api, sock_fd, INT, module, INT, pid); + + pc->cb_info = callback_new(sock_fd); + if (!pc->cb_info) { + LOGE("fail to create callback"); + ret = PLAYER_ERROR_INVALID_OPERATION; + goto ERROR; } - SERVER_TIMEOUT(pc) = MAX_SERVER_TIME_OUT; /* will be update after prepare phase. */ - } else - goto ERROR; - pc->cb_info->bufmgr = tbm_bufmgr_init(-1); - pc->push_media_stream = FALSE; + ret = client_wait_for_server_ack(api, pc->cb_info, CREATE_CB_TIME_OUT); + if (ret == PLAYER_ERROR_INVALID_OPERATION) { + retry = true; + goto ERROR; + } + retry = false; - g_free(ret_buf); - return ret; + if (!_player_event_queue_new(pc->cb_info)) { + LOGE("fail to create event queue"); + ret = PLAYER_ERROR_INVALID_OPERATION; + goto ERROR; + } + + ret = client_wait_for_cb_return(api, pc->cb_info, &ret_buf, CALLBACK_TIME_OUT * 2); + if (ret == PLAYER_ERROR_NONE) { + intptr_t module_addr; + *player = (player_h) pc; + if (player_msg_get_type(module_addr, ret_buf, POINTER)) { + pc->cb_info->data_fd = muse_core_client_new_data_ch(); + muse_core_send_module_addr(module_addr, pc->cb_info->data_fd); + LOGD("Data channel fd %d, muse module addr %p", pc->cb_info->data_fd, module_addr); + } else { + ret = PLAYER_ERROR_INVALID_OPERATION; + goto ERROR; + } + SERVER_TIMEOUT(pc) = MAX_SERVER_TIME_OUT; /* will be update after prepare phase. */ + } else + goto ERROR; + + pc->cb_info->bufmgr = tbm_bufmgr_init(-1); + pc->push_media_stream = FALSE; + + g_free(ret_buf); + return ret; ERROR: - if (pc && pc->cb_info) { - if (pc->cb_info->event_queue.running) - _player_event_queue_destroy(pc->cb_info); - callback_destroy(pc->cb_info); - pc->cb_info = NULL; + if (pc && pc->cb_info) { + if (pc->cb_info->event_queue.running) + _player_event_queue_destroy(pc->cb_info); + callback_destroy(pc->cb_info); + pc->cb_info = NULL; + } + g_free(ret_buf); + ret_buf = NULL; + LOGE("ret value : %d, retry #%d", ret, CONNECTION_RETRY - retry_count); + if (!retry) + break; } g_free(pc); - g_free(ret_buf); - LOGD("ret value : %d", ret); + pc = NULL; return ret; } @@ -1473,8 +1527,8 @@ int player_prepare_async(player_h player, player_prepared_cb callback, void *use int timeout = 0; player_msg_get_type(timeout, ret_buf, INT); - LOGD("server timeout will be %d", timeout); - SERVER_TIMEOUT(pc) = timeout; + LOGD("server timeout will be %ds", timeout); + SERVER_TIMEOUT(pc) = timeout * G_TIME_SPAN_MILLISECOND; } g_free(ret_buf); @@ -1496,8 +1550,8 @@ int player_prepare(player_h player) int timeout = 0; player_msg_get_type(timeout, ret_buf, INT); - LOGD("server timeout will be %d", timeout); - SERVER_TIMEOUT(pc) = timeout; + LOGD("server timeout will be %ds", timeout); + SERVER_TIMEOUT(pc) = timeout * G_TIME_SPAN_MILLISECOND; } g_free(ret_buf);