fix(util): fix race condition.
This commit is contained in:
parent
2d1e9ba631
commit
faa87e13b0
|
@ -106,12 +106,15 @@ int32_t cfgLoad(SConfig *pCfg, ECfgSrcType cfgType, const void *sourceStr);
|
||||||
int32_t cfgLoadFromArray(SConfig *pCfg, SArray *pArgs); // SConfigPair
|
int32_t cfgLoadFromArray(SConfig *pCfg, SArray *pArgs); // SConfigPair
|
||||||
void cfgCleanup(SConfig *pCfg);
|
void cfgCleanup(SConfig *pCfg);
|
||||||
int32_t cfgGetSize(SConfig *pCfg);
|
int32_t cfgGetSize(SConfig *pCfg);
|
||||||
SConfigItem *cfgGetItem(SConfig *pCfg, const char *name);
|
SConfigItem *cfgGetItem(SConfig *pCfg, const char *pName);
|
||||||
int32_t cfgSetItem(SConfig *pCfg, const char *name, const char *value, ECfgSrcType stype);
|
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);
|
int32_t cfgCheckRangeForDynUpdate(SConfig *pCfg, const char *name, const char *pVal, bool isServer);
|
||||||
|
|
||||||
SConfigIter *cfgCreateIter(SConfig *pConf);
|
SConfigIter *cfgCreateIter(SConfig *pConf);
|
||||||
SConfigItem *cfgNextIter(SConfigIter *pIter);
|
SConfigItem *cfgNextIter(SConfigIter *pIter);
|
||||||
void cfgDestroyIter(SConfigIter *pIter);
|
void cfgDestroyIter(SConfigIter *pIter);
|
||||||
|
void cfgLock(SConfig *pCfg);
|
||||||
|
void cfgUnLock(SConfig *pCfg);
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
int32_t cfgAddBool(SConfig *pCfg, const char *name, bool defaultVal, int8_t scope, int8_t dynScope);
|
int32_t cfgAddBool(SConfig *pCfg, const char *name, bool defaultVal, int8_t scope, int8_t dynScope);
|
||||||
|
|
|
@ -1515,15 +1515,20 @@ static int32_t taosCfgDynamicOptionsForServer(SConfig *pCfg, const char *name) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cfgLock(pCfg);
|
||||||
|
|
||||||
SConfigItem *pItem = cfgGetItem(pCfg, name);
|
SConfigItem *pItem = cfgGetItem(pCfg, name);
|
||||||
if (!pItem || (pItem->dynScope & CFG_DYN_SERVER) == 0) {
|
if (!pItem || (pItem->dynScope & CFG_DYN_SERVER) == 0) {
|
||||||
uError("failed to config:%s, not support", name);
|
uError("failed to config:%s, not support", name);
|
||||||
terrno = TSDB_CODE_INVALID_CFG;
|
terrno = TSDB_CODE_INVALID_CFG;
|
||||||
|
|
||||||
|
cfgUnLock(pCfg);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strncasecmp(name, "debugFlag", 9) == 0) {
|
if (strncasecmp(name, "debugFlag", 9) == 0) {
|
||||||
taosSetAllDebugFlag(pCfg, pItem->i32);
|
taosSetAllDebugFlag(pCfg, pItem->i32);
|
||||||
|
cfgUnLock(pCfg);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1580,17 +1585,21 @@ static int32_t taosCfgDynamicOptionsForServer(SConfig *pCfg, const char *name) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cfgUnLock(pCfg);
|
||||||
return terrno == TSDB_CODE_SUCCESS ? 0 : -1;
|
return terrno == TSDB_CODE_SUCCESS ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo fix race condition caused by update of config, pItem->str may be removed
|
|
||||||
static int32_t taosCfgDynamicOptionsForClient(SConfig *pCfg, const char *name) {
|
static int32_t taosCfgDynamicOptionsForClient(SConfig *pCfg, const char *name) {
|
||||||
terrno = TSDB_CODE_SUCCESS;
|
terrno = TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
|
cfgLock(pCfg);
|
||||||
|
|
||||||
SConfigItem *pItem = cfgGetItem(pCfg, name);
|
SConfigItem *pItem = cfgGetItem(pCfg, name);
|
||||||
if ((pItem == NULL) || (pItem->dynScope & CFG_DYN_CLIENT) == 0) {
|
if ((pItem == NULL) || (pItem->dynScope & CFG_DYN_CLIENT) == 0) {
|
||||||
uError("failed to config:%s, not support", name);
|
uError("failed to config:%s, not support", name);
|
||||||
terrno = TSDB_CODE_INVALID_CFG;
|
terrno = TSDB_CODE_INVALID_CFG;
|
||||||
|
|
||||||
|
cfgUnLock(pCfg);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1728,6 +1737,7 @@ static int32_t taosCfgDynamicOptionsForClient(SConfig *pCfg, const char *name) {
|
||||||
matched = true;
|
matched = true;
|
||||||
} else if (strcasecmp("slowLogScope", name) == 0) {
|
} else if (strcasecmp("slowLogScope", name) == 0) {
|
||||||
if (taosSetSlowLogScope(pItem->str)) {
|
if (taosSetSlowLogScope(pItem->str)) {
|
||||||
|
cfgUnLock(pCfg);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
uInfo("%s set to %s", name, pItem->str);
|
uInfo("%s set to %s", name, pItem->str);
|
||||||
|
@ -1747,6 +1757,7 @@ static int32_t taosCfgDynamicOptionsForClient(SConfig *pCfg, const char *name) {
|
||||||
taosExpandDir(tsTempDir, tsTempDir, PATH_MAX);
|
taosExpandDir(tsTempDir, tsTempDir, PATH_MAX);
|
||||||
if (taosMulMkDir(tsTempDir) != 0) {
|
if (taosMulMkDir(tsTempDir) != 0) {
|
||||||
uError("failed to create tempDir:%s since %s", tsTempDir, terrstr());
|
uError("failed to create tempDir:%s since %s", tsTempDir, terrstr());
|
||||||
|
cfgUnLock(pCfg);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
matched = true;
|
matched = true;
|
||||||
|
@ -1802,6 +1813,7 @@ static int32_t taosCfgDynamicOptionsForClient(SConfig *pCfg, const char *name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
_out:
|
_out:
|
||||||
|
cfgUnLock(pCfg);
|
||||||
return terrno == TSDB_CODE_SUCCESS ? 0 : -1;
|
return terrno == TSDB_CODE_SUCCESS ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1844,6 +1856,8 @@ static void taosSetAllDebugFlag(SConfig *pCfg, int32_t flag) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cfgLock(pCfg);
|
||||||
|
|
||||||
SArray *noNeedToSetVars = NULL;
|
SArray *noNeedToSetVars = NULL;
|
||||||
SConfigItem *pItem = cfgGetItem(pCfg, "debugFlag");
|
SConfigItem *pItem = cfgGetItem(pCfg, "debugFlag");
|
||||||
if (pItem != NULL) {
|
if (pItem != NULL) {
|
||||||
|
@ -1878,7 +1892,11 @@ static void taosSetAllDebugFlag(SConfig *pCfg, int32_t flag) {
|
||||||
taosArrayClear(noNeedToSetVars); // reset array
|
taosArrayClear(noNeedToSetVars); // reset array
|
||||||
|
|
||||||
uInfo("all debug flag are set to %d", flag);
|
uInfo("all debug flag are set to %d", flag);
|
||||||
if (terrno == TSDB_CODE_CFG_NOT_FOUND) terrno = TSDB_CODE_SUCCESS; // ignore not exist
|
if (terrno == TSDB_CODE_CFG_NOT_FOUND) {
|
||||||
|
terrno = TSDB_CODE_SUCCESS; // ignore not exist
|
||||||
|
}
|
||||||
|
|
||||||
|
cfgUnLock(pCfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t taosGranted(int8_t type) {
|
int8_t taosGranted(int8_t type) {
|
||||||
|
|
|
@ -88,7 +88,7 @@ int32_t cfgLoadFromArray(SConfig *pCfg, SArray *pArgs) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cfgFreeItem(SConfigItem *pItem) {
|
void cfgItemFreeVal(SConfigItem *pItem) {
|
||||||
if (pItem->dtype == CFG_DTYPE_STRING || pItem->dtype == CFG_DTYPE_DIR || pItem->dtype == CFG_DTYPE_LOCALE ||
|
if (pItem->dtype == CFG_DTYPE_STRING || pItem->dtype == CFG_DTYPE_DIR || pItem->dtype == CFG_DTYPE_LOCALE ||
|
||||||
pItem->dtype == CFG_DTYPE_CHARSET || pItem->dtype == CFG_DTYPE_TIMEZONE) {
|
pItem->dtype == CFG_DTYPE_CHARSET || pItem->dtype == CFG_DTYPE_TIMEZONE) {
|
||||||
taosMemoryFreeClear(pItem->str);
|
taosMemoryFreeClear(pItem->str);
|
||||||
|
@ -100,23 +100,26 @@ static void cfgFreeItem(SConfigItem *pItem) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void cfgCleanup(SConfig *pCfg) {
|
void cfgCleanup(SConfig *pCfg) {
|
||||||
if (pCfg != NULL) {
|
if (pCfg == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t size = taosArrayGetSize(pCfg->array);
|
int32_t size = taosArrayGetSize(pCfg->array);
|
||||||
for (int32_t i = 0; i < size; ++i) {
|
for (int32_t i = 0; i < size; ++i) {
|
||||||
SConfigItem *pItem = taosArrayGet(pCfg->array, i);
|
SConfigItem *pItem = taosArrayGet(pCfg->array, i);
|
||||||
cfgFreeItem(pItem);
|
cfgItemFreeVal(pItem);
|
||||||
taosMemoryFreeClear(pItem->name);
|
taosMemoryFreeClear(pItem->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
taosArrayDestroy(pCfg->array);
|
taosArrayDestroy(pCfg->array);
|
||||||
taosThreadMutexDestroy(&pCfg->lock);
|
taosThreadMutexDestroy(&pCfg->lock);
|
||||||
taosMemoryFree(pCfg);
|
taosMemoryFree(pCfg);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
int32_t cfgGetSize(SConfig *pCfg) { return taosArrayGetSize(pCfg->array); }
|
int32_t cfgGetSize(SConfig *pCfg) { return taosArrayGetSize(pCfg->array); }
|
||||||
|
|
||||||
static int32_t cfgCheckAndSetConf(SConfigItem *pItem, const char *conf) {
|
static int32_t cfgCheckAndSetConf(SConfigItem *pItem, const char *conf) {
|
||||||
cfgFreeItem(pItem);
|
cfgItemFreeVal(pItem);
|
||||||
ASSERT(pItem->str == NULL);
|
ASSERT(pItem->str == NULL);
|
||||||
|
|
||||||
pItem->str = taosStrdup(conf);
|
pItem->str = taosStrdup(conf);
|
||||||
|
@ -257,13 +260,21 @@ static int32_t cfgSetTimezone(SConfigItem *pItem, const char *value, ECfgSrcType
|
||||||
|
|
||||||
static int32_t cfgSetTfsItem(SConfig *pCfg, const char *name, const char *value, const char *level, const char *primary,
|
static int32_t cfgSetTfsItem(SConfig *pCfg, const char *name, const char *value, const char *level, const char *primary,
|
||||||
ECfgSrcType stype) {
|
ECfgSrcType stype) {
|
||||||
|
taosThreadMutexLock(&pCfg->lock);
|
||||||
|
|
||||||
SConfigItem *pItem = cfgGetItem(pCfg, name);
|
SConfigItem *pItem = cfgGetItem(pCfg, name);
|
||||||
if (pItem == NULL) return -1;
|
if (pItem == NULL) {
|
||||||
|
taosThreadMutexUnlock(&pCfg->lock);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (pItem->array == NULL) {
|
if (pItem->array == NULL) {
|
||||||
pItem->array = taosArrayInit(16, sizeof(SDiskCfg));
|
pItem->array = taosArrayInit(16, sizeof(SDiskCfg));
|
||||||
if (pItem->array == NULL) {
|
if (pItem->array == NULL) {
|
||||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
taosThreadMutexUnlock(&pCfg->lock);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -275,10 +286,14 @@ static int32_t cfgSetTfsItem(SConfig *pCfg, const char *name, const char *value,
|
||||||
void *ret = taosArrayPush(pItem->array, &cfg);
|
void *ret = taosArrayPush(pItem->array, &cfg);
|
||||||
if (ret == NULL) {
|
if (ret == NULL) {
|
||||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||||
|
taosThreadMutexUnlock(&pCfg->lock);
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pItem->stype = stype;
|
pItem->stype = stype;
|
||||||
|
taosThreadMutexUnlock(&pCfg->lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,14 +328,15 @@ static int32_t cfgUpdateDebugFlagItem(SConfig *pCfg, const char *name, bool rese
|
||||||
int32_t cfgSetItem(SConfig *pCfg, const char *name, const char *value, ECfgSrcType stype) {
|
int32_t cfgSetItem(SConfig *pCfg, const char *name, const char *value, ECfgSrcType stype) {
|
||||||
// GRANT_CFG_SET;
|
// GRANT_CFG_SET;
|
||||||
int32_t code = 0;
|
int32_t code = 0;
|
||||||
|
taosThreadMutexLock(&pCfg->lock);
|
||||||
|
|
||||||
SConfigItem *pItem = cfgGetItem(pCfg, name);
|
SConfigItem *pItem = cfgGetItem(pCfg, name);
|
||||||
if (pItem == NULL) {
|
if (pItem == NULL) {
|
||||||
terrno = TSDB_CODE_CFG_NOT_FOUND;
|
terrno = TSDB_CODE_CFG_NOT_FOUND;
|
||||||
|
taosThreadMutexUnlock(&pCfg->lock);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
taosThreadMutexLock(&pCfg->lock);
|
|
||||||
|
|
||||||
switch (pItem->dtype) {
|
switch (pItem->dtype) {
|
||||||
case CFG_DTYPE_BOOL: {
|
case CFG_DTYPE_BOOL: {
|
||||||
code = cfgSetBool(pItem, value, stype);
|
code = cfgSetBool(pItem, value, stype);
|
||||||
|
@ -369,12 +385,12 @@ int32_t cfgSetItem(SConfig *pCfg, const char *name, const char *value, ECfgSrcTy
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
SConfigItem *cfgGetItem(SConfig *pCfg, const char *name) {
|
SConfigItem *cfgGetItem(SConfig *pCfg, const char *pName) {
|
||||||
if (pCfg == NULL) return NULL;
|
if (pCfg == NULL) return NULL;
|
||||||
int32_t size = taosArrayGetSize(pCfg->array);
|
int32_t size = taosArrayGetSize(pCfg->array);
|
||||||
for (int32_t i = 0; i < size; ++i) {
|
for (int32_t i = 0; i < size; ++i) {
|
||||||
SConfigItem *pItem = taosArrayGet(pCfg->array, i);
|
SConfigItem *pItem = taosArrayGet(pCfg->array, i);
|
||||||
if (strcasecmp(pItem->name, name) == 0) {
|
if (strcasecmp(pItem->name, pName) == 0) {
|
||||||
return pItem;
|
return pItem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -383,9 +399,23 @@ SConfigItem *cfgGetItem(SConfig *pCfg, const char *name) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cfgLock(SConfig *pCfg) {
|
||||||
|
if (pCfg == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
taosThreadMutexLock(&pCfg->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cfgUnLock(SConfig *pCfg) {
|
||||||
|
taosThreadMutexUnlock(&pCfg->lock);
|
||||||
|
}
|
||||||
|
|
||||||
int32_t cfgCheckRangeForDynUpdate(SConfig *pCfg, const char *name, const char *pVal, bool isServer) {
|
int32_t cfgCheckRangeForDynUpdate(SConfig *pCfg, const char *name, const char *pVal, bool isServer) {
|
||||||
ECfgDynType dynType = isServer ? CFG_DYN_SERVER : CFG_DYN_CLIENT;
|
ECfgDynType dynType = isServer ? CFG_DYN_SERVER : CFG_DYN_CLIENT;
|
||||||
|
|
||||||
|
cfgLock(pCfg);
|
||||||
|
|
||||||
SConfigItem *pItem = cfgGetItem(pCfg, name);
|
SConfigItem *pItem = cfgGetItem(pCfg, name);
|
||||||
if (!pItem || (pItem->dynScope & dynType) == 0) {
|
if (!pItem || (pItem->dynScope & dynType) == 0) {
|
||||||
uError("failed to config:%s, not support update this config", name);
|
uError("failed to config:%s, not support update this config", name);
|
||||||
|
@ -439,6 +469,7 @@ int32_t cfgCheckRangeForDynUpdate(SConfig *pCfg, const char *name, const char *p
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1057,8 +1088,7 @@ int32_t cfgLoadFromCfgFile(SConfig *pConfig, const char *filepath) {
|
||||||
|
|
||||||
code = cfgSetItem(pConfig, name, newValue, CFG_STYPE_CFG_FILE);
|
code = cfgSetItem(pConfig, name, newValue, CFG_STYPE_CFG_FILE);
|
||||||
if (code != 0 && terrno != TSDB_CODE_CFG_NOT_FOUND) break;
|
if (code != 0 && terrno != TSDB_CODE_CFG_NOT_FOUND) break;
|
||||||
}
|
} else {
|
||||||
else{
|
|
||||||
paGetToken(value + vlen + 1, &value2, &vlen2);
|
paGetToken(value + vlen + 1, &value2, &vlen2);
|
||||||
if (vlen2 != 0) {
|
if (vlen2 != 0) {
|
||||||
value2[vlen2] = 0;
|
value2[vlen2] = 0;
|
||||||
|
|
Loading…
Reference in New Issue