From c7806ebca20e178d5484f639b751e1b0b9e873b3 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Thu, 25 Apr 2024 13:58:02 +0800 Subject: [PATCH] fix(util): fix race condition. --- include/common/tcommon.h | 3 +- include/common/tglobal.h | 2 +- include/util/tconfig.h | 32 ++-- source/client/src/clientEnv.c | 57 ++++--- source/client/test/clientTests.cpp | 8 +- source/common/src/tglobal.c | 19 ++- source/common/src/tmisce.c | 48 +++++- source/dnode/mgmt/mgmt_dnode/src/dmHandle.c | 35 +--- source/libs/command/src/command.c | 37 +--- source/util/src/tconfig.c | 178 +++++++++++--------- 10 files changed, 221 insertions(+), 198 deletions(-) diff --git a/include/common/tcommon.h b/include/common/tcommon.h index 2c4a00a72d..d28477ae40 100644 --- a/include/common/tcommon.h +++ b/include/common/tcommon.h @@ -15,7 +15,7 @@ #ifndef _TD_COMMON_DEF_H_ #define _TD_COMMON_DEF_H_ -// #include "taosdef.h" + #include "tarray.h" #include "tmsg.h" #include "tvariant.h" @@ -412,6 +412,7 @@ typedef struct STUidTagInfo { #define UD_TAG_COLUMN_INDEX 2 int32_t taosGenCrashJsonMsg(int signum, char** pMsg, int64_t clusterId, int64_t startTime); +int32_t dumpConfToDataBlock(SSDataBlock* pBlock, int32_t startCol); #define TSMA_RES_STB_POSTFIX "_tsma_res_stb_" #define MD5_OUTPUT_LEN 32 diff --git a/include/common/tglobal.h b/include/common/tglobal.h index 00ed8bfb8e..3b8929f241 100644 --- a/include/common/tglobal.h +++ b/include/common/tglobal.h @@ -260,7 +260,7 @@ int32_t taosInitCfg(const char *cfgDir, const char **envCmd, const char *envFile bool tsc); void taosCleanupCfg(); -int32_t taosCfgDynamicOptions(SConfig *pCfg, char *name, bool forServer); +int32_t taosCfgDynamicOptions(SConfig *pCfg, const char *name, bool forServer); struct SConfig *taosGetCfg(); diff --git a/include/util/tconfig.h b/include/util/tconfig.h index 45abe2ff83..2095601e14 100644 --- a/include/util/tconfig.h +++ b/include/util/tconfig.h @@ -98,34 +98,32 @@ typedef struct { const char *value; } SConfigPair; -typedef struct SConfig { - ECfgSrcType stype; - SArray *array; -} SConfig; - -SConfig *cfgInit(); -int32_t cfgLoad(SConfig *pCfg, ECfgSrcType cfgType, const void *sourceStr); -int32_t cfgLoadFromArray(SConfig *pCfg, SArray *pArgs); // SConfigPair -void cfgCleanup(SConfig *pCfg); +typedef struct SConfig SConfig; +typedef struct SConfigIter SConfigIter; +SConfig *cfgInit(); +int32_t cfgLoad(SConfig *pCfg, ECfgSrcType cfgType, const void *sourceStr); +int32_t cfgLoadFromArray(SConfig *pCfg, SArray *pArgs); // SConfigPair +void cfgCleanup(SConfig *pCfg); int32_t cfgGetSize(SConfig *pCfg); SConfigItem *cfgGetItem(SConfig *pCfg, const char *name); int32_t cfgSetItem(SConfig *pCfg, const char *name, const char *value, ECfgSrcType stype); +int32_t cfgCheckRangeForDynUpdate(SConfig *pCfg, const char *name, const char *pVal, bool isServer); +SConfigIter *cfgCreateIter(SConfig *pConf); +SConfigItem *cfgNextIter(SConfigIter *pIter); +void cfgDestroyIter(SConfigIter *pIter); -int32_t cfgCheckRangeForDynUpdate(SConfig *pCfg, const char *name, const char *pVal, bool isServer); - +// clang-format off int32_t cfgAddBool(SConfig *pCfg, const char *name, bool defaultVal, int8_t scope, int8_t dynScope); -int32_t cfgAddInt32(SConfig *pCfg, const char *name, int32_t defaultVal, int64_t minval, int64_t maxval, int8_t scope, - int8_t dynScope); -int32_t cfgAddInt64(SConfig *pCfg, const char *name, int64_t defaultVal, int64_t minval, int64_t maxval, int8_t scope, - int8_t dynScope); -int32_t cfgAddFloat(SConfig *pCfg, const char *name, float defaultVal, float minval, float maxval, int8_t scope, - int8_t dynScope); +int32_t cfgAddInt32(SConfig *pCfg, const char *name, int32_t defaultVal, int64_t minval, int64_t maxval, int8_t scope, int8_t dynScope); +int32_t cfgAddInt64(SConfig *pCfg, const char *name, int64_t defaultVal, int64_t minval, int64_t maxval, int8_t scope, int8_t dynScope); +int32_t cfgAddFloat(SConfig *pCfg, const char *name, float defaultVal, float minval, float maxval, int8_t scope, int8_t dynScope); int32_t cfgAddString(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope, int8_t dynScope); int32_t cfgAddDir(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope, int8_t dynScope); int32_t cfgAddLocale(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope, int8_t dynScope); int32_t cfgAddCharset(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope, int8_t dynScope); int32_t cfgAddTimezone(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope, int8_t dynScope); +// clang-format on const char *cfgStypeStr(ECfgSrcType type); const char *cfgDtypeStr(ECfgDataType type); diff --git a/source/client/src/clientEnv.c b/source/client/src/clientEnv.c index 7f73aa6845..f37e9851e1 100644 --- a/source/client/src/clientEnv.c +++ b/source/client/src/clientEnv.c @@ -770,6 +770,32 @@ int taos_init() { return tscInitRes; } +const char* getCfgName(TSDB_OPTION option) { + const char* name = NULL; + + switch (option) { + case TSDB_OPTION_SHELL_ACTIVITY_TIMER: + name = "shellActivityTimer"; + break; + case TSDB_OPTION_LOCALE: + name = "locale"; + break; + case TSDB_OPTION_CHARSET: + name = "charset"; + break; + case TSDB_OPTION_TIMEZONE: + name = "timezone"; + break; + case TSDB_OPTION_USE_ADAPTER: + name = "useAdapter"; + break; + default: + break; + } + + return name; +} + int taos_options_imp(TSDB_OPTION option, const char *str) { if (option == TSDB_OPTION_CONFIGDIR) { #ifndef WINDOWS @@ -799,39 +825,26 @@ int taos_options_imp(TSDB_OPTION option, const char *str) { SConfig *pCfg = taosGetCfg(); SConfigItem *pItem = NULL; + const char *name = getCfgName(option); - switch (option) { - case TSDB_OPTION_SHELL_ACTIVITY_TIMER: - pItem = cfgGetItem(pCfg, "shellActivityTimer"); - break; - case TSDB_OPTION_LOCALE: - pItem = cfgGetItem(pCfg, "locale"); - break; - case TSDB_OPTION_CHARSET: - pItem = cfgGetItem(pCfg, "charset"); - break; - case TSDB_OPTION_TIMEZONE: - pItem = cfgGetItem(pCfg, "timezone"); - break; - case TSDB_OPTION_USE_ADAPTER: - pItem = cfgGetItem(pCfg, "useAdapter"); - break; - default: - break; + if (name == NULL) { + tscError("Invalid option %d", option); + return -1; } + pItem = cfgGetItem(pCfg, name); if (pItem == NULL) { tscError("Invalid option %d", option); return -1; } - int code = cfgSetItem(pCfg, pItem->name, str, CFG_STYPE_TAOS_OPTIONS); + int code = cfgSetItem(pCfg, name, str, CFG_STYPE_TAOS_OPTIONS); if (code != 0) { - tscError("failed to set cfg:%s to %s since %s", pItem->name, str, terrstr()); + tscError("failed to set cfg:%s to %s since %s", name, str, terrstr()); } else { - tscInfo("set cfg:%s to %s", pItem->name, str); + tscInfo("set cfg:%s to %s", name, str); if (TSDB_OPTION_SHELL_ACTIVITY_TIMER == option || TSDB_OPTION_USE_ADAPTER == option) { - code = taosCfgDynamicOptions(pCfg, pItem->name, false); + code = taosCfgDynamicOptions(pCfg, name, false); } } diff --git a/source/client/test/clientTests.cpp b/source/client/test/clientTests.cpp index 778b1826b4..b534671acb 100644 --- a/source/client/test/clientTests.cpp +++ b/source/client/test/clientTests.cpp @@ -827,10 +827,14 @@ TEST(clientCase, projection_query_tables) { // } // taos_free_result(pRes); - TAOS_RES* pRes = taos_query(pConn, "use test"); + TAOS_RES* pRes = taos_query(pConn, "use cache_1"); taos_free_result(pRes); - pRes = taos_query(pConn, "create table st2 (ts timestamp, k int primary key, j varchar(1000)) tags(a int)"); + pRes = taos_query(pConn, "select last(ts), ts from cache_1.t1"); +// pRes = taos_query(pConn, "select last(ts), ts from cache_1.no_pk_t1"); + if (taos_errno(pRes) != 0) { + printf("failed to exec query, %s\n", taos_errstr(pRes)); + } taos_free_result(pRes); // pRes = taos_query(pConn, "create stream stream_1 trigger at_once fill_history 1 ignore expired 0 into str_res1 as select _wstart as ts, count(*) from stable_1 interval(10s);"); diff --git a/source/common/src/tglobal.c b/source/common/src/tglobal.c index 24f00ab6a5..ba96dc0adf 100644 --- a/source/common/src/tglobal.c +++ b/source/common/src/tglobal.c @@ -1032,7 +1032,7 @@ static void taosSetServerLogCfg(SConfig *pCfg) { sndDebugFlag = cfgGetItem(pCfg, "sndDebugFlag")->i32; } -static int32_t taosSetSlowLogScope(char *pScope) { +static int32_t taosSetSlowLogScope(const char *pScope) { if (NULL == pScope || 0 == strlen(pScope)) { tsSlowLogScope = SLOW_LOG_TYPE_ALL; return 0; @@ -1505,7 +1505,7 @@ static int32_t taosCfgSetOption(OptionNameAndVar *pOptions, int32_t optionSize, return terrno == TSDB_CODE_SUCCESS ? 0 : -1; } -static int32_t taosCfgDynamicOptionsForServer(SConfig *pCfg, char *name) { +static int32_t taosCfgDynamicOptionsForServer(SConfig *pCfg, const char *name) { terrno = TSDB_CODE_SUCCESS; if (strcasecmp(name, "resetlog") == 0) { @@ -1583,11 +1583,12 @@ static int32_t taosCfgDynamicOptionsForServer(SConfig *pCfg, char *name) { return terrno == TSDB_CODE_SUCCESS ? 0 : -1; } -static int32_t taosCfgDynamicOptionsForClient(SConfig *pCfg, char *name) { +// todo fix race condition caused by update of config, pItem->str may be removed +static int32_t taosCfgDynamicOptionsForClient(SConfig *pCfg, const char *name) { terrno = TSDB_CODE_SUCCESS; SConfigItem *pItem = cfgGetItem(pCfg, name); - if (!pItem || (pItem->dynScope & CFG_DYN_CLIENT) == 0) { + if ((pItem == NULL) || (pItem->dynScope & CFG_DYN_CLIENT) == 0) { uError("failed to config:%s, not support", name); terrno = TSDB_CODE_INVALID_CFG; return -1; @@ -1598,6 +1599,7 @@ static int32_t taosCfgDynamicOptionsForClient(SConfig *pCfg, char *name) { int32_t len = strlen(name); char lowcaseName[CFG_NAME_MAX_LEN + 1] = {0}; strntolower(lowcaseName, name, TMIN(CFG_NAME_MAX_LEN, len)); + switch (lowcaseName[0]) { case 'd': { if (strcasecmp("debugFlag", name) == 0) { @@ -1803,9 +1805,12 @@ _out: return terrno == TSDB_CODE_SUCCESS ? 0 : -1; } -int32_t taosCfgDynamicOptions(SConfig *pCfg, char *name, bool forServer) { - if (forServer) return taosCfgDynamicOptionsForServer(pCfg, name); - return taosCfgDynamicOptionsForClient(pCfg, name); +int32_t taosCfgDynamicOptions(SConfig *pCfg, const char *name, bool forServer) { + if (forServer) { + return taosCfgDynamicOptionsForServer(pCfg, name); + } else { + return taosCfgDynamicOptionsForClient(pCfg, name); + } } void taosSetDebugFlag(int32_t *pFlagPtr, const char *flagName, int32_t flagVal) { diff --git a/source/common/src/tmisce.c b/source/common/src/tmisce.c index 77dd8344b1..0a9e8f434b 100644 --- a/source/common/src/tmisce.c +++ b/source/common/src/tmisce.c @@ -17,6 +17,8 @@ #include "tmisce.h" #include "tglobal.h" #include "tjson.h" +#include "tdatablock.h" + int32_t taosGetFqdnPortFromEp(const char* ep, SEp* pEp) { pEp->port = 0; memset(pEp->fqdn, 0, TSDB_FQDN_LEN); @@ -97,10 +99,10 @@ void epsetSort(SEpSet* pDst) { SEp* s = &pDst->eps[j + 1]; int cmp = strncmp(f->fqdn, s->fqdn, sizeof(f->fqdn)); if (cmp > 0 || (cmp == 0 && f->port > s->port)) { - SEp ep = {0}; - epAssign(&ep, f); + SEp ep1 = {0}; + epAssign(&ep1, f); epAssign(f, s); - epAssign(s, &ep); + epAssign(s, &ep1); } } } @@ -216,3 +218,43 @@ int32_t taosGenCrashJsonMsg(int signum, char** pMsg, int64_t clusterId, int64_t return TSDB_CODE_SUCCESS; } + +int32_t dumpConfToDataBlock(SSDataBlock* pBlock, int32_t startCol) { + SConfig* pConf = taosGetCfg(); + int32_t numOfRows = 0; + int32_t col = startCol; + SConfigItem* pItem = NULL; + + blockDataEnsureCapacity(pBlock, cfgGetSize(pConf)); + SConfigIter* pIter = cfgCreateIter(pConf); + + while ((pItem = cfgNextIter(pIter)) != NULL) { + col = startCol; + + // GRANT_CFG_SKIP; + char name[TSDB_CONFIG_OPTION_LEN + VARSTR_HEADER_SIZE] = {0}; + STR_WITH_MAXSIZE_TO_VARSTR(name, pItem->name, TSDB_CONFIG_OPTION_LEN + VARSTR_HEADER_SIZE); + SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, col++); + colDataSetVal(pColInfo, numOfRows, name, false); + + char value[TSDB_CONFIG_VALUE_LEN + VARSTR_HEADER_SIZE] = {0}; + int32_t valueLen = 0; + cfgDumpItemValue(pItem, &value[VARSTR_HEADER_SIZE], TSDB_CONFIG_VALUE_LEN, &valueLen); + varDataSetLen(value, valueLen); + pColInfo = taosArrayGet(pBlock->pDataBlock, col++); + colDataSetVal(pColInfo, numOfRows, value, false); + + char scope[TSDB_CONFIG_SCOPE_LEN + VARSTR_HEADER_SIZE] = {0}; + cfgDumpItemScope(pItem, &scope[VARSTR_HEADER_SIZE], TSDB_CONFIG_SCOPE_LEN, &valueLen); + varDataSetLen(scope, valueLen); + pColInfo = taosArrayGet(pBlock->pDataBlock, col++); + colDataSetVal(pColInfo, numOfRows, scope, false); + + numOfRows++; + } + + pBlock->info.rows = numOfRows; + + cfgDestroyIter(pIter); + return TSDB_CODE_SUCCESS; +} diff --git a/source/dnode/mgmt/mgmt_dnode/src/dmHandle.c b/source/dnode/mgmt/mgmt_dnode/src/dmHandle.c index 12e414b30d..56fdb463c4 100644 --- a/source/dnode/mgmt/mgmt_dnode/src/dmHandle.c +++ b/source/dnode/mgmt/mgmt_dnode/src/dmHandle.c @@ -333,39 +333,10 @@ SSDataBlock *dmBuildVariablesBlock(void) { } int32_t dmAppendVariablesToBlock(SSDataBlock *pBlock, int32_t dnodeId) { - int32_t numOfCfg = taosArrayGetSize(tsCfg->array); - int32_t numOfRows = 0; - blockDataEnsureCapacity(pBlock, numOfCfg); + /*int32_t code = */dumpConfToDataBlock(pBlock, 1); - for (int32_t i = 0, c = 0; i < numOfCfg; ++i, c = 0) { - SConfigItem *pItem = taosArrayGet(tsCfg->array, i); - // GRANT_CFG_SKIP; - - SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, c++); - colDataSetVal(pColInfo, i, (const char *)&dnodeId, false); - - char name[TSDB_CONFIG_OPTION_LEN + VARSTR_HEADER_SIZE] = {0}; - STR_WITH_MAXSIZE_TO_VARSTR(name, pItem->name, TSDB_CONFIG_OPTION_LEN + VARSTR_HEADER_SIZE); - pColInfo = taosArrayGet(pBlock->pDataBlock, c++); - colDataSetVal(pColInfo, i, name, false); - - char value[TSDB_CONFIG_VALUE_LEN + VARSTR_HEADER_SIZE] = {0}; - int32_t valueLen = 0; - cfgDumpItemValue(pItem, &value[VARSTR_HEADER_SIZE], TSDB_CONFIG_VALUE_LEN, &valueLen); - varDataSetLen(value, valueLen); - pColInfo = taosArrayGet(pBlock->pDataBlock, c++); - colDataSetVal(pColInfo, i, value, false); - - char scope[TSDB_CONFIG_SCOPE_LEN + VARSTR_HEADER_SIZE] = {0}; - cfgDumpItemScope(pItem, &scope[VARSTR_HEADER_SIZE], TSDB_CONFIG_SCOPE_LEN, &valueLen); - varDataSetLen(scope, valueLen); - pColInfo = taosArrayGet(pBlock->pDataBlock, c++); - colDataSetVal(pColInfo, i, scope, false); - - numOfRows++; - } - - pBlock->info.rows = numOfRows; + SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, 0); + colDataSetNItems(pColInfo, 0, (const char *)&dnodeId, pBlock->info.rows, false); return TSDB_CODE_SUCCESS; } diff --git a/source/libs/command/src/command.c b/source/libs/command/src/command.c index bf901188dc..2d190edb58 100644 --- a/source/libs/command/src/command.c +++ b/source/libs/command/src/command.c @@ -955,46 +955,11 @@ static int32_t buildLocalVariablesResultDataBlock(SSDataBlock** pOutput) { return TSDB_CODE_SUCCESS; } -int32_t setLocalVariablesResultIntoDataBlock(SSDataBlock* pBlock) { - int32_t numOfCfg = taosArrayGetSize(tsCfg->array); - int32_t numOfRows = 0; - blockDataEnsureCapacity(pBlock, numOfCfg); - - for (int32_t i = 0, c = 0; i < numOfCfg; ++i, c = 0) { - SConfigItem* pItem = taosArrayGet(tsCfg->array, i); - // GRANT_CFG_SKIP; - - char name[TSDB_CONFIG_OPTION_LEN + VARSTR_HEADER_SIZE] = {0}; - STR_WITH_MAXSIZE_TO_VARSTR(name, pItem->name, TSDB_CONFIG_OPTION_LEN + VARSTR_HEADER_SIZE); - SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, c++); - colDataSetVal(pColInfo, i, name, false); - - char value[TSDB_CONFIG_VALUE_LEN + VARSTR_HEADER_SIZE] = {0}; - int32_t valueLen = 0; - cfgDumpItemValue(pItem, &value[VARSTR_HEADER_SIZE], TSDB_CONFIG_VALUE_LEN, &valueLen); - varDataSetLen(value, valueLen); - pColInfo = taosArrayGet(pBlock->pDataBlock, c++); - colDataSetVal(pColInfo, i, value, false); - - char scope[TSDB_CONFIG_SCOPE_LEN + VARSTR_HEADER_SIZE] = {0}; - cfgDumpItemScope(pItem, &scope[VARSTR_HEADER_SIZE], TSDB_CONFIG_SCOPE_LEN, &valueLen); - varDataSetLen(scope, valueLen); - pColInfo = taosArrayGet(pBlock->pDataBlock, c++); - colDataSetVal(pColInfo, i, scope, false); - - numOfRows++; - } - - pBlock->info.rows = numOfRows; - - return TSDB_CODE_SUCCESS; -} - static int32_t execShowLocalVariables(SRetrieveTableRsp** pRsp) { SSDataBlock* pBlock = NULL; int32_t code = buildLocalVariablesResultDataBlock(&pBlock); if (TSDB_CODE_SUCCESS == code) { - code = setLocalVariablesResultIntoDataBlock(pBlock); + code = dumpConfToDataBlock(pBlock, 0); } if (TSDB_CODE_SUCCESS == code) { code = buildRetrieveTableRsp(pBlock, SHOW_LOCAL_VARIABLES_RESULT_COLS, pRsp); diff --git a/source/util/src/tconfig.c b/source/util/src/tconfig.c index aec1eba684..5ca2be37f2 100644 --- a/source/util/src/tconfig.c +++ b/source/util/src/tconfig.c @@ -27,12 +27,17 @@ #define CFG_NAME_PRINT_LEN 24 #define CFG_SRC_PRINT_LEN 12 +struct SConfig { + ECfgSrcType stype; + SArray *array; + TdThreadMutex lock; +}; + int32_t cfgLoadFromCfgFile(SConfig *pConfig, const char *filepath); -int32_t cfgLoadFromEnvFile(SConfig *pConfig, const char *filepath); +int32_t cfgLoadFromEnvFile(SConfig *pConfig, const char *envFile); int32_t cfgLoadFromEnvVar(SConfig *pConfig); int32_t cfgLoadFromEnvCmd(SConfig *pConfig, const char **envCmd); int32_t cfgLoadFromApollUrl(SConfig *pConfig, const char *url); -int32_t cfgSetItem(SConfig *pConfig, const char *name, const char *value, ECfgSrcType stype); extern char **environ; @@ -50,6 +55,7 @@ SConfig *cfgInit() { return NULL; } + taosThreadMutexInit(&pCfg->lock, NULL); return pCfg; } @@ -87,9 +93,9 @@ static void cfgFreeItem(SConfigItem *pItem) { pItem->dtype == CFG_DTYPE_CHARSET || pItem->dtype == CFG_DTYPE_TIMEZONE) { taosMemoryFreeClear(pItem->str); } + if (pItem->array) { - taosArrayDestroy(pItem->array); - pItem->array = NULL; + pItem->array = taosArrayDestroy(pItem->array); } } @@ -102,37 +108,18 @@ void cfgCleanup(SConfig *pCfg) { taosMemoryFreeClear(pItem->name); } taosArrayDestroy(pCfg->array); + taosThreadMutexDestroy(&pCfg->lock); taosMemoryFree(pCfg); } } int32_t cfgGetSize(SConfig *pCfg) { return taosArrayGetSize(pCfg->array); } -static int32_t cfgCheckAndSetTimezone(SConfigItem *pItem, const char *timezone) { +static int32_t cfgCheckAndSetConf(SConfigItem *pItem, const char *conf) { cfgFreeItem(pItem); - pItem->str = taosStrdup(timezone); - if (pItem->str == NULL) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - return -1; - } + ASSERT(pItem->str == NULL); - return 0; -} - -static int32_t cfgCheckAndSetCharset(SConfigItem *pItem, const char *charset) { - cfgFreeItem(pItem); - pItem->str = taosStrdup(charset); - if (pItem->str == NULL) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - return -1; - } - - return 0; -} - -static int32_t cfgCheckAndSetLocale(SConfigItem *pItem, const char *locale) { - cfgFreeItem(pItem); - pItem->str = taosStrdup(locale); + pItem->str = taosStrdup(conf); if (pItem->str == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; return -1; @@ -229,7 +216,7 @@ static int32_t cfgSetString(SConfigItem *pItem, const char *value, ECfgSrcType s return -1; } - taosMemoryFree(pItem->str); + taosMemoryFreeClear(pItem->str); pItem->str = tmp; pItem->stype = stype; return 0; @@ -246,20 +233,8 @@ static int32_t cfgSetDir(SConfigItem *pItem, const char *value, ECfgSrcType styp return 0; } -static int32_t cfgSetLocale(SConfigItem *pItem, const char *value, ECfgSrcType stype) { - if (cfgCheckAndSetLocale(pItem, value) != 0) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - uError("cfg:%s, type:%s src:%s value:%s failed to dup since %s", pItem->name, cfgDtypeStr(pItem->dtype), - cfgStypeStr(stype), value, terrstr()); - return -1; - } - - pItem->stype = stype; - return 0; -} - -static int32_t cfgSetCharset(SConfigItem *pItem, const char *value, ECfgSrcType stype) { - if (cfgCheckAndSetCharset(pItem, value) != 0) { +static int32_t doSetConf(SConfigItem *pItem, const char *value, ECfgSrcType stype) { + if (cfgCheckAndSetConf(pItem, value) != 0) { terrno = TSDB_CODE_OUT_OF_MEMORY; uError("cfg:%s, type:%s src:%s value:%s failed to dup since %s", pItem->name, cfgDtypeStr(pItem->dtype), cfgStypeStr(stype), value, terrstr()); @@ -271,18 +246,13 @@ static int32_t cfgSetCharset(SConfigItem *pItem, const char *value, ECfgSrcType } static int32_t cfgSetTimezone(SConfigItem *pItem, const char *value, ECfgSrcType stype) { - if (cfgCheckAndSetTimezone(pItem, value) != 0) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - uError("cfg:%s, type:%s src:%s value:%s failed to dup since %s", pItem->name, cfgDtypeStr(pItem->dtype), - cfgStypeStr(stype), value, terrstr()); - return -1; + int32_t code = doSetConf(pItem, value, stype); + if (code != TSDB_CODE_SUCCESS) { + return code; } - pItem->stype = stype; - // apply new timezone osSetTimezone(value); - - return 0; + return code; } static int32_t cfgSetTfsItem(SConfig *pCfg, const char *name, const char *value, const char *level, const char *primary, @@ -342,40 +312,62 @@ static int32_t cfgUpdateDebugFlagItem(SConfig *pCfg, const char *name, bool rese int32_t cfgSetItem(SConfig *pCfg, const char *name, const char *value, ECfgSrcType stype) { // GRANT_CFG_SET; + int32_t code = 0; SConfigItem *pItem = cfgGetItem(pCfg, name); if (pItem == NULL) { terrno = TSDB_CODE_CFG_NOT_FOUND; return -1; } + taosThreadMutexLock(&pCfg->lock); + switch (pItem->dtype) { - case CFG_DTYPE_BOOL: - return cfgSetBool(pItem, value, stype); - case CFG_DTYPE_INT32: - return cfgSetInt32(pItem, value, stype); - case CFG_DTYPE_INT64: - return cfgSetInt64(pItem, value, stype); + case CFG_DTYPE_BOOL: { + code = cfgSetBool(pItem, value, stype); + break; + } + case CFG_DTYPE_INT32: { + code = cfgSetInt32(pItem, value, stype); + break; + } + case CFG_DTYPE_INT64: { + code = cfgSetInt64(pItem, value, stype); + break; + } case CFG_DTYPE_FLOAT: - case CFG_DTYPE_DOUBLE: - return cfgSetFloat(pItem, value, stype); - case CFG_DTYPE_STRING: - return cfgSetString(pItem, value, stype); - case CFG_DTYPE_DIR: - return cfgSetDir(pItem, value, stype); - case CFG_DTYPE_TIMEZONE: - return cfgSetTimezone(pItem, value, stype); - case CFG_DTYPE_CHARSET: - return cfgSetCharset(pItem, value, stype); - case CFG_DTYPE_LOCALE: - return cfgSetLocale(pItem, value, stype); + case CFG_DTYPE_DOUBLE: { + code = cfgSetFloat(pItem, value, stype); + break; + } + case CFG_DTYPE_STRING: { + code = cfgSetString(pItem, value, stype); + break; + } + case CFG_DTYPE_DIR: { + code = cfgSetDir(pItem, value, stype); + break; + } + case CFG_DTYPE_TIMEZONE: { + code = cfgSetTimezone(pItem, value, stype); + break; + } + case CFG_DTYPE_CHARSET: { + code = doSetConf(pItem, value, stype); + break; + } + case CFG_DTYPE_LOCALE: { + code = doSetConf(pItem, value, stype); + break; + } case CFG_DTYPE_NONE: default: break; } -_err_out: + taosThreadMutexUnlock(&pCfg->lock); + terrno = TSDB_CODE_INVALID_CFG; - return -1; + return code; } SConfigItem *cfgGetItem(SConfig *pCfg, const char *name) { @@ -388,16 +380,16 @@ SConfigItem *cfgGetItem(SConfig *pCfg, const char *name) { } } - // uError("name:%s, cfg not found", name); terrno = TSDB_CODE_CFG_NOT_FOUND; return NULL; } int32_t cfgCheckRangeForDynUpdate(SConfig *pCfg, const char *name, const char *pVal, bool isServer) { ECfgDynType dynType = isServer ? CFG_DYN_SERVER : CFG_DYN_CLIENT; + SConfigItem *pItem = cfgGetItem(pCfg, name); if (!pItem || (pItem->dynScope & dynType) == 0) { - uError("failed to config:%s, not support", name); + uError("failed to config:%s, not support update this config", name); terrno = TSDB_CODE_INVALID_CFG; return -1; } @@ -459,7 +451,7 @@ static int32_t cfgAddItem(SConfig *pCfg, SConfigItem *pItem, const char *name) { return -1; } - int size = pCfg->array->size; + int32_t size = taosArrayGetSize(pCfg->array); for (int32_t i = 0; i < size; ++i) { SConfigItem *existItem = taosArrayGet(pCfg->array, i); if (existItem != NULL && strcmp(existItem->name, pItem->name) == 0) { @@ -559,7 +551,7 @@ int32_t cfgAddDir(SConfig *pCfg, const char *name, const char *defaultVal, int8_ int32_t cfgAddLocale(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope, int8_t dynScope) { SConfigItem item = {.dtype = CFG_DTYPE_LOCALE, .scope = scope, .dynScope = dynScope}; - if (cfgCheckAndSetLocale(&item, defaultVal) != 0) { + if (cfgCheckAndSetConf(&item, defaultVal) != 0) { return -1; } @@ -568,7 +560,7 @@ int32_t cfgAddLocale(SConfig *pCfg, const char *name, const char *defaultVal, in int32_t cfgAddCharset(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope, int8_t dynScope) { SConfigItem item = {.dtype = CFG_DTYPE_CHARSET, .scope = scope, .dynScope = dynScope}; - if (cfgCheckAndSetCharset(&item, defaultVal) != 0) { + if (cfgCheckAndSetConf(&item, defaultVal) != 0) { return -1; } @@ -577,7 +569,7 @@ int32_t cfgAddCharset(SConfig *pCfg, const char *name, const char *defaultVal, i int32_t cfgAddTimezone(SConfig *pCfg, const char *name, const char *defaultVal, int8_t scope, int8_t dynScope) { SConfigItem item = {.dtype = CFG_DTYPE_TIMEZONE, .scope = scope, .dynScope = dynScope}; - if (cfgCheckAndSetTimezone(&item, defaultVal) != 0) { + if (cfgCheckAndSetConf(&item, defaultVal) != 0) { return -1; } @@ -1356,3 +1348,35 @@ int32_t cfgGetApollUrl(const char **envCmd, const char *envFile, char *apolloUrl uInfo("fail get apollo url from cmd env file"); return -1; } + +struct SConfigIter { + int32_t index; + SConfig *pConf; +}; + +SConfigIter *cfgCreateIter(SConfig *pConf) { + SConfigIter* pIter = taosMemoryCalloc(1, sizeof(SConfigIter)); + if (pIter == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + return NULL; + } + + pIter->pConf = pConf; + return pIter; +} + +SConfigItem *cfgNextIter(SConfigIter* pIter) { + if (pIter->index < cfgGetSize(pIter->pConf)) { + return taosArrayGet(pIter->pConf->array, pIter->index++); + } + + return NULL; +} + +void cfgDestroyIter(SConfigIter *pIter) { + if (pIter == NULL) { + return; + } + + taosMemoryFree(pIter); +} \ No newline at end of file