Apply server ack at handle creation 61/78261/5
authorHyongtaek Lim <hyongtaek.lim@samsung.com>
Fri, 15 Jul 2016 08:58:06 +0000 (17:58 +0900)
committerHyongtaek Lim <hyongtaek.lim@samsung.com>
Fri, 15 Jul 2016 08:58:39 +0000 (17:58 +0900)
Change-Id: I4c852b935950b555be7fa7c7d8aea7a75da5826f
Signed-off-by: Hyongtaek Lim <hyongtaek.lim@samsung.com>
include/common/player.h [changed mode: 0755->0644]
include/player_private.h
src/player.c

old mode 100755 (executable)
new mode 100644 (file)
index 925cdb7..ed4ccc4 100644 (file)
@@ -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;
index 7207966..6133311 100644 (file)
@@ -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);