From 87db9505b8f239b8d7ccfab7df6a1958768c706c Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Fri, 5 Feb 2021 12:46:14 +0900 Subject: [PATCH] Fix leak in presentation sync fd. - The part related to presentation feedback and sync fd, which was a member of wl_egl_buffer, was separated into an independent structure pst_feedback. Change-Id: Ice9604b306923afdd93871380084879509f5e6ae Signed-off-by: Joonbum Ko --- src/tpl_wl_egl.c | 159 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 91 insertions(+), 68 deletions(-) diff --git a/src/tpl_wl_egl.c b/src/tpl_wl_egl.c index 878b41f..25bb0cb 100644 --- a/src/tpl_wl_egl.c +++ b/src/tpl_wl_egl.c @@ -179,9 +179,6 @@ struct _tpl_wl_egl_buffer { /* Fd to send a signal when wl_surface_commit with this buffer */ int32_t commit_sync_fd; - /* to get presentation feedback from display server */ - struct wp_presentation_feedback *presentation_feedback; - /* Fd to send a siganl when receive the * presentation feedback from display server */ int32_t presentation_sync_fd; @@ -194,6 +191,17 @@ struct _tpl_wl_egl_buffer { tpl_wl_egl_surface_t *wl_egl_surface; }; +struct pst_feedback { + /* to get presentation feedback from display server */ + struct wp_presentation_feedback *presentation_feedback; + + int32_t pst_sync_fd; + + int bo_name; + tpl_wl_egl_surface_t *wl_egl_surface; + +}; + static int _get_tbm_surface_bo_name(tbm_surface_h tbm_surface); static void @@ -1382,23 +1390,23 @@ _thread_wl_egl_surface_fini(tpl_wl_egl_surface_t *wl_egl_surface) if (wl_egl_display->presentation && wl_egl_surface->presentation_feedbacks) { while (!__tpl_list_is_empty(wl_egl_surface->presentation_feedbacks)) { - tbm_surface_h tbm_surface = - __tpl_list_pop_front(wl_egl_surface->presentation_feedbacks, NULL); - if (tbm_surface_internal_is_valid(tbm_surface)) { - tpl_wl_egl_buffer_t *wl_egl_buffer = _get_wl_egl_buffer(tbm_surface); - if (wl_egl_buffer && - wl_egl_buffer->presentation_sync_fd != -1 && - wl_egl_buffer->presentation_feedback) { - - _write_to_eventfd(wl_egl_buffer->presentation_sync_fd); - close(wl_egl_buffer->presentation_sync_fd); - wl_egl_buffer->presentation_sync_fd = -1; - - wp_presentation_feedback_destroy(wl_egl_buffer->presentation_feedback); - wl_egl_buffer->presentation_feedback = NULL; - } + struct pst_feedback *pst_feedback = + (struct pst_feedback *)__tpl_list_pop_front( + wl_egl_surface->presentation_feedbacks, NULL); + if (pst_feedback) { + _write_to_eventfd(pst_feedback->pst_sync_fd); + close(pst_feedback->pst_sync_fd); + pst_feedback->pst_sync_fd = -1; + + wp_presentation_feedback_destroy(pst_feedback->presentation_feedback); + pst_feedback->presentation_feedback = NULL; + + free(pst_feedback); } } + + __tpl_list_free(wl_egl_surface->presentation_feedbacks, NULL); + wl_egl_surface->presentation_feedbacks = NULL; } if (wl_egl_surface->presentation_sync.fd != -1) { @@ -2072,7 +2080,6 @@ _wl_egl_buffer_init(tpl_wl_egl_buffer_t *wl_egl_buffer, wl_egl_buffer->commit_sync_fd = -1; wl_egl_buffer->presentation_sync_fd = -1; - wl_egl_buffer->presentation_feedback = NULL; wl_egl_buffer->buffer_release = NULL; wl_egl_buffer->transform = tizen_private->transform; @@ -2811,40 +2818,40 @@ __cb_presentation_feedback_presented(void *data, TPL_IGNORE(seq_lo); TPL_IGNORE(flags); - tpl_wl_egl_buffer_t *wl_egl_buffer = (tpl_wl_egl_buffer_t *)data; - tpl_wl_egl_surface_t *wl_egl_surface = wl_egl_buffer->wl_egl_surface; - tbm_surface_h tbm_surface = wl_egl_buffer->tbm_surface; + struct pst_feedback *pst_feedback = (struct pst_feedback *)data; + tpl_wl_egl_surface_t *wl_egl_surface = pst_feedback->wl_egl_surface; tpl_gmutex_lock(&wl_egl_surface->presentation_sync.mutex); - TPL_DEBUG("[FEEDBACK][PRESENTED] wl_egl_surface(%p) tbm_surface(%p) bo(%d)", - wl_egl_surface, tbm_surface, - _get_tbm_surface_bo_name(tbm_surface)); + TPL_DEBUG("[FEEDBACK][PRESENTED] pst_feedback(%p) presentation_feedback(%p) bo(%d)", + pst_feedback, presentation_feedback, pst_feedback->bo_name); - if (wl_egl_buffer->presentation_sync_fd != -1) { - int ret = _write_to_eventfd(wl_egl_buffer->presentation_sync_fd); + if (pst_feedback->pst_sync_fd != -1) { + int ret = _write_to_eventfd(pst_feedback->pst_sync_fd); if (ret == -1) { TPL_ERR("Failed to send presentation_sync signal to fd(%d)", - wl_egl_buffer->presentation_sync_fd); + pst_feedback->pst_sync_fd); } - TRACE_ASYNC_END(wl_egl_buffer->presentation_sync_fd, + TRACE_ASYNC_END(pst_feedback->pst_sync_fd, "[PRESENTATION_SYNC] bo(%d)", - _get_tbm_surface_bo_name(tbm_surface)); - TPL_DEBUG("[PRESENTATION_SYNC_FD_CLOSE] wl_egl_buffer(%p) presentation_sync_fd(%d)", - wl_egl_buffer, wl_egl_buffer->presentation_sync_fd); - close(wl_egl_buffer->presentation_sync_fd); - wl_egl_buffer->presentation_sync_fd = -1; + pst_feedback->bo_name); + + close(pst_feedback->pst_sync_fd); + pst_feedback->pst_sync_fd = -1; } - if (wl_egl_buffer->presentation_feedback) - wp_presentation_feedback_destroy(wl_egl_buffer->presentation_feedback); + wp_presentation_feedback_destroy(presentation_feedback); - wl_egl_buffer->presentation_feedback = NULL; + pst_feedback->presentation_feedback = NULL; + pst_feedback->wl_egl_surface = NULL; + pst_feedback->bo_name = 0; - __tpl_list_remove_data(wl_egl_surface->presentation_feedbacks, tbm_surface, + __tpl_list_remove_data(wl_egl_surface->presentation_feedbacks, pst_feedback, TPL_FIRST, NULL); + free(pst_feedback); + tpl_gmutex_unlock(&wl_egl_surface->presentation_sync.mutex); } @@ -2852,39 +2859,40 @@ static void __cb_presentation_feedback_discarded(void *data, struct wp_presentation_feedback *presentation_feedback) { - tpl_wl_egl_buffer_t *wl_egl_buffer = (tpl_wl_egl_buffer_t *)data; - tpl_wl_egl_surface_t *wl_egl_surface = wl_egl_buffer->wl_egl_surface; - tbm_surface_h tbm_surface = wl_egl_buffer->tbm_surface; + struct pst_feedback *pst_feedback = (struct pst_feedback *)data; + tpl_wl_egl_surface_t *wl_egl_surface = pst_feedback->wl_egl_surface; tpl_gmutex_lock(&wl_egl_surface->presentation_sync.mutex); - TPL_DEBUG("[FEEDBACK][DISCARDED] wl_egl_surface(%p) tbm_surface(%p) bo(%d)", - wl_egl_surface, tbm_surface, - _get_tbm_surface_bo_name(tbm_surface)); + TPL_DEBUG("[FEEDBACK][DISCARDED] pst_feedback(%p) presentation_feedback(%p) bo(%d)", + pst_feedback, presentation_feedback, pst_feedback->bo_name); - if (wl_egl_buffer->presentation_sync_fd != -1) { - int ret = _write_to_eventfd(wl_egl_buffer->presentation_sync_fd); + if (pst_feedback->pst_sync_fd != -1) { + int ret = _write_to_eventfd(pst_feedback->pst_sync_fd); if (ret == -1) { TPL_ERR("Failed to send presentation_sync signal to fd(%d)", - wl_egl_buffer->presentation_sync_fd); + pst_feedback->pst_sync_fd); } - TRACE_ASYNC_END(wl_egl_buffer->presentation_sync_fd, + TRACE_ASYNC_END(pst_feedback->pst_sync_fd, "[PRESENTATION_SYNC] bo(%d)", - _get_tbm_surface_bo_name(tbm_surface)); + pst_feedback->bo_name); - close(wl_egl_buffer->presentation_sync_fd); - wl_egl_buffer->presentation_sync_fd = -1; + close(pst_feedback->pst_sync_fd); + pst_feedback->pst_sync_fd = -1; } - if (wl_egl_buffer->presentation_feedback) - wp_presentation_feedback_destroy(wl_egl_buffer->presentation_feedback); + wp_presentation_feedback_destroy(presentation_feedback); - wl_egl_buffer->presentation_feedback = NULL; + pst_feedback->presentation_feedback = NULL; + pst_feedback->wl_egl_surface = NULL; + pst_feedback->bo_name = 0; - __tpl_list_remove_data(wl_egl_surface->presentation_feedbacks, tbm_surface, + __tpl_list_remove_data(wl_egl_surface->presentation_feedbacks, pst_feedback, TPL_FIRST, NULL); + free(pst_feedback); + tpl_gmutex_unlock(&wl_egl_surface->presentation_sync.mutex); } @@ -2953,17 +2961,36 @@ _thread_wl_surface_commit(tpl_wl_egl_surface_t *wl_egl_surface, version = wl_proxy_get_version((struct wl_proxy *)wl_surface); + /* create presentation feedback and add listener */ tpl_gmutex_lock(&wl_egl_surface->presentation_sync.mutex); if (wl_egl_display->presentation && wl_egl_buffer->presentation_sync_fd != -1) { - wl_egl_buffer->presentation_feedback = - wp_presentation_feedback(wl_egl_display->presentation, - wl_surface); - wp_presentation_feedback_add_listener(wl_egl_buffer->presentation_feedback, - &feedback_listener, wl_egl_buffer); - __tpl_list_push_back(wl_egl_surface->presentation_feedbacks, tbm_surface); - TRACE_ASYNC_BEGIN(wl_egl_buffer->presentation_sync_fd, - "[PRESENTATION_SYNC] bo(%d)", - _get_tbm_surface_bo_name(tbm_surface)); + + struct pst_feedback *pst_feedback = NULL; + pst_feedback = (struct pst_feedback *) calloc(1, sizeof(struct pst_feedback)); + if (pst_feedback) { + pst_feedback->presentation_feedback = + wp_presentation_feedback(wl_egl_display->presentation, + wl_surface); + + pst_feedback->wl_egl_surface = wl_egl_surface; + pst_feedback->bo_name = _get_tbm_surface_bo_name(tbm_surface); + + pst_feedback->pst_sync_fd = wl_egl_buffer->presentation_sync_fd; + wl_egl_buffer->presentation_sync_fd = -1; + + wp_presentation_feedback_add_listener(pst_feedback->presentation_feedback, + &feedback_listener, pst_feedback); + __tpl_list_push_back(wl_egl_surface->presentation_feedbacks, pst_feedback); + TRACE_ASYNC_BEGIN(pst_feedback->pst_sync_fd, + "[PRESENTATION_SYNC] bo(%d)", + pst_feedback->bo_name); + } else { + TPL_ERR("Failed to create presentation feedback. wl_egl_buffer(%p)", + wl_egl_buffer); + _write_to_eventfd(wl_egl_buffer->presentation_sync_fd); + close(wl_egl_buffer->presentation_sync_fd); + wl_egl_buffer->presentation_sync_fd = -1; + } } tpl_gmutex_unlock(&wl_egl_surface->presentation_sync.mutex); @@ -3184,10 +3211,6 @@ __cb_wl_egl_buffer_free(tpl_wl_egl_buffer_t *wl_egl_buffer) wl_egl_buffer->presentation_sync_fd); close(wl_egl_buffer->presentation_sync_fd); wl_egl_buffer->presentation_sync_fd = -1; - - if (wl_egl_buffer->presentation_feedback) - wp_presentation_feedback_destroy(wl_egl_buffer->presentation_feedback); - wl_egl_buffer->presentation_feedback = NULL; } if (wl_egl_buffer->rects) { -- 2.7.4