ini: first implementation 32/170532/2
authorBoram Park <boram1288.park@samsung.com>
Fri, 12 Jan 2018 08:31:29 +0000 (17:31 +0900)
committerBoram Park <boram1288.park@samsung.com>
Tue, 20 Feb 2018 23:04:04 +0000 (08:04 +0900)
Change-Id: I9e2fd2892279fbc84d1265802b5b33ef6d68dc27

configure.ac
include/tdm_backend.h
packaging/libtdm.spec
src/Makefile.am
src/tdm.c
src/tdm_config.c [new file with mode: 0644]
src/tdm_config.h [new file with mode: 0644]
src/tdm_private.h
tools/tdm_test_server.c

index 9a706cf..02919f8 100644 (file)
@@ -44,7 +44,7 @@ fi
 
 PKG_CHECK_MODULES(WAYLAND_SCANNER, wayland-scanner >= 1.7.0)
 
-PKG_CHECK_MODULES(TDM, dlog libtbm libpng pixman-1 wayland-server)
+PKG_CHECK_MODULES(TDM, dlog libtbm libpng pixman-1 wayland-server iniparser)
 PKG_CHECK_MODULES(TDM_CLIENT, dlog wayland-client)
 
 PKG_CHECK_MODULES(TTRACE,
@@ -72,6 +72,14 @@ AC_ARG_WITH(tdm-module-path, AS_HELP_STRING([--with-tdm-module-path=PATH], [tdm
 AC_DEFINE_UNQUOTED(TDM_MODULE_PATH, "${TDM_MODULE_PATH}", [Directory for the modules of tdm])
 AC_SUBST(TDM_MODULE_PATH)
 
+# set the data dir for the tdm config
+DEFAULT_TDM_DATA_PATH="${datadir}/tdm"
+AC_ARG_WITH(tdm-data-path, AS_HELP_STRING([--with-tdm-data-path=PATH], [tdm data dir]),
+                               [ TDM_DATA_PATH="$withval" ],
+                               [ TDM_DATA_PATH="${DEFAULT_TDM_DATA_PATH}" ])
+AC_DEFINE_UNQUOTED(TDM_DATA_PATH, "${TDM_DATA_PATH}", [Directory for the data of tdm])
+AC_SUBST(TDM_DATA_PATH)
+
 AC_SUBST([TDM_MAJOR_VERSION], [tdm_major_version])
 AC_SUBST([TDM_MINOR_VERSION], [tdm_minor_version])
 AC_SUBST([TDM_MICRO_VERSION], [tdm_micro_version])
@@ -105,4 +113,5 @@ echo "TDM_LIBS          : $TDM_LIBS"
 echo "TDM_CLIENT_CFLAGS : $TDM_CLIENT_CFLAGS"
 echo "TDM_CLIENT_LIBS   : $TDM_CLIENT_LIBS"
 echo "TDM_MODULE_PATH   : $TDM_MODULE_PATH"
+echo "TDM_DATA_PATH     : $TDM_DATA_PATH"
 echo ""
index 09b1377..de6fb24 100644 (file)
@@ -1446,6 +1446,29 @@ void
 tdm_event_loop_source_remove(tdm_event_loop_source *source);
 
 /**
+ * @brief Get the ini value with given key
+ * @details
+ * @param[in] key The given key
+ * @param[in] default_value The default value
+ * @return the value of given key if success. Otherwise, default_value.
+ * @see #tdm_config_get_string
+ */
+int
+tdm_config_get_int(const char *key, int default_value);
+
+/**
+ * @brief Get the ini value with given key
+ * @details
+ * @param[in] key The given key
+ * @param[in] default_value The default value
+ * @return the value of given key if success. Otherwise, default_value.
+ * @see #tdm_config_get_int
+ */
+const char *
+tdm_config_get_string(const char *key, const char *default_value);
+
+
+/**
  * @brief Trigger a 'need to validate' event.
  * @param[in] output The output the event should be triggered for.
  * @note The global display lock has to be locked before the call to this function.
index 876648f..7140089 100644 (file)
@@ -13,6 +13,7 @@ BuildRequires:  pkgconfig(libtbm)
 BuildRequires:  pkgconfig(libpng)
 BuildRequires:  pkgconfig(ttrace)
 BuildRequires:  pkgconfig(wayland-server)
+BuildRequires:  pkgconfig(iniparser)
 BuildRequires:  pkgconfig(pixman-1)
 BuildRequires:  gtest-devel 
 
@@ -82,6 +83,7 @@ LDFLAGS+=" -lgcov"
 %endif
 
 %reconfigure --disable-static --with-utests=${UTEST} \
+             --with-tdm-data-path=%{TZ_SYS_RO_SHARE}/tdm \
              CFLAGS="${CFLAGS} -Wall -Werror" \
              CXXFLAGS="${CXXFLAGS} -Wall -Werror" \
              LDFLAGS="${LDFLAGS} -Wl,--hash-style=both -Wl,--as-needed"
index feabb5d..7ec1cd4 100644 (file)
@@ -13,6 +13,7 @@ libtdm_la_CFLAGS = \
 libtdm_la_SOURCES = \
        $(top_srcdir)/protocol/tdm-protocol.c \
        tdm_backend.c \
+       tdm_config.c \
        tdm_server.c \
        tdm_vblank.c \
        tdm_event_loop.c \
index 312bac9..96bed27 100644 (file)
--- a/src/tdm.c
+++ b/src/tdm.c
@@ -943,6 +943,14 @@ tdm_display_init(tdm_error *error)
 
        start = stamp1 = tdm_helper_get_time();
 
+       ret = tdm_config_init();
+       if (ret != TDM_ERROR_NONE)
+               goto failed_config;
+
+       stamp2 = tdm_helper_get_time();
+       TDM_DBG("config init time: %.3f ms", (stamp2 - stamp1) * 1000.0);
+       stamp1 = stamp2;
+
        private_display = calloc(1, sizeof(tdm_private_display));
        if (!private_display) {
                /* LCOV_EXCL_START */
@@ -1077,6 +1085,8 @@ failed_vblank:
 failed_mutex_init:
        free(private_display);
 failed_alloc:
+       tdm_config_deinit();
+failed_config:
        if (error)
                *error = ret;
        pthread_mutex_unlock(&gLock);
@@ -1131,6 +1141,8 @@ tdm_display_deinit(tdm_display *dpy)
                tdm_debug_dump_dir = NULL;
        }
 
+       tdm_config_deinit();
+
        pthread_mutex_unlock(&gLock);
 
        TDM_INFO("done");
diff --git a/src/tdm_config.c b/src/tdm_config.c
new file mode 100644 (file)
index 0000000..6686769
--- /dev/null
@@ -0,0 +1,283 @@
+/**************************************************************************
+ *
+ * libtdm
+ *
+ * Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
+ *
+ * Contact: Eunchul Kim <chulspro.kim@samsung.com>,
+ *          JinYoung Jeon <jy0.jeon@samsung.com>,
+ *          Taeheon Kim <th908.kim@samsung.com>,
+ *          YoungJun Cho <yj44.cho@samsung.com>,
+ *          SooChan Lim <sc1.lim@samsung.com>,
+ *          Boram Park <sc1.lim@samsung.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+**************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <iniparser.h>
+
+#include "tdm_log.h"
+#include "tdm_macro.h"
+#include "tdm_list.h"
+#include "tdm.h"
+#include "tdm_private.h"
+#include "tdm_config.h"
+
+#define TDM_CONFIG_FILENAME "tdm.ini"
+#define TDM_CONFIG_GENERAL_SECTION "general"
+
+static dictionary *g_dic = NULL;
+static pthread_mutex_t g_dic_lock;
+
+static int
+_tdm_config_check_file_owner(const char *filepath)
+{
+       struct stat sb;
+
+       if (stat(filepath, &sb) < 0) {
+               TDM_WRN("%s: %m", filepath);
+               return -1;
+       }
+
+       if (sb.st_uid != getuid()) {
+               TDM_WRN("'%s': not owned by %u", filepath, getuid());
+               return -1;
+       }
+
+       return 0;
+}
+
+static dictionary *
+_tdm_config_load_file(const char *dir, const char *filename)
+{
+       char filepath[TDM_PATH_LEN];
+       dictionary *dic;
+
+       snprintf(filepath, sizeof filepath, "%s/%s", dir, filename);
+
+       if (_tdm_config_check_file_owner(filepath) < 0)
+               return NULL;
+
+       dic = iniparser_load(filepath);
+       TDM_RETURN_VAL_IF_FAIL(dic != NULL, NULL);
+
+       if (!iniparser_find_entry(dic, TDM_CONFIG_GENERAL_SECTION)) {
+               TDM_ERR("no '%s' section: '%s'", TDM_CONFIG_GENERAL_SECTION, filepath);
+               iniparser_freedict(dic);
+               return NULL;
+       }
+
+       TDM_INFO("opened successed: '%s'", filepath);
+
+       return dic;
+}
+
+static dictionary *
+_tdm_config_load(void)
+{
+       dictionary *dic = NULL;
+
+#if 0
+       /* not allowed: try to read from RW directory */
+       dic = _tdm_config_load_file(TDM_SYSCONF_PATH, TDM_CONFIG_FILENAME);
+#endif
+
+       if (!dic) {
+               /* try to read from RO directory */
+               dic = _tdm_config_load_file(TDM_DATA_PATH, TDM_CONFIG_FILENAME);
+       }
+
+       return dic;
+}
+
+INTERN tdm_error
+tdm_config_init(void)
+{
+       if (g_dic) {
+               TDM_ERR("init failed: twice");
+               return TDM_ERROR_OPERATION_FAILED;
+       }
+
+       if (pthread_mutex_init(&g_dic_lock, NULL)) {
+               TDM_ERR("mutex init failed: %m");
+               return TDM_ERROR_OUT_OF_MEMORY;
+       }
+
+       g_dic = _tdm_config_load();
+       if (!g_dic) {
+               if (!getenv("TDM_NO_CONFIG")) {
+                       TDM_ERR("Loading config file failed!!");
+                       pthread_mutex_destroy(&g_dic_lock);
+                       return TDM_ERROR_NONE;
+               }
+       }
+
+       TDM_INFO("tdm config init done (%p)", g_dic);
+
+       return TDM_ERROR_NONE;
+}
+
+INTERN void
+tdm_config_deinit(void)
+{
+       if (!g_dic) {
+               return;
+       }
+
+       iniparser_freedict(g_dic);
+       g_dic = NULL;
+
+       /* we don't need to lock/unlock here because we come here
+        * after tdm_thread has been destroyed
+        */
+       pthread_mutex_destroy(&g_dic_lock);
+
+       TDM_INFO("tdm config deinit done");
+}
+
+static const char*
+_tdm_config_get_string_internal(dictionary *dic, const char *key, const char *default_value)
+{
+       char *temp = NULL;
+       const char *result;
+
+       if (default_value) {
+               temp = strdup(default_value);
+               if (!temp) {
+                       TDM_ERR("strdup failed: %m");
+                       return default_value;
+               }
+       }
+
+       result = (const char *)iniparser_getstring(dic, key, temp);
+       if (!result || strlen(result) == 0) {
+               free(temp);
+               return default_value;
+       }
+
+       free(temp);
+
+       return result;
+}
+
+INTERN int
+tdm_config_get_int(const char *key, int default_value)
+{
+       const char *result;
+       int value;
+
+       TDM_RETURN_VAL_IF_FAIL(key != NULL, default_value);
+
+       if (!g_dic) {
+               TDM_INFO("%s = %d: default", key, default_value);
+               return default_value;
+       }
+
+       pthread_mutex_lock(&g_dic_lock);
+       result = _tdm_config_get_string_internal(g_dic, key, NULL);
+       pthread_mutex_unlock(&g_dic_lock);
+
+       if (!result) {
+               TDM_INFO("%s = %d: no key", key, default_value);
+               return default_value;
+       }
+
+       value = (int)strtol(result, NULL, 0);
+
+       TDM_INFO("%s = %d", key, value);
+
+       return value;
+}
+
+INTERN const char*
+tdm_config_get_string(const char *key, const char *default_value)
+{
+       const char *result;
+
+       TDM_RETURN_VAL_IF_FAIL(key != NULL, default_value);
+
+       if (!g_dic) {
+               TDM_INFO("%s = %s: default", key, default_value);
+               return default_value;
+       }
+
+       pthread_mutex_lock(&g_dic_lock);
+       result = _tdm_config_get_string_internal(g_dic, key, default_value);
+       pthread_mutex_unlock(&g_dic_lock);
+
+       TDM_INFO("%s = %s", key, result);
+
+       return result;
+}
+
+INTERN tdm_error
+tdm_config_set_int(const char *key, int value)
+{
+       char temp[TDM_NAME_LEN];
+       int ret;
+
+       TDM_RETURN_VAL_IF_FAIL(key != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+       if (!g_dic) {
+               TDM_INFO("%s = %d set failed", key, value);
+               return TDM_ERROR_BAD_REQUEST;
+       }
+
+       snprintf(temp, sizeof temp, "%d", value);
+
+       pthread_mutex_lock(&g_dic_lock);
+       ret = iniparser_set(g_dic, key, (const char*)temp);
+       pthread_mutex_unlock(&g_dic_lock);
+
+       TDM_RETURN_VAL_IF_FAIL(ret == 0, TDM_ERROR_OPERATION_FAILED);
+
+       TDM_INFO("%s = %d set done", key, value);
+
+       return TDM_ERROR_NONE;
+}
+
+INTERN tdm_error
+tdm_config_set_string(const char *key, const char *value)
+{
+       int ret;
+
+       TDM_RETURN_VAL_IF_FAIL(key != NULL, TDM_ERROR_INVALID_PARAMETER);
+
+       if (!g_dic) {
+               TDM_INFO("%s = %s set failed", key, value);
+               return TDM_ERROR_BAD_REQUEST;
+       }
+
+       pthread_mutex_lock(&g_dic_lock);
+       ret = iniparser_set(g_dic, key, value);
+       pthread_mutex_unlock(&g_dic_lock);
+
+       TDM_RETURN_VAL_IF_FAIL(ret == 0, TDM_ERROR_OPERATION_FAILED);
+
+       TDM_INFO("%s = %s set done", key, value);
+
+       return TDM_ERROR_NONE;
+}
diff --git a/src/tdm_config.h b/src/tdm_config.h
new file mode 100644 (file)
index 0000000..b743f93
--- /dev/null
@@ -0,0 +1,67 @@
+/**************************************************************************
+ *
+ * libtdm
+ *
+ * Copyright 2015 Samsung Electronics co., Ltd. All Rights Reserved.
+ *
+ * Contact: Eunchul Kim <chulspro.kim@samsung.com>,
+ *          JinYoung Jeon <jy0.jeon@samsung.com>,
+ *          Taeheon Kim <th908.kim@samsung.com>,
+ *          YoungJun Cho <yj44.cho@samsung.com>,
+ *          SooChan Lim <sc1.lim@samsung.com>,
+ *          Boram Park <sc1.lim@samsung.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+**************************************************************************/
+
+#ifndef _TDM_CONFIG_H_
+#define _TDM_CONFIG_H_
+
+#include "tdm_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "tdm_common.h"
+
+/**
+ * @file tdm_config.h
+ * @brief The config header file for a frontend library
+ */
+
+tdm_error
+tdm_config_init(void);
+void
+tdm_config_deinit(void);
+
+tdm_error
+tdm_config_set_int(const char *key, int value);
+tdm_error
+tdm_config_set_string(const char *key, const char *value);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TDM_CONFIG_H_ */
index a055105..f7c2a11 100644 (file)
@@ -64,6 +64,7 @@
 #include "tdm_macro.h"
 #include "tdm_helper.h"
 #include "tdm_thread.h"
+#include "tdm_config.h"
 
 #ifdef __cplusplus
 extern "C" {
index 52e0f61..db70668 100644 (file)
@@ -183,7 +183,6 @@ usage(char *app_name)
                printf("\t%s\n", usages[t].desc);
        }
        printf("\n");
-       exit(0);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -316,6 +315,7 @@ struct _tdm_test_server {
        tdm_display *display;
 };
 
+static void destroy(tdm_test_server *data);
 static void run_test(tdm_test_server *data);
 static void output_setup(tdm_test_server_output *o);
 static void layer_show_buffer(tdm_test_server_layer *l, tbm_surface_h b);
@@ -517,6 +517,7 @@ parse_args(tdm_test_server *data, int argc, char *argv[])
 
        if (argc < 2) {
                usage(argv[0]);
+               destroy(data);
                exit(0);
        }
 
@@ -597,6 +598,7 @@ parse_args(tdm_test_server *data, int argc, char *argv[])
                        data->do_vblank = 1;
                } else {
                        usage(argv[0]);
+                       destroy(data);
                        exit(0);
                }
        }