From 96cda783ee08e0565a4ca5ef82ed97558feb68c0 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Thu, 6 Jul 2017 11:42:23 +0900 Subject: [PATCH 01/16] increase version to 1.7.0 Change-Id: I69d8bc1d44f992e66a097e6aae7569e13e6df194 --- configure.ac | 2 +- doc/tdm_doc.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index ddd144a..a4cb6b8 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ AC_PREREQ([2.60]) m4_define([tdm_major_version], [1]) -m4_define([tdm_minor_version], [6]) +m4_define([tdm_minor_version], [7]) m4_define([tdm_micro_version], [0]) m4_define([tdm_version], [tdm_major_version.tdm_minor_version.tdm_micro_version]) diff --git a/doc/tdm_doc.h b/doc/tdm_doc.h index 35d9ee9..1d3e915 100644 --- a/doc/tdm_doc.h +++ b/doc/tdm_doc.h @@ -39,7 +39,7 @@ /** * @mainpage TDM * @author Boram Park, boram1288.park@samsung.com - * @version 1.6.0 + * @version 1.7.0 * @par Introduction * TDM stands for Tizen Display Manager. It's the display HAL layer for tizen * display server. It offers the frontend APIs(@ref tdm.h) for a frontend user -- 2.7.4 From 7f8c3b416f50b7a13d22f79cfc813d5ef8c34d79 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 19 Jul 2017 12:23:44 +0900 Subject: [PATCH 02/16] add tdm_output_set_dpms_async Change-Id: I9775ea2e5e78e8a4b11ec85b2b7481b670959b13 --- include/tdm.h | 19 +++++++++- include/tdm_backend.h | 25 +++++++++++--- src/tdm_output.c | 96 ++++++++++++++++++++++++++++++++++++++++----------- src/tdm_private.h | 1 + 4 files changed, 115 insertions(+), 26 deletions(-) diff --git a/include/tdm.h b/include/tdm.h index 29c8193..a7695c1 100644 --- a/include/tdm.h +++ b/include/tdm.h @@ -524,15 +524,32 @@ tdm_error tdm_output_get_mode(tdm_output *output, const tdm_output_mode **mode); /** - * @brief Set DPMS of a output object + * @brief Set DPMS of a output object synchronously * @param[in] output A output object * @param[in] dpms_value DPMS value * @return #TDM_ERROR_NONE if success. Otherwise, error value. + * @see tdm_output_set_dpms_async */ tdm_error tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value); /** + * @brief Set DPMS of a output object asynchronously + * @details This function can be used when a output supports the asynchronous DPMS + * control. The output has #TDM_OUTPUT_CAPABILITY_ASYNC_DPMS flags which + * #tdm_output_get_capabilities returns. If an output change handler is added with + * #tdm_output_add_change_handler, the output change handler will be called when + * the DPMS status is changed indeed. + * @param[in] output A output object + * @param[in] dpms_value DPMS value + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + * @see tdm_output_add_change_handler, tdm_output_set_dpms, + * tdm_output_get_capabilities, #TDM_OUTPUT_CAPABILITY_ASYNC_DPMS. + */ +tdm_error +tdm_output_set_dpms_async(tdm_output *output, tdm_output_dpms dpms_value); + +/** * @brief Get DPMS of a output object * @param[in] output A output object * @param[out] dpms_value DPMS value diff --git a/include/tdm_backend.h b/include/tdm_backend.h index 0949372..2de8c7b 100644 --- a/include/tdm_backend.h +++ b/include/tdm_backend.h @@ -451,7 +451,7 @@ typedef struct _tdm_func_output { tdm_output_commit_handler func); /** - * @brief Set DPMS of a output object + * @brief Set DPMS of a output object synchronously * @param[in] output A output object * @param[in] dpms_value DPMS value * @return #TDM_ERROR_NONE if success. Otherwise, error value. @@ -512,18 +512,35 @@ typedef struct _tdm_func_output { /** * @brief Set a output dpms handler - * @details A backend module needs to call the output dpms handler when the - * output DPMS has been changed to let the TDM frontend know the change. + * @details This function can be NULL if an output doesn't support asynchronous + * DPMS control. Otherwise, a backend module needs to call the output dpms handler + * to let the TDM frontend know the output DPMS change indeed. * @param[in] output A output object * @param[in] func A output dpms handler * @param[in] user_data The user data * @return #TDM_ERROR_NONE if success. Otherwise, error value. + * @see #output_set_dpms_async, #TDM_OUTPUT_CAPABILITY_ASYNC_DPMS * @since 1.4.0 */ tdm_error (*output_set_dpms_handler)(tdm_output *output, tdm_output_dpms_handler func, void *user_data); - void (*reserved2)(void); + + /** + * @brief Set DPMS of a output object asynchronously + * @param[in] output A output object + * @details This function can be NULL if an output doesn't support asynchronous + * DPMS control. Otherwise, an output should have #TDM_OUTPUT_CAPABILITY_ASYNC_DPMS + * flags which #output_get_capability returns. And if a output dpms handler is added with + * #output_set_dpms_handler, a backend module needs to call the output dpms handler + * to let the TDM frontend know the output DPMS change indeed. + * @param[in] dpms_value DPMS value + * @return #TDM_ERROR_NONE if success. Otherwise, error value. + * @see #output_set_dpms_handler, #TDM_OUTPUT_CAPABILITY_ASYNC_DPMS + * @since 1.7.0 + */ + tdm_error (*output_set_dpms_async)(tdm_output *output, tdm_output_dpms dpms_value); + void (*reserved3)(void); void (*reserved4)(void); void (*reserved5)(void); diff --git a/src/tdm_output.c b/src/tdm_output.c index 62ba065..8b7abd4 100644 --- a/src/tdm_output.c +++ b/src/tdm_output.c @@ -1087,6 +1087,7 @@ tdm_output_cb_dpms(tdm_output *output_backend, tdm_output_dpms dpms, void *user_ } private_output->current_dpms_value = dpms; + private_output->waiting_dpms_change = 0; TDM_INFO("output(%d) dpms %s", private_output->pipe, tdm_dpms_str(dpms)); @@ -1108,6 +1109,12 @@ tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value) _pthread_mutex_lock(&private_display->lock); + if (private_output->waiting_dpms_change) { + TDM_ERR("DPMS is not changed yet. Can't be changed twice"); + _pthread_mutex_unlock(&private_display->lock); + return TDM_ERROR_BAD_REQUEST; + } + if (private_output->current_dpms_value == dpms_value) { _pthread_mutex_unlock(&private_display->lock); return TDM_ERROR_NONE; @@ -1132,30 +1139,16 @@ tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value) func_output = &private_display->func_output; - if (!func_output->output_set_dpms) { - _pthread_mutex_unlock(&private_display->lock); - private_output->current_dpms_value = dpms_value; - TDM_INFO("output(%d) dpms %s", private_output->pipe, tdm_dpms_str(dpms_value)); + if (func_output->output_set_dpms) + ret = func_output->output_set_dpms(private_output->output_backend, dpms_value); + else { + ret = TDM_ERROR_NONE; TDM_WRN("not implemented!!"); - return TDM_ERROR_NONE; + goto done; } - if (func_output->output_set_dpms_handler) { - if (!private_output->regist_dpms_cb) { - private_output->regist_dpms_cb = 1; - ret = func_output->output_set_dpms_handler(private_output->output_backend, - tdm_output_cb_dpms, private_output); - if (ret != TDM_ERROR_NONE) { - _pthread_mutex_unlock(&private_display->lock); - TDM_ERR("Can't set the dpms handler!!"); - return ret; - } - } - } - - ret = func_output->output_set_dpms(private_output->output_backend, dpms_value); - - if (ret == TDM_ERROR_NONE && !func_output->output_set_dpms_handler) { +done: + if (ret == TDM_ERROR_NONE) { tdm_value value; private_output->current_dpms_value = dpms_value; @@ -1179,6 +1172,67 @@ tdm_output_set_dpms(tdm_output *output, tdm_output_dpms dpms_value) return ret; } +EXTERN tdm_error +tdm_output_set_dpms_async(tdm_output *output, tdm_output_dpms dpms_value) +{ + tdm_func_output *func_output; + OUTPUT_FUNC_ENTRY(); + + if (!(private_output->caps.capabilities & TDM_OUTPUT_CAPABILITY_ASYNC_DPMS)) { + TDM_ERR("output doesn't support the asynchronous DPMS control!"); + return TDM_ERROR_BAD_REQUEST; + } + + if (dpms_value > TDM_OUTPUT_DPMS_OFF) + dpms_value = TDM_OUTPUT_DPMS_OFF; + + _pthread_mutex_lock(&private_display->lock); + + if (private_output->waiting_dpms_change) { + TDM_ERR("DPMS is not changed yet. Can't be changed twice"); + _pthread_mutex_unlock(&private_display->lock); + return TDM_ERROR_BAD_REQUEST; + } + + if (private_output->current_dpms_value == dpms_value) { + _pthread_mutex_unlock(&private_display->lock); + return TDM_ERROR_NONE; + } + + func_output = &private_display->func_output; + if (!func_output->output_set_dpms_handler) { + TDM_ERR("not implemented: output_set_dpms_handler"); + _pthread_mutex_unlock(&private_display->lock); + return TDM_ERROR_NOT_IMPLEMENTED; + } + + if (!func_output->output_set_dpms_async) { + TDM_ERR("not implemented: output_set_dpms_async"); + _pthread_mutex_unlock(&private_display->lock); + return TDM_ERROR_NOT_IMPLEMENTED; + } + + if (!private_output->regist_dpms_cb) { + private_output->regist_dpms_cb = 1; + ret = func_output->output_set_dpms_handler(private_output->output_backend, + tdm_output_cb_dpms, private_output); + if (ret != TDM_ERROR_NONE) { + _pthread_mutex_unlock(&private_display->lock); + TDM_ERR("Can't set the dpms handler!!"); + return ret; + } + } + + ret = func_output->output_set_dpms_async(private_output->output_backend, dpms_value); + + if (ret == TDM_ERROR_NONE) + private_output->waiting_dpms_change = 1; + + _pthread_mutex_unlock(&private_display->lock); + + return ret; +} + INTERN tdm_error tdm_output_get_dpms_internal(tdm_output *output, tdm_output_dpms *dpms_value) { diff --git a/src/tdm_private.h b/src/tdm_private.h index 4ea122d..12ac385 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -193,6 +193,7 @@ struct _tdm_private_output { unsigned int pipe; tdm_output_dpms current_dpms_value; + unsigned int waiting_dpms_change; const tdm_output_mode *current_mode; int regist_vblank_cb; -- 2.7.4 From 9af4e72354e3c50b9d35081875e5074fbf329003 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 19 Jul 2017 14:06:34 +0900 Subject: [PATCH 03/16] fix invariant result Change-Id: Iecb805dfda52036b6bf9a37bb9af994dbe2979d8 --- src/tdm_helper.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tdm_helper.c b/src/tdm_helper.c index aaf7fbd..712a9da 100644 --- a/src/tdm_helper.c +++ b/src/tdm_helper.c @@ -548,7 +548,7 @@ tdm_helper_get_fd(const char *env) if (!value) return -1; - const long sl = strtol(value, &end, 10); + const long int sl = strtol(value, &end, 10); if (end == value) { TDM_ERR("%s: not a decimal number\n", value); return -1; @@ -558,10 +558,10 @@ tdm_helper_get_fd(const char *env) } else if ((sl == LONG_MIN || sl == LONG_MAX) && errno == ERANGE) { TDM_ERR("%s out of range of type long\n", value); return -1; - } else if (sl > INT_MAX) { + } else if (sl >= INT_MAX) { TDM_ERR("%ld greater than INT_MAX\n", sl); return -1; - } else if (sl < INT_MIN) { + } else if (sl <= INT_MIN) { TDM_ERR("%ld less than INT_MIN\n", sl); return -1; } else { -- 2.7.4 From 456f771e2280747215eaf149663391a4578110b6 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 19 Jul 2017 14:36:16 +0900 Subject: [PATCH 04/16] package version up to 1.7.1 Change-Id: Ie7163eaa657b052afe4be96e7e46ad02b54fb295 --- packaging/libtdm.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index 3bc43e4..8e36bee 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -1,7 +1,7 @@ %bcond_with utest Name: libtdm -Version: 1.7.0 +Version: 1.7.1 Release: 0 Summary: User Library of Tizen Display Manager Group: Development/Libraries -- 2.7.4 From 584eccca95f5dbe7d7f5caa5e70443a6970b2eea Mon Sep 17 00:00:00 2001 From: Boram Park Date: Wed, 19 Jul 2017 15:10:06 +0900 Subject: [PATCH 05/16] lock/unlock when calling a tdm_output internal function Change-Id: I0b3e4023f79309fd276142a9706e6ade564e001c --- src/tdm_layer.c | 1 + src/tdm_output.c | 2 ++ src/tdm_vblank.c | 11 +++++++++++ 3 files changed, 14 insertions(+) diff --git a/src/tdm_layer.c b/src/tdm_layer.c index 9897c5c..6f7b16c 100644 --- a/src/tdm_layer.c +++ b/src/tdm_layer.c @@ -870,6 +870,7 @@ tdm_layer_remove_commit_handler_internal(tdm_layer *layer, tdm_layer_commit_hand tdm_private_layer_commit_handler *lm = NULL, *lmm = NULL; TDM_RETURN_IF_FAIL(private_layer != NULL); + TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED()); LIST_FOR_EACH_ENTRY_SAFE(lm, lmm, &private_output->layer_commit_handler_list, link) { if (lm->func == func && lm->user_data == user_data) { diff --git a/src/tdm_output.c b/src/tdm_output.c index 8b7abd4..f6d780a 100644 --- a/src/tdm_output.c +++ b/src/tdm_output.c @@ -810,6 +810,7 @@ tdm_output_remove_vblank_handler_internal(tdm_output *output, tdm_output_vblank_ tdm_private_vblank_handler *v = NULL; TDM_RETURN_IF_FAIL(private_output != NULL); + TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED()); LIST_FOR_EACH_ENTRY(v, &private_output->vblank_handler_list, link) { if (v->func == func && v->user_data == user_data) { @@ -828,6 +829,7 @@ tdm_output_remove_commit_handler_internal(tdm_output *output, tdm_output_commit_ tdm_private_output_commit_handler *c = NULL; TDM_RETURN_IF_FAIL(private_output != NULL); + TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED()); LIST_FOR_EACH_ENTRY(c, &private_output->output_commit_handler_list, link) { if (c->func == func && c->user_data == user_data) { diff --git a/src/tdm_vblank.c b/src/tdm_vblank.c index cb21a0c..88a5084 100644 --- a/src/tdm_vblank.c +++ b/src/tdm_vblank.c @@ -277,7 +277,11 @@ _tdm_vblank_change_to_SW(tdm_private_vblank *private_vblank) LIST_FOR_EACH_ENTRY_SAFE(w, ww, &private_vblank->HW_wait_list, link) { LIST_DEL(&w->link); + + tdm_display_lock(private_vblank->dpy); tdm_output_remove_vblank_handler_internal(private_vblank->output, _tdm_vblank_cb_vblank_HW, w); + tdm_display_unlock(private_vblank->dpy); + w->type = VBLANK_TYPE_SW_FAKE; _tdm_vblank_wait_SW(w); } @@ -291,7 +295,10 @@ _tdm_vblank_free_HW_wait(tdm_private_vblank *private_vblank, tdm_error error, un LIST_FOR_EACH_ENTRY_SAFE(w, ww, &private_vblank->HW_wait_list, link) { LIST_DEL(&w->link); _tdm_vblank_valid_list_del(&w->valid_link); + + tdm_display_lock(private_vblank->dpy); tdm_output_remove_vblank_handler_internal(private_vblank->output, _tdm_vblank_cb_vblank_HW, w); + tdm_display_unlock(private_vblank->dpy); if (call_cb && w->func) w->func(private_vblank, error, 0, 0, 0, w->user_data); @@ -1075,7 +1082,11 @@ tdm_vblank_wait(tdm_vblank *vblank, unsigned int req_sec, unsigned int req_usec, if (ret != TDM_ERROR_NONE) { LIST_DEL(&wait_info->link); _tdm_vblank_valid_list_del(&wait_info->valid_link); + + tdm_display_lock(private_vblank->dpy); tdm_output_remove_vblank_handler_internal(private_vblank->output, _tdm_vblank_cb_vblank_HW, wait_info); + tdm_display_unlock(private_vblank->dpy); + free(wait_info); return ret; } -- 2.7.4 From 472317e7ef4c44ffeb6abd60144a1cd5e953ee42 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Fri, 21 Jul 2017 16:09:57 +0900 Subject: [PATCH 06/16] lock/unlock outside of the helper function Change-Id: I58ffefedb39143391a62a3f9526dea09256f647b --- src/tdm_helper.c | 20 ++++++++------------ src/tdm_monitor_server.c | 2 ++ 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/tdm_helper.c b/src/tdm_helper.c index 712a9da..cf05aa0 100644 --- a/src/tdm_helper.c +++ b/src/tdm_helper.c @@ -789,7 +789,6 @@ tdm_helper_get_display_information(tdm_display *dpy, char *reply, int *len) private_display = dpy; func_output = &private_display->func_output; func_layer = &private_display->func_layer; - _pthread_mutex_lock(&private_display->lock); /* module information */ module_data = private_display->module_data; @@ -825,9 +824,9 @@ tdm_helper_get_display_information(tdm_display *dpy, char *reply, int *len) if (private_output->caps.mode_count > 0) { const tdm_output_mode *current_mode = NULL; - TDM_DBG_GOTO_IF_FAIL(func_output->output_get_mode, unlock); + TDM_DBG_RETURN_IF_FAIL(func_output->output_get_mode); ret = func_output->output_get_mode(private_output->output_backend, ¤t_mode); - TDM_DBG_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, unlock); + TDM_DBG_RETURN_IF_FAIL(ret == TDM_ERROR_NONE); TDM_SNPRINTF(reply, len, "\t\t name refresh (Hz) clk hdisp hss hse htot vdisp vss vse vtot vscan\n"); for (i = 0; i < private_output->caps.mode_count; i++) { @@ -858,11 +857,11 @@ tdm_helper_get_display_information(tdm_display *dpy, char *reply, int *len) TDM_SNPRINTF(reply, len, "\t\tname\ttype\tidx\tvalue\n"); for (i = 0; i < private_output->caps.prop_count; i++) { tdm_value value; - TDM_DBG_GOTO_IF_FAIL(func_output->output_get_property, unlock); + TDM_DBG_RETURN_IF_FAIL(func_output->output_get_property); ret = func_output->output_get_property(private_output->output_backend, private_output->caps.props[i].id, &value); - TDM_DBG_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, unlock); + TDM_DBG_RETURN_IF_FAIL(ret == TDM_ERROR_NONE); TDM_SNPRINTF(reply, len, "\t\t%s\t%s\t%u\t", private_output->caps.props[i].name, tdm_value_type_str(private_output->caps.props[i].type), @@ -903,10 +902,10 @@ tdm_helper_get_display_information(tdm_display *dpy, char *reply, int *len) tdm_size size; tbm_surface_info_s buf_info; - TDM_DBG_GOTO_IF_FAIL(func_layer->layer_get_info, unlock); + TDM_DBG_RETURN_IF_FAIL(func_layer->layer_get_info); memset(&info, 0, sizeof info); ret = func_layer->layer_get_info(private_layer->layer_backend, &info); - TDM_DBG_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, unlock); + TDM_DBG_RETURN_IF_FAIL(ret == TDM_ERROR_NONE); if (!private_layer->showing_buffer) continue; @@ -959,11 +958,11 @@ tdm_helper_get_display_information(tdm_display *dpy, char *reply, int *len) TDM_SNPRINTF(reply, len, "\t\tname\ttype\tidx\tvalue\n"); for (i = 0; i < private_layer->caps.prop_count; i++) { tdm_value value; - TDM_DBG_GOTO_IF_FAIL(func_layer->layer_get_property, unlock); + TDM_DBG_RETURN_IF_FAIL(func_layer->layer_get_property); ret = func_layer->layer_get_property(private_layer->layer_backend, private_layer->caps.props[i].id, &value); - TDM_DBG_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, unlock); + TDM_DBG_RETURN_IF_FAIL(ret == TDM_ERROR_NONE); TDM_SNPRINTF(reply, len, "\t\t%s\t%s\t%u\t", private_layer->caps.props[i].name, tdm_value_type_str(private_output->caps.props[i].type), @@ -1074,9 +1073,6 @@ tdm_helper_get_display_information(tdm_display *dpy, char *reply, int *len) TDM_SNPRINTF(reply, len, "[No Capture capability]\n"); } TDM_SNPRINTF(reply, len, "\n"); - -unlock: - _pthread_mutex_unlock(&private_display->lock); } EXTERN int diff --git a/src/tdm_monitor_server.c b/src/tdm_monitor_server.c index c46d457..e7844a5 100644 --- a/src/tdm_monitor_server.c +++ b/src/tdm_monitor_server.c @@ -50,7 +50,9 @@ static void _tdm_monitor_server_usage(char *app_name, char *reply, int *len); static void _tdm_monitor_server_query(unsigned int pid, char *cwd, int argc, char *argv[], char *reply, int *len, tdm_display *dpy) { + tdm_display_lock(dpy); tdm_helper_get_display_information(dpy, reply, len); + tdm_display_unlock(dpy); } static void -- 2.7.4 From cfd952b7abd487a592e2c625f5f37f439f324193 Mon Sep 17 00:00:00 2001 From: Sangjin Lee Date: Fri, 21 Jul 2017 13:44:23 +0900 Subject: [PATCH 07/16] dump: add function to check whether file is link or not According to security code guide, before open the file for write it should be check the file is symbolic link. Change-Id: I11e5be6898640995669c470cec703aef93869bfd --- src/tdm_helper.c | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/src/tdm_helper.c b/src/tdm_helper.c index cf05aa0..947d41e 100644 --- a/src/tdm_helper.c +++ b/src/tdm_helper.c @@ -68,12 +68,40 @@ tdm_helper_get_time(void) return 0; } +static int +_tdm_helper_check_file_is_valid(const char* path, int del_link) +{ + char *real_path; + + if (!path) + return 0; + + real_path = realpath(path, NULL); + if (real_path && strncmp(path, real_path, strlen(path))) { + if (del_link) + unlink(path); + free(real_path); + + return 0; + } + + if (real_path) + free(real_path); + + return 1; +} + static void _tdm_helper_dump_raw(const char *file, void *data1, int size1, void *data2, int size2, void *data3, int size3) { unsigned int *blocks; - FILE *fp = fopen(file, "w+"); + FILE *fp; + + if (!_tdm_helper_check_file_is_valid(file, 1)) + TDM_WRN("'%s' may be symbolic link\n", file); + + fp = fopen(file, "w+"); TDM_RETURN_IF_FAIL(fp != NULL); blocks = (unsigned int *)data1; @@ -96,7 +124,12 @@ static void _tdm_helper_dump_png(const char *file, const void *data, int width, int height) { - FILE *fp = fopen(file, "wb"); + FILE *fp; + + if (!_tdm_helper_check_file_is_valid(file, 1)) + TDM_WRN("'%s' may be symbolic link\n", file); + + fp = fopen(file, "wb"); TDM_RETURN_IF_FAIL(fp != NULL); png_structp pPngStruct = -- 2.7.4 From 1cf266db18d48f68aaf8b3606e705c05e749eaad Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 24 Jul 2017 09:34:15 +0900 Subject: [PATCH 08/16] package version up to 1.7.2 Change-Id: I1131954ba752ae4d6d2fc9e5bb79483e99015e63 --- packaging/libtdm.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index 8e36bee..803beff 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -1,7 +1,7 @@ %bcond_with utest Name: libtdm -Version: 1.7.1 +Version: 1.7.2 Release: 0 Summary: User Library of Tizen Display Manager Group: Development/Libraries -- 2.7.4 From 313cc5288224cf110c1d86b7700da77409ff6b79 Mon Sep 17 00:00:00 2001 From: Changyeon Lee Date: Mon, 24 Jul 2017 16:30:30 +0900 Subject: [PATCH 09/16] layer: check always commit handler list when checking commit possible Change-Id: I3a121f7a90e3ff68a473f473fbc6b4c864a0d859 Signed-off-by: Boram Park --- src/tdm_layer.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/tdm_layer.c b/src/tdm_layer.c index 6f7b16c..abf2a91 100644 --- a/src/tdm_layer.c +++ b/src/tdm_layer.c @@ -700,25 +700,38 @@ _tdm_lauer_get_output_used_layer_count(tdm_private_output *private_output) return count; } +/* commit_per_vblank == 1: we can commit if + * - there is no previous commit request + * - only 1 layer is used + * commit_per_vblank == 2: we can commit if + * - there is no previous commit request + */ static int _tdm_layer_commit_possible(tdm_private_layer *private_layer) { tdm_private_output *private_output = private_layer->private_output; tdm_private_display *private_display = private_output->private_display; - if (private_display->commit_per_vblank == 1 && _tdm_lauer_get_output_used_layer_count(private_output) == 1) { + TDM_RETURN_VAL_IF_FAIL(!(private_display->commit_per_vblank > 0), 1); + + /* There is a previous commit request which is not done and displayed on screen yet. + * We can't commit at this time. + */ + if (!LIST_IS_EMPTY(&private_output->layer_commit_handler_list)) { if (tdm_debug_module & TDM_DEBUG_COMMIT) - TDM_INFO("layer(%p) commit: 1 layer", private_layer); - return 1; + TDM_INFO("layer(%p) commit: not possible(previous commit)", private_layer); + return 0; } - if (private_display->commit_per_vblank == 2 && LIST_IS_EMPTY(&private_output->layer_commit_handler_list)) { + if (private_display->commit_per_vblank == 1 && _tdm_lauer_get_output_used_layer_count(private_output) > 1) { if (tdm_debug_module & TDM_DEBUG_COMMIT) - TDM_INFO("layer(%p) commit: non previous commit", private_layer); - return 1; + TDM_INFO("layer(%p) commit: not possible(more than 2 layers)", private_layer); + return 0; } - return 0; + TDM_INFO("layer(%p) commit: possible", private_layer); + + return 1; } /* CAUTION: Once _tdm_layer_commit returns success, the layer commit handler MUST be called always. -- 2.7.4 From 871e1c7106bd949a1daff413e5458f1d62cde7f0 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 24 Jul 2017 17:37:43 +0900 Subject: [PATCH 10/16] package version up to 1.7.3 Change-Id: I16d73e08975905546d71fe413e8395de75eba99d --- packaging/libtdm.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index 803beff..a0dfb3a 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -1,7 +1,7 @@ %bcond_with utest Name: libtdm -Version: 1.7.2 +Version: 1.7.3 Release: 0 Summary: User Library of Tizen Display Manager Group: Development/Libraries -- 2.7.4 From 08ac90dfd139c9760e878736095d4e8db4cce1aa Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 25 Jul 2017 18:58:56 +0900 Subject: [PATCH 11/16] correct the wrong condition Change-Id: Ie7a60db49527b1f1e71067d10eda4327d0492603 --- src/tdm_layer.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/tdm_layer.c b/src/tdm_layer.c index abf2a91..e751f54 100644 --- a/src/tdm_layer.c +++ b/src/tdm_layer.c @@ -712,7 +712,7 @@ _tdm_layer_commit_possible(tdm_private_layer *private_layer) tdm_private_output *private_output = private_layer->private_output; tdm_private_display *private_display = private_output->private_display; - TDM_RETURN_VAL_IF_FAIL(!(private_display->commit_per_vblank > 0), 1); + TDM_RETURN_VAL_IF_FAIL(private_display->commit_per_vblank > 0, 1); /* There is a previous commit request which is not done and displayed on screen yet. * We can't commit at this time. @@ -729,7 +729,8 @@ _tdm_layer_commit_possible(tdm_private_layer *private_layer) return 0; } - TDM_INFO("layer(%p) commit: possible", private_layer); + if (tdm_debug_module & TDM_DEBUG_COMMIT) + TDM_INFO("layer(%p) commit: possible", private_layer); return 1; } -- 2.7.4 From 6abc037265160665b1a54f67e79c019acda1b77f Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 25 Jul 2017 19:05:18 +0900 Subject: [PATCH 12/16] deinit the event loop after all resources are destroyed. The event loop should be deinited after all event sources are removed. The event sources can be removed in _tdm_display_destroy_private_display and _tdm_display_unload_module function. So we make the tdm thread join to the main thread and remove all resources. And finally we deinit the event loop. Change-Id: I32f3b5429b40b0711ef50215d05e0eda1c8b1814 --- src/tdm.c | 8 +++++--- src/tdm_event_loop.c | 14 ++++++++++++-- src/tdm_private.h | 2 ++ 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/tdm.c b/src/tdm.c index 9baace2..7723018 100644 --- a/src/tdm.c +++ b/src/tdm.c @@ -1006,6 +1006,7 @@ tdm_display_init(tdm_error *error) failed_update: _tdm_display_unload_module(private_display); failed_load: + tdm_event_loop_stop(private_display); tdm_event_loop_deinit(private_display); failed_event: _pthread_mutex_unlock(&private_display->lock); @@ -1040,11 +1041,12 @@ tdm_display_deinit(tdm_display *dpy) * things because it's finalized. */ _pthread_mutex_lock(&private_display->lock); - tdm_event_loop_deinit(private_display); - _pthread_mutex_unlock(&private_display->lock); - + tdm_event_loop_stop(private_display); _tdm_display_destroy_private_display(private_display); _tdm_display_unload_module(private_display); + _pthread_mutex_unlock(&private_display->lock); + + tdm_event_loop_deinit(private_display); #ifdef INIT_BUFMGR if (private_display->bufmgr) diff --git a/src/tdm_event_loop.c b/src/tdm_event_loop.c index c947243..1c88685 100644 --- a/src/tdm_event_loop.c +++ b/src/tdm_event_loop.c @@ -147,8 +147,9 @@ tdm_event_loop_deinit(tdm_private_display *private_display) if (!private_display->private_loop) return; - /* after tdm_thread_deinit, we don't worry about thread things because it's finalized */ - tdm_thread_deinit(private_display->private_loop); + if (tdm_thread_is_running()) + TDM_ERR("thread is still running. tdm_event_loop_stop SHOULD be called"); + tdm_server_deinit(private_display->private_loop); if (private_display->private_loop->backend_source) @@ -162,6 +163,15 @@ tdm_event_loop_deinit(tdm_private_display *private_display) } INTERN void +tdm_event_loop_stop(tdm_private_display *private_display) +{ + TDM_RETURN_IF_FAIL(TDM_MUTEX_IS_LOCKED()); + + /* after tdm_thread_deinit, we don't worry about thread things because it's finalized */ + tdm_thread_deinit(private_display->private_loop); +} + +INTERN void tdm_event_loop_create_backend_source(tdm_private_display *private_display) { tdm_private_loop *private_loop = private_display->private_loop; diff --git a/src/tdm_private.h b/src/tdm_private.h index 12ac385..cecf66d 100644 --- a/src/tdm_private.h +++ b/src/tdm_private.h @@ -494,6 +494,8 @@ tdm_event_loop_init(tdm_private_display *private_display); void tdm_event_loop_deinit(tdm_private_display *private_display); void +tdm_event_loop_stop(tdm_private_display *private_display); +void tdm_event_loop_create_backend_source(tdm_private_display *private_display); int tdm_event_loop_get_fd(tdm_private_display *private_display); -- 2.7.4 From 99800526d224cd5d8ae872a9047d9c648df41400 Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Fri, 28 Jul 2017 10:59:31 +0900 Subject: [PATCH 13/16] package version up to 1.7.4 Change-Id: I30ad6821660e110bf9b51dc80352a6e3092cfb98 --- packaging/libtdm.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtdm.spec b/packaging/libtdm.spec index a0dfb3a..5862dcf 100644 --- a/packaging/libtdm.spec +++ b/packaging/libtdm.spec @@ -1,7 +1,7 @@ %bcond_with utest Name: libtdm -Version: 1.7.3 +Version: 1.7.4 Release: 0 Summary: User Library of Tizen Display Manager Group: Development/Libraries -- 2.7.4 From 64548b108119a23117924598442f621a04675369 Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 7 Aug 2017 16:53:34 +0900 Subject: [PATCH 14/16] fix memory leak Change-Id: I3e259c314d069bc76884b96dba2b08d975060716 --- src/tdm_capture.c | 2 ++ src/tdm_pp.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/tdm_capture.c b/src/tdm_capture.c index 4772332..2bd1986 100644 --- a/src/tdm_capture.c +++ b/src/tdm_capture.c @@ -578,6 +578,8 @@ tdm_capture_commit(tdm_capture *capture) tdm_buffer_unref_backend(b->buffer); _pthread_mutex_lock(&private_display->lock); LIST_DEL(&b->link); + + free(b); } } diff --git a/src/tdm_pp.c b/src/tdm_pp.c index 02de669..52ef19b 100644 --- a/src/tdm_pp.c +++ b/src/tdm_pp.c @@ -496,6 +496,8 @@ tdm_pp_commit(tdm_pp *pp) tdm_buffer_unref_backend(b->dst); _pthread_mutex_lock(&private_display->lock); LIST_DEL(&b->link); + + free(b); } } -- 2.7.4 From 6aac53b7e9506ce76a53e2f5e8852f09b90b4c5d Mon Sep 17 00:00:00 2001 From: Boram Park Date: Mon, 7 Aug 2017 16:57:16 +0900 Subject: [PATCH 15/16] remove buffers from commit_buffer_list when commit failed. When pp, commit is the sync operation, cb_done() will be called at the line of commit(). In this case, buffers will be freed in cb_done() before LIST_FOR_EACH_ENTRY_SAFE(b, bb, &commit_buffer_list, commit_link) line done. So commit_link should be deleted when freed. When commit() successed, commit_link will be deleted twice. So we need to use LIST_DELINIT instead of LIST_DEL Change-Id: I6a09878e1eae49d31eb3f3626e005a3ae10841d8 --- src/tdm_capture.c | 3 ++- src/tdm_pp.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/tdm_capture.c b/src/tdm_capture.c index 2bd1986..6be39eb 100644 --- a/src/tdm_capture.c +++ b/src/tdm_capture.c @@ -149,6 +149,7 @@ tdm_capture_cb_done(tdm_capture *capture_backend, tbm_surface_h buffer, if ((capture_buffer = _tdm_capture_find_tbm_buffer(&private_capture->buffer_list, buffer))) { LIST_DEL(&capture_buffer->link); + LIST_DELINIT(&capture_buffer->commit_link); _pthread_mutex_unlock(&private_display->lock); if (private_capture->done_func) @@ -561,7 +562,7 @@ tdm_capture_commit(tdm_capture *capture) TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); LIST_FOR_EACH_ENTRY_SAFE(b, bb, &commit_buffer_list, commit_link) { - LIST_DEL(&b->commit_link); + LIST_DELINIT(&b->commit_link); if (!_tdm_capture_find_buffer(&private_capture->buffer_list, b)) continue; diff --git a/src/tdm_pp.c b/src/tdm_pp.c index 52ef19b..ab95105 100644 --- a/src/tdm_pp.c +++ b/src/tdm_pp.c @@ -150,6 +150,7 @@ tdm_pp_cb_done(tdm_pp *pp_backend, tbm_surface_h src, tbm_surface_h dst, if ((pp_buffer = _tdm_pp_find_tbm_buffers(&private_pp->buffer_list, src, dst))) { LIST_DEL(&pp_buffer->link); + LIST_DELINIT(&pp_buffer->commit_link); _pthread_mutex_unlock(&private_display->lock); if (private_pp->done_func) @@ -477,7 +478,7 @@ tdm_pp_commit(tdm_pp *pp) TDM_WARNING_IF_FAIL(ret == TDM_ERROR_NONE); LIST_FOR_EACH_ENTRY_SAFE(b, bb, &commit_buffer_list, commit_link) { - LIST_DEL(&b->commit_link); + LIST_DELINIT(&b->commit_link); if (!_tdm_pp_find_buffer(&private_pp->buffer_list, b)) continue; -- 2.7.4 From ac1f0059fbb5b8acb87137e06530601b08985a1f Mon Sep 17 00:00:00 2001 From: SooChan Lim Date: Mon, 7 Aug 2017 15:27:41 +0900 Subject: [PATCH 16/16] adapt ASLR for tdm-monitor and tools Change-Id: I14544a6fa5f4a9d4ded753ec12f031a7e09309ef --- client/Makefile.am | 5 ++++- tools/Makefile.am | 10 ++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/client/Makefile.am b/client/Makefile.am index becccc6..af2503f 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -36,9 +36,12 @@ bin_PROGRAMS = \ tdm_monitor_SOURCES = \ $(top_srcdir)/protocol/tdm-protocol.c \ tdm_monitor.c -tdm_monitor_LDFLAGS = ${LDFLAGS} +tdm_monitor_LDFLAGS = \ + -pie \ + ${LDFLAGS} tdm_monitor_LDADD = $(TDM_CLIENT_LIBS) ../common/libtdm-common.la tdm_monitor_CFLAGS = \ + -fPIE \ $(TDM_CFLAGS) \ -I$(top_srcdir)/include \ -I$(top_srcdir)/protocol \ diff --git a/tools/Makefile.am b/tools/Makefile.am index 2057e4a..d19e5e6 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -6,8 +6,11 @@ bin_PROGRAMS = \ tdm_test_server_SOURCES = \ buffers.c \ tdm_test_server.c -tdm_test_server_LDFLAGS = ${LDFLAGS} +tdm_test_server_LDFLAGS = \ + -pie \ + ${LDFLAGS} tdm_test_server_CFLAGS = \ + -fPIE \ $(TDM_CFLAGS) \ -I$(top_srcdir)/include \ -I$(top_srcdir)/src @@ -18,8 +21,11 @@ tdm_test_server_LDADD = \ #tdm-test-cliet tdm_test_client_SOURCES = \ tdm_test_client.c -tdm_test_client_LDFLAGS = ${LDFLAGS} +tdm_test_client_LDFLAGS = \ + -pie \ + ${LDFLAGS} tdm_test_client_CFLAGS = \ + -fPIE \ $(TDM_CFLAGS) \ -I$(top_srcdir)/include \ -I$(top_srcdir)/client \ -- 2.7.4