提交 21427af3 编写于 作者: weixin_48148422's avatar weixin_48148422

TBASE-306

enhance `taos_options` to support cocurrent calls.
note it still a problem if one thread is modifying a global configuration
while another thread is reading it.
上级 aaa694d7
......@@ -182,51 +182,45 @@ void taos_init_imp() {
void taos_init() { pthread_once(&tscinit, taos_init_imp); }
int taos_options(TSDB_OPTION option, const void *arg, ...) {
char * pStr = NULL;
SGlobalConfig *cfg_configDir = tsGetConfigOption("configDir");
SGlobalConfig *cfg_activetimer = tsGetConfigOption("shellActivityTimer");
SGlobalConfig *cfg_locale = tsGetConfigOption("locale");
SGlobalConfig *cfg_charset = tsGetConfigOption("charset");
SGlobalConfig *cfg_timezone = tsGetConfigOption("timezone");
SGlobalConfig *cfg_socket = tsGetConfigOption("sockettype");
static int taos_options_imp(TSDB_OPTION option, const char *pStr) {
SGlobalConfig *cfg = NULL;
switch (option) {
case TSDB_OPTION_CONFIGDIR:
pStr = (char *)arg;
if (cfg_configDir && cfg_configDir->cfgStatus <= TSDB_CFG_CSTATUS_OPTION) {
cfg = tsGetConfigOption("configDir");
if (cfg && cfg->cfgStatus <= TSDB_CFG_CSTATUS_OPTION) {
strncpy(configDir, pStr, TSDB_FILENAME_LEN);
cfg_configDir->cfgStatus = TSDB_CFG_CSTATUS_OPTION;
cfg->cfgStatus = TSDB_CFG_CSTATUS_OPTION;
tscPrint("set config file directory:%s", pStr);
} else {
tscWarn("config option:%s, input value:%s, is configured by %s, use %s", cfg_configDir->option, pStr,
tsCfgStatusStr[cfg_configDir->cfgStatus], (char *)cfg_configDir->ptr);
tscWarn("config option:%s, input value:%s, is configured by %s, use %s", cfg->option, pStr,
tsCfgStatusStr[cfg->cfgStatus], (char *)cfg->ptr);
}
break;
case TSDB_OPTION_SHELL_ACTIVITY_TIMER:
if (cfg_activetimer && cfg_activetimer->cfgStatus <= TSDB_CFG_CSTATUS_OPTION) {
tsShellActivityTimer = atoi((char *)arg);
cfg = tsGetConfigOption("shellActivityTimer");
if (cfg && cfg->cfgStatus <= TSDB_CFG_CSTATUS_OPTION) {
tsShellActivityTimer = atoi(pStr);
if (tsShellActivityTimer < 1) tsShellActivityTimer = 1;
if (tsShellActivityTimer > 3600) tsShellActivityTimer = 3600;
cfg_activetimer->cfgStatus = TSDB_CFG_CSTATUS_OPTION;
cfg->cfgStatus = TSDB_CFG_CSTATUS_OPTION;
tscPrint("set shellActivityTimer:%d", tsShellActivityTimer);
} else {
tscWarn("config option:%s, input value:%s, is configured by %s, use %d", cfg_activetimer->option, pStr,
tsCfgStatusStr[cfg_activetimer->cfgStatus], (int32_t *)cfg_activetimer->ptr);
tscWarn("config option:%s, input value:%s, is configured by %s, use %d", cfg->option, pStr,
tsCfgStatusStr[cfg->cfgStatus], (int32_t *)cfg->ptr);
}
break;
case TSDB_OPTION_LOCALE: { // set locale
pStr = (char *)arg;
cfg = tsGetConfigOption("locale");
size_t len = strlen(pStr);
if (len == 0 || len > TSDB_LOCALE_LEN) {
tscPrint("Invalid locale:%s, use default", pStr);
return -1;
}
if (cfg_locale && cfg_charset && cfg_locale->cfgStatus <= TSDB_CFG_CSTATUS_OPTION) {
if (cfg && cfg && cfg->cfgStatus <= TSDB_CFG_CSTATUS_OPTION) {
char sep = '.';
if (strlen(tsLocale) == 0) { // locale does not set yet
......@@ -239,7 +233,7 @@ int taos_options(TSDB_OPTION option, const void *arg, ...) {
if (locale != NULL) {
tscPrint("locale set, prev locale:%s, new locale:%s", tsLocale, locale);
cfg_locale->cfgStatus = TSDB_CFG_CSTATUS_OPTION;
cfg->cfgStatus = TSDB_CFG_CSTATUS_OPTION;
} else { // set the user-specified localed failed, use default LC_CTYPE as current locale
locale = setlocale(LC_CTYPE, tsLocale);
tscPrint("failed to set locale:%s, current locale:%s", pStr, tsLocale);
......@@ -261,7 +255,7 @@ int taos_options(TSDB_OPTION option, const void *arg, ...) {
}
strncpy(tsCharset, charset, tListLen(tsCharset));
cfg_charset->cfgStatus = TSDB_CFG_CSTATUS_OPTION;
cfg->cfgStatus = TSDB_CFG_CSTATUS_OPTION;
} else {
tscPrint("charset:%s is not valid in locale, charset remains:%s", charset, tsCharset);
......@@ -272,23 +266,22 @@ int taos_options(TSDB_OPTION option, const void *arg, ...) {
tscPrint("charset remains:%s", tsCharset);
}
} else {
tscWarn("config option:%s, input value:%s, is configured by %s, use %s", cfg_locale->option, pStr,
tsCfgStatusStr[cfg_locale->cfgStatus], (char *)cfg_locale->ptr);
tscWarn("config option:%s, input value:%s, is configured by %s, use %s", cfg->option, pStr,
tsCfgStatusStr[cfg->cfgStatus], (char *)cfg->ptr);
}
break;
}
case TSDB_OPTION_CHARSET: {
/* set charset will override the value of charset, assigned during system locale changed */
pStr = (char *)arg;
cfg = tsGetConfigOption("charset");
size_t len = strlen(pStr);
if (len == 0 || len > TSDB_LOCALE_LEN) {
tscPrint("failed to set charset:%s", pStr);
return -1;
}
if (cfg_charset && cfg_charset->cfgStatus <= TSDB_CFG_CSTATUS_OPTION) {
if (cfg && cfg->cfgStatus <= TSDB_CFG_CSTATUS_OPTION) {
if (taosValidateEncodec(pStr)) {
if (strlen(tsCharset) == 0) {
tscPrint("charset is set:%s", pStr);
......@@ -297,40 +290,41 @@ int taos_options(TSDB_OPTION option, const void *arg, ...) {
}
strncpy(tsCharset, pStr, tListLen(tsCharset));
cfg_charset->cfgStatus = TSDB_CFG_CSTATUS_OPTION;
cfg->cfgStatus = TSDB_CFG_CSTATUS_OPTION;
} else {
tscPrint("charset:%s not valid", pStr);
}
} else {
tscWarn("config option:%s, input value:%s, is configured by %s, use %s", cfg_charset->option, pStr,
tsCfgStatusStr[cfg_charset->cfgStatus], (char *)cfg_charset->ptr);
tscWarn("config option:%s, input value:%s, is configured by %s, use %s", cfg->option, pStr,
tsCfgStatusStr[cfg->cfgStatus], (char *)cfg->ptr);
}
break;
}
case TSDB_OPTION_TIMEZONE:
pStr = (char *)arg;
if (cfg_timezone && cfg_timezone->cfgStatus <= TSDB_CFG_CSTATUS_OPTION) {
cfg = tsGetConfigOption("timezone");
if (cfg && cfg->cfgStatus <= TSDB_CFG_CSTATUS_OPTION) {
strcpy(tsTimezone, pStr);
tsSetTimeZone();
cfg_timezone->cfgStatus = TSDB_CFG_CSTATUS_OPTION;
cfg->cfgStatus = TSDB_CFG_CSTATUS_OPTION;
tscTrace("timezone set:%s, input:%s by taos_options", tsTimezone, pStr);
} else {
tscWarn("config option:%s, input value:%s, is configured by %s, use %s", cfg_timezone->option, pStr,
tsCfgStatusStr[cfg_timezone->cfgStatus], (char *)cfg_timezone->ptr);
tscWarn("config option:%s, input value:%s, is configured by %s, use %s", cfg->option, pStr,
tsCfgStatusStr[cfg->cfgStatus], (char *)cfg->ptr);
}
break;
case TSDB_OPTION_SOCKET_TYPE:
if (cfg_socket && cfg_socket->cfgStatus <= TSDB_CFG_CSTATUS_OPTION) {
if (strcasecmp(arg, TAOS_SOCKET_TYPE_NAME_UDP) != 0 && strcasecmp(arg, TAOS_SOCKET_TYPE_NAME_TCP) != 0) {
cfg = tsGetConfigOption("sockettype");
if (cfg && cfg->cfgStatus <= TSDB_CFG_CSTATUS_OPTION) {
if (strcasecmp(pStr, TAOS_SOCKET_TYPE_NAME_UDP) != 0 && strcasecmp(pStr, TAOS_SOCKET_TYPE_NAME_TCP) != 0) {
tscError("only 'tcp' or 'udp' allowed for configuring the socket type");
return -1;
}
strncpy(tsSocketType, arg, tListLen(tsSocketType));
cfg_socket->cfgStatus = TSDB_CFG_CSTATUS_OPTION;
strncpy(tsSocketType, pStr, tListLen(tsSocketType));
cfg->cfgStatus = TSDB_CFG_CSTATUS_OPTION;
tscPrint("socket type is set:%s", tsSocketType);
}
break;
......@@ -342,3 +336,20 @@ int taos_options(TSDB_OPTION option, const void *arg, ...) {
return 0;
}
int taos_options(TSDB_OPTION option, const void *arg, ...) {
static int32_t lock = 0;
for (int i = 1; atomic_val_compare_exchange_32(&lock, 0, 1) != 0; ++i) {
if (i % 1000 == 0) {
tscPrint("haven't acquire lock after spin %d times.", i);
sched_yield();
}
}
int ret = taos_options_imp(option, (const char*)arg);
atomic_store_32(&lock, 0);
return ret;
}
\ No newline at end of file
......@@ -247,7 +247,7 @@ typedef struct {
extern SGlobalConfig *tsGlobalConfig;
extern int tsGlobalConfigNum;
extern char * tsCfgStatusStr[];
SGlobalConfig *tsGetConfigOption(char *option);
SGlobalConfig *tsGetConfigOption(const char *option);
#define TSDB_CFG_MAX_NUM 110
#define TSDB_CFG_PRINT_LEN 23
......
......@@ -364,7 +364,7 @@ void tsReadLogOption(char *option, char *value) {
}
}
SGlobalConfig *tsGetConfigOption(char *option) {
SGlobalConfig *tsGetConfigOption(const char *option) {
tsInitGlobalConfig();
for (int i = 0; i < tsGlobalConfigNum; ++i) {
SGlobalConfig *cfg = tsGlobalConfig + i;
......@@ -374,7 +374,7 @@ SGlobalConfig *tsGetConfigOption(char *option) {
return NULL;
}
void tsReadConfigOption(char *option, char *value) {
void tsReadConfigOption(const char *option, char *value) {
for (int i = 0; i < tsGlobalConfigNum; ++i) {
SGlobalConfig *cfg = tsGlobalConfig + i;
if (!(cfg->cfgType & TSDB_CFG_CTYPE_B_CONFIG)) continue;
......@@ -423,9 +423,7 @@ void tsInitConfigOption(SGlobalConfig *cfg, char *name, void *ptr, int8_t valTyp
cfg->cfgStatus = TSDB_CFG_CSTATUS_NONE;
}
void tsInitGlobalConfig() {
if (tsGlobalConfig != NULL) return;
static void doInitGlobalConfig() {
tsGlobalConfig = (SGlobalConfig *) malloc(sizeof(SGlobalConfig) * TSDB_CFG_MAX_NUM);
memset(tsGlobalConfig, 0, sizeof(SGlobalConfig) * TSDB_CFG_MAX_NUM);
......@@ -783,6 +781,11 @@ void tsInitGlobalConfig() {
tsGlobalConfigNum = (int)(cfg - tsGlobalConfig);
}
static pthread_once_t initGlobalConfig = PTHREAD_ONCE_INIT;
void tsInitGlobalConfig() {
pthread_once(&initGlobalConfig, doInitGlobalConfig);
}
void tsReadGlobalLogConfig() {
tsInitGlobalConfig();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册