Fix leak in presentation sync fd. 84/254784/1
authorJoonbum Ko <joonbum.ko@samsung.com>
Fri, 5 Feb 2021 03:46:14 +0000 (12:46 +0900)
committerJoonbum Ko <joonbum.ko@samsung.com>
Tue, 9 Mar 2021 08:51:53 +0000 (17:51 +0900)
 - 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 <joonbum.ko@samsung.com>
src/tpl_wl_egl.c

index 878b41f..25bb0cb 100644 (file)
@@ -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) {