From 26cfd43965439f3410908a0a6e76d91b33c883b1 Mon Sep 17 00:00:00 2001 From: Changyeon Lee Date: Fri, 2 Nov 2018 14:09:51 +0900 Subject: [PATCH] tdm_client: add timeout timer to tdm_server vblank if callback of timeout is called, send done event to client with TDM_ERROR_TIMEOUT. Change-Id: I3a1bd15bc733cf685f84f6eeb81acd03952b6183 --- src/tdm_server.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 89 insertions(+), 2 deletions(-) diff --git a/src/tdm_server.c b/src/tdm_server.c index d4166b4..76bae78 100644 --- a/src/tdm_server.c +++ b/src/tdm_server.c @@ -102,6 +102,9 @@ typedef struct _tdm_server_vblank_info { tdm_vblank *vblank; unsigned int stamp; + + /* for timeout */ + tdm_event_loop_source *vblank_timeout_timer; } tdm_server_vblank_info; typedef struct _tdm_server_wait_info { @@ -110,6 +113,8 @@ typedef struct _tdm_server_wait_info { unsigned int req_id; double req_time; + + unsigned int timeout; } tdm_server_wait_info; typedef struct _tdm_server_client_info { @@ -123,6 +128,7 @@ static tdm_private_server *keep_private_server; static struct list_head client_list; static void destroy_wait(tdm_server_wait_info *wait_info); +static void _tdm_server_vblank_timeout_update(tdm_server_vblank_info *vblank_info, int ms_delay); static void _tdm_server_get_process_name(pid_t pid, char *name, unsigned int size) @@ -158,6 +164,9 @@ _tdm_server_send_done(tdm_server_wait_info *wait_info, tdm_error error, { tdm_server_wait_info *found; tdm_server_vblank_info *vblank_info; + tdm_server_output_info *output_info; + tdm_private_server *private_server; + tdm_private_loop *private_loop; TDM_RETURN_IF_FAIL(keep_private_server != NULL); @@ -172,18 +181,82 @@ _tdm_server_send_done(tdm_server_wait_info *wait_info, tdm_error error, TDM_DBG("req_id(%d) done", wait_info->req_id); vblank_info = wait_info->vblank_info; + output_info = vblank_info->output_info; + private_server = output_info->private_server; + private_loop = private_server->private_loop; + + tdm_display_lock(private_loop->dpy); + _tdm_server_vblank_timeout_update(vblank_info, 0); + tdm_display_unlock(private_loop->dpy); if (tdm_ttrace_module & TDM_TTRACE_SERVER_VBLANK) TDM_TRACE_ASYNC_END((int)wait_info->req_time, "TDM_Server_Vblank:%u", vblank_info->stamp); - wl_tdm_vblank_send_done(vblank_info->resource, wait_info->req_id, - sequence, tv_sec, tv_usec, error); + if (!wait_info->timeout) + wl_tdm_vblank_send_done(vblank_info->resource, wait_info->req_id, + sequence, tv_sec, tv_usec, error); destroy_wait(wait_info); } /* LCOV_EXCL_STOP */ /* LCOV_EXCL_START */ +static tdm_error +_tdm_server_timeout_timer_cb(void *user_data) +{ + tdm_server_vblank_info *vblank_info = user_data; + tdm_server_wait_info *wait_info = NULL; + double curr; + unsigned int tv_sec; + unsigned int tv_usec; + + TDM_RETURN_VAL_IF_FAIL(vblank_info != NULL, TDM_ERROR_OPERATION_FAILED); + TDM_RETURN_VAL_IF_FAIL(keep_private_server != NULL, TDM_ERROR_OPERATION_FAILED); + + curr = tdm_helper_get_time(); + tv_sec = TDM_TIME_SEC(curr); + tv_usec = TDM_TIME_USEC(curr); + + LIST_FOR_EACH_ENTRY(wait_info, &keep_private_server->wait_list, link) { + wl_tdm_vblank_send_done(vblank_info->resource, wait_info->req_id, + 0, tv_sec, tv_usec, TDM_ERROR_TIMEOUT); + TDM_ERR("tdm_server_vblank(%p) req_id(%d) timeout force send vblank", vblank_info); + wait_info->timeout = 1; + } + + return TDM_ERROR_NONE; +} + +static void +_tdm_server_vblank_timeout_update(tdm_server_vblank_info *vblank_info, int ms_delay) +{ + tdm_server_output_info *output_info = vblank_info->output_info; + tdm_private_server *private_server = output_info->private_server; + tdm_private_loop *private_loop = private_server->private_loop; + tdm_error ret; + + if (!vblank_info->vblank_timeout_timer) { + vblank_info->vblank_timeout_timer = + tdm_event_loop_add_timer_handler(private_loop->dpy, + _tdm_server_timeout_timer_cb, + vblank_info, + &ret); + if (!vblank_info->vblank_timeout_timer) { + TDM_ERR("tdm_server_vblank(%p) couldn't add timer", vblank_info); + return; + } + + if (tdm_debug_module & TDM_DEBUG_VBLANK) + TDM_INFO("tdm_server_vblank(%p) create vblank timeout timer", vblank_info); + } + + ret = tdm_event_loop_source_timer_update(vblank_info->vblank_timeout_timer, ms_delay); + if (ret != TDM_ERROR_NONE) { + TDM_ERR("tdm_server_vblank(%p) couldn't update timer", vblank_info); + return; + } +} + static void _tdm_server_cb_vblank(tdm_vblank *vblank, tdm_error error, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data) @@ -257,10 +330,19 @@ static void destroy_vblank_callback(struct wl_resource *resource) { tdm_server_vblank_info *vblank_info = wl_resource_get_user_data(resource); + tdm_server_output_info *output_info = vblank_info->output_info; + tdm_private_server *private_server = output_info->private_server; + tdm_private_loop *private_loop = private_server->private_loop; tdm_server_wait_info *w = NULL, *ww = NULL; TDM_RETURN_IF_FAIL(vblank_info != NULL); + if (vblank_info->vblank_timeout_timer) { + tdm_display_lock(private_loop->dpy); + tdm_event_loop_source_remove(vblank_info->vblank_timeout_timer); + tdm_display_unlock(private_loop->dpy); + } + LIST_DEL(&vblank_info->link); if (vblank_info->vblank) @@ -335,6 +417,7 @@ _tdm_server_vblank_cb_wait_vblank(struct wl_client *client, struct wl_resource * tdm_server_vblank_info *vblank_info = wl_resource_get_user_data(resource); tdm_server_output_info *output_info = vblank_info->output_info; tdm_private_server *private_server = output_info->private_server; + tdm_private_loop *private_loop = private_server->private_loop; tdm_server_wait_info *wait_info; unsigned int enable_fake = 0; tdm_error ret; @@ -369,6 +452,10 @@ _tdm_server_vblank_cb_wait_vblank(struct wl_client *client, struct wl_resource * TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, wait_failed); + tdm_display_lock(private_loop->dpy); + _tdm_server_vblank_timeout_update(vblank_info, 1000); + tdm_display_unlock(private_loop->dpy); + return; wait_failed: /* LCOV_EXCL_START */ -- 2.7.4