tbm_module: handle the memory leak of the bo_data_array 59/260359/3
authorSooChan Lim <sc1.lim@samsung.com>
Thu, 24 Jun 2021 01:08:01 +0000 (10:08 +0900)
committerSooChan Lim <sc1.lim@samsung.com>
Thu, 24 Jun 2021 01:59:17 +0000 (10:59 +0900)
deal with the memory free when it operates to be failed.

Change-Id: Ifdf99fca1f1b056139ff3c63e72fb08ab15faed2

src/tbm_module.c
src/tbm_module.h
src/tbm_surface_internal.c

index 2f38521..22dc061 100644 (file)
@@ -837,7 +837,7 @@ tbm_module_alloc_bo_data_with_format(tbm_module *module, int format, int bo_idx,
                break;
        case TBM_MODULE_TYPE_BUFMGR_BACKEND:
                TBM_WRN("!!WARNING: This backend interface will be DEPRECATED after Tizen 6.5.");
-               TBM_ERR("error: not supported tbm_bufmgr_internal_alloc_bo_with_format.");
+               TBM_ERR("error: not supported tbm_module_alloc_bo_data_with_format.");
 
                *error = TBM_ERROR_NOT_SUPPORTED;
                goto failed;
@@ -1035,7 +1035,7 @@ tbm_surface_data_get_plane_data(tbm_surface_data *surface_data, int plane_idx, u
 }
 
 tbm_bo_data **
-tbm_surface_data_get_bo_data_array(tbm_surface_data *surface_data, int *num_bos, tbm_error_e *error)
+tbm_surface_data_get_bo_data_array(tbm_surface_data *surface_data, int *num_bos, int *memory_types, tbm_error_e *error)
 {
        tbm_bo_data **bo_data_array = NULL;
        hal_tbm_bo **hal_bos = NULL;
@@ -1047,11 +1047,12 @@ tbm_surface_data_get_bo_data_array(tbm_surface_data *surface_data, int *num_bos,
        hal_bos = hal_tbm_surface_get_bos(surface_data->hal_surface, num_bos, (hal_tbm_error *)error);
        TBM_RETURN_VAL_IF_FAIL(hal_bos, NULL);
 
-       bo_data_array = calloc(*num_bos, sizeof(struct _tbm_bo_data));
-       if (bo_data_array) {
-               TBM_ERR("memory allocation failed.");
-               *error = TBM_ERROR_OUT_OF_MEMORY;
-               return NULL;
+       bo_data_array = calloc(*num_bos, sizeof(tbm_bo_data *));
+       TBM_RETURN_VAL_IF_FAIL(bo_data_array, NULL);
+
+       for (i = 0; i < *num_bos; i++) {
+               bo_data_array[i] = calloc(*num_bos, sizeof(struct _tbm_bo_data));
+               TBM_GOTO_VAL_SET_ERR_IF_FAIL(bo_data_array[i], failed, *error, TBM_ERROR_OUT_OF_MEMORY);
        }
 
        for (i = 0; i < *num_bos; i++) {
@@ -1059,7 +1060,22 @@ tbm_surface_data_get_bo_data_array(tbm_surface_data *surface_data, int *num_bos,
                bo_data_array[i]->module = surface_data->module;
        }
 
+       // get memory_types(bo flags)
+       *memory_types = tbm_bo_data_get_memory_types(bo_data_array[0], error);
+       TBM_GOTO_VAL_IF_FAIL(*error == TBM_ERROR_NONE, failed);
+
        return bo_data_array;
+
+/* LCOV_EXCL_START */
+failed:
+       for (i = 0; i < *num_bos; i++) {
+               if (bo_data_array[i])
+                       free(bo_data_array[i]);
+       }
+       free(bo_data_array);
+
+       return NULL;
+/* LCOV_EXCL_STOP */
 }
 
 tbm_surface_buffer_data *
index 65db355..3de506a 100644 (file)
@@ -103,7 +103,7 @@ int          tbm_module_compare_bo_data(tbm_module *module, tbm_bo_data *bo_data
 
 void                      tbm_surface_data_free(tbm_surface_data *surface_data);
 tbm_error_e               tbm_surface_data_get_plane_data(tbm_surface_data *surface_data, int plane_idx, uint32_t *size, uint32_t *offset, uint32_t *pitch, int *bo_idx);
-tbm_bo_data             **tbm_surface_data_get_bo_data_array(tbm_surface_data *surface_data, int *num_bos, tbm_error_e *error);
+tbm_bo_data             **tbm_surface_data_get_bo_data_array(tbm_surface_data *surface_data, int *num_bos, int *memory_types, tbm_error_e *error);
 tbm_surface_buffer_data  *tbm_surface_data_export(tbm_surface_data *surface_data, tbm_error_e *error);
 
 void          tbm_bo_data_free(tbm_bo_data *bo_data, int get_from_surface_data);
index 5d39a0e..c9a2e47 100644 (file)
@@ -673,24 +673,20 @@ _tbm_surface_internal_set_data(struct _tbm_surface *surf, int flags, int is_surf
                        surf->planes_bo_idx[i] = bo_idx;
                }
 
+               // calculate the size of a surface
+               for (i = 0; i < surf->info.num_planes; i++)
+                       surf->info.size += surf->info.planes[i].size;
+
                // get the bo_data_array
-               bo_data_array = tbm_surface_data_get_bo_data_array(surf->surface_data, &num_bos, &error);
+               bo_data_array = tbm_surface_data_get_bo_data_array(surf->surface_data, &num_bos, &memory_types, &error);
                if (!bo_data_array) {
                        TBM_ERR("tbm_surface_data_get_bo_data_array failed. error:%s", tbm_error_str(error));
                        return error;
                }
-               surf->num_bos = num_bos;
 
-               // calculate the size of a surface
-               for (i = 0; i < surf->info.num_planes; i++)
-                       surf->info.size += surf->info.planes[i].size;
+               // set num_bos
+               surf->num_bos = num_bos;
 
-               // get memory_types(bo flags)
-               memory_types = tbm_bo_data_get_memory_types(bo_data_array[0], &error);
-               if (error != TBM_ERROR_NONE) {
-                       TBM_ERR("tbm_bo_data_get_memory_types failed. error:%s", tbm_error_str(error));
-                       return error;
-               }
                // set flags
                surf->flags = memory_types;
 
@@ -704,6 +700,10 @@ _tbm_surface_internal_set_data(struct _tbm_surface *surf, int flags, int is_surf
 
                        _tbm_bo_set_surface(surf->bos[i], surf);
                }
+
+               // only free the pointers of the arrary, not the item(tbm_bo_data).
+               // the item(tbm_bo_data) is set to the tbm_bo. tbm_bo handles the life cycle of the tbm_bo_data.
+               free(bo_data_array);
        } else {
                // set infomation of planes
                for (i = 0; i < surf->info.num_planes; i++) {
@@ -758,6 +758,16 @@ _tbm_surface_internal_set_data(struct _tbm_surface *surf, int flags, int is_surf
        return TBM_ERROR_NONE;
 
 failed:
+       if (is_surface_data) {
+               for (j = 0; j < num_bos; j++) {
+                       if (bo_data_array[j]) {
+                               free(bo_data_array[j]);
+                               surf->bos[j] = NULL;
+                       }
+               }
+               free(bo_data_array);
+       }
+
        for (j = 0; j < i; j++) {
                if (surf->bos[j])
                        tbm_bo_unref(surf->bos[j]);