virtual: fix buffer management error 14/186414/2
authorJunkyeong Kim <jk0430.kim@samsung.com>
Thu, 9 Aug 2018 10:36:36 +0000 (19:36 +0900)
committerJunkyeong Kim <jk0430.kim@samsung.com>
Thu, 16 Aug 2018 02:29:29 +0000 (11:29 +0900)
Change-Id: I3c9a0c5dc79ed21b1871555d4abf7bec88bed6e9
Signed-off-by: Junkyeong Kim <jk0430.kim@samsung.com>
src/tdm_server.c

index b4aede3..09c6e3c 100644 (file)
@@ -715,22 +715,6 @@ _tdm_server_cb_create_output(struct wl_client *client, struct wl_resource *resou
 
 static void _tdm_voutput_cb_destroy(struct wl_client *client, struct wl_resource *resource)
 {
-       tdm_server_voutput_info *voutput_info;
-       tdm_private_server *private_server;
-       tdm_output *output;
-       tdm_error ret = TDM_ERROR_NONE;
-
-       voutput_info = wl_resource_get_user_data(resource);
-
-       private_server = voutput_info->private_server;
-       output = voutput_info->output;
-
-       if (output)
-               ret = tdm_display_destroy_output(private_server->private_loop->dpy, output);
-
-       if (ret != TDM_ERROR_NONE)
-               TDM_ERR("_tdm_voutput_cb_destroy fail");
-
        wl_resource_destroy(resource);
 }
 
@@ -807,6 +791,7 @@ static void
 _tdm_voutput_cb_commit_done(struct wl_client *client, struct wl_resource *resource)
 {
        tdm_server_voutput_info *voutput_info;
+       tbm_surface_h buffer;
 
        voutput_info = wl_resource_get_user_data(resource);
        if (voutput_info->status != TDM_OUTPUT_CONN_STATUS_CONNECTED)
@@ -814,9 +799,14 @@ _tdm_voutput_cb_commit_done(struct wl_client *client, struct wl_resource *resour
                // handle error
                return;
        }
-       tdm_output_commit_done(voutput_info->output, voutput_info->attach_buffer->buffer);
+
+       buffer = voutput_info->attach_buffer->buffer;
+       tbm_surface_internal_unref(buffer);
+
        voutput_info->committing = 0;
        voutput_info->attach_buffer = NULL;
+
+       tdm_output_commit_done(voutput_info->output, buffer);
 }
 
 static const struct wl_tdm_voutput_interface tdm_voutput_implementation = {
@@ -842,15 +832,16 @@ static void
 _tdm_voutput_buffer_destory(struct wl_resource *wl_buffer)
 {
        tdm_server_voutput_info *voutput_info = NULL;
-       tdm_server_voutput_buffer *vb = NULL;
+       tdm_server_voutput_buffer *vb = NULL, *vbb = NULL;
 
        voutput_info = (tdm_server_voutput_info *)wl_resource_get_user_data(wl_buffer);
        TDM_RETURN_IF_FAIL(voutput_info != NULL);
 
-       LIST_FOR_EACH_ENTRY(vb, &voutput_info->buffer_list, link) {
+       LIST_FOR_EACH_ENTRY_SAFE(vb, vbb, &voutput_info->buffer_list, link) {
                if (vb->wl_buffer == wl_buffer) {
                        tbm_surface_internal_unref(vb->buffer);
                        wl_resource_set_user_data(wl_buffer, NULL);
+                       LIST_DEL(&vb->link);
                        free(vb);
                }
        }
@@ -1000,8 +991,10 @@ _tdm_output_get_voutput_buffer(tdm_server_voutput_info *voutput_info, tbm_surfac
        tdm_server_voutput_buffer *voutput_buffer = NULL, *vb = NULL;
 
        LIST_FOR_EACH_ENTRY(vb, &voutput_info->buffer_list, link) {
-               if (vb && vb->buffer == buffer)
+               if (vb && vb->buffer == buffer) {
+                       tbm_surface_internal_ref(vb->buffer);
                        return vb;
+               }
        }
 
        tbm_surface_internal_ref(buffer);
@@ -1029,7 +1022,7 @@ _tdm_output_get_voutput_buffer(tdm_server_voutput_info *voutput_info, tbm_surfac
        }
 
        voutput_buffer->buffer = buffer;
-       LIST_ADDTAIL(&voutput_info->link, &voutput_info->buffer_list);
+       LIST_ADDTAIL(&voutput_buffer->link, &voutput_info->buffer_list);
 
        return voutput_buffer;
 }
@@ -1091,13 +1084,23 @@ void
 tdm_voutput_cb_resource_destroy(struct wl_resource *resource)
 {
        tdm_server_voutput_info *voutput_info = wl_resource_get_user_data(resource);
-       tdm_server_voutput_buffer *vb, *vbb;
+       tdm_server_voutput_buffer *vb;
+       tdm_private_server *private_server;
+       tdm_output *output;
+       tdm_error ret = TDM_ERROR_NONE;
+
        TDM_RETURN_IF_FAIL(voutput_info != NULL);
 
-       LIST_FOR_EACH_ENTRY_SAFE(vb, vbb, &voutput_info->buffer_list, link) {
-               if (!vb) continue;
+       private_server = voutput_info->private_server;
+       output = voutput_info->output;
 
-               LIST_DEL(&vb->link);
+       if (output)
+               ret = tdm_display_destroy_output(private_server->private_loop->dpy, output);
+       if (ret != TDM_ERROR_NONE)
+               TDM_ERR("_tdm_voutput_cb_destroy fail");
+
+       LIST_FOR_EACH_ENTRY(vb, &voutput_info->buffer_list, link) {
+               if (!vb) continue;
 
                if (vb->wl_buffer)
                        wl_resource_destroy(vb->wl_buffer);