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.
This commit is contained in:
parent
aaa694d7a9
commit
21427af360
|
@ -182,51 +182,45 @@ void taos_init_imp() {
|
||||||
|
|
||||||
void taos_init() { pthread_once(&tscinit, taos_init_imp); }
|
void taos_init() { pthread_once(&tscinit, taos_init_imp); }
|
||||||
|
|
||||||
int taos_options(TSDB_OPTION option, const void *arg, ...) {
|
static int taos_options_imp(TSDB_OPTION option, const char *pStr) {
|
||||||
char * pStr = NULL;
|
SGlobalConfig *cfg = 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");
|
|
||||||
|
|
||||||
switch (option) {
|
switch (option) {
|
||||||
case TSDB_OPTION_CONFIGDIR:
|
case TSDB_OPTION_CONFIGDIR:
|
||||||
pStr = (char *)arg;
|
cfg = tsGetConfigOption("configDir");
|
||||||
if (cfg_configDir && cfg_configDir->cfgStatus <= TSDB_CFG_CSTATUS_OPTION) {
|
if (cfg && cfg->cfgStatus <= TSDB_CFG_CSTATUS_OPTION) {
|
||||||
strncpy(configDir, pStr, TSDB_FILENAME_LEN);
|
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);
|
tscPrint("set config file directory:%s", pStr);
|
||||||
} else {
|
} else {
|
||||||
tscWarn("config option:%s, input value:%s, is configured by %s, use %s", cfg_configDir->option, pStr,
|
tscWarn("config option:%s, input value:%s, is configured by %s, use %s", cfg->option, pStr,
|
||||||
tsCfgStatusStr[cfg_configDir->cfgStatus], (char *)cfg_configDir->ptr);
|
tsCfgStatusStr[cfg->cfgStatus], (char *)cfg->ptr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TSDB_OPTION_SHELL_ACTIVITY_TIMER:
|
case TSDB_OPTION_SHELL_ACTIVITY_TIMER:
|
||||||
if (cfg_activetimer && cfg_activetimer->cfgStatus <= TSDB_CFG_CSTATUS_OPTION) {
|
cfg = tsGetConfigOption("shellActivityTimer");
|
||||||
tsShellActivityTimer = atoi((char *)arg);
|
if (cfg && cfg->cfgStatus <= TSDB_CFG_CSTATUS_OPTION) {
|
||||||
|
tsShellActivityTimer = atoi(pStr);
|
||||||
if (tsShellActivityTimer < 1) tsShellActivityTimer = 1;
|
if (tsShellActivityTimer < 1) tsShellActivityTimer = 1;
|
||||||
if (tsShellActivityTimer > 3600) tsShellActivityTimer = 3600;
|
if (tsShellActivityTimer > 3600) tsShellActivityTimer = 3600;
|
||||||
cfg_activetimer->cfgStatus = TSDB_CFG_CSTATUS_OPTION;
|
cfg->cfgStatus = TSDB_CFG_CSTATUS_OPTION;
|
||||||
tscPrint("set shellActivityTimer:%d", tsShellActivityTimer);
|
tscPrint("set shellActivityTimer:%d", tsShellActivityTimer);
|
||||||
} else {
|
} else {
|
||||||
tscWarn("config option:%s, input value:%s, is configured by %s, use %d", cfg_activetimer->option, pStr,
|
tscWarn("config option:%s, input value:%s, is configured by %s, use %d", cfg->option, pStr,
|
||||||
tsCfgStatusStr[cfg_activetimer->cfgStatus], (int32_t *)cfg_activetimer->ptr);
|
tsCfgStatusStr[cfg->cfgStatus], (int32_t *)cfg->ptr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TSDB_OPTION_LOCALE: { // set locale
|
case TSDB_OPTION_LOCALE: { // set locale
|
||||||
pStr = (char *)arg;
|
cfg = tsGetConfigOption("locale");
|
||||||
|
|
||||||
size_t len = strlen(pStr);
|
size_t len = strlen(pStr);
|
||||||
if (len == 0 || len > TSDB_LOCALE_LEN) {
|
if (len == 0 || len > TSDB_LOCALE_LEN) {
|
||||||
tscPrint("Invalid locale:%s, use default", pStr);
|
tscPrint("Invalid locale:%s, use default", pStr);
|
||||||
return -1;
|
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 = '.';
|
char sep = '.';
|
||||||
|
|
||||||
if (strlen(tsLocale) == 0) { // locale does not set yet
|
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) {
|
if (locale != NULL) {
|
||||||
tscPrint("locale set, prev locale:%s, new locale:%s", tsLocale, locale);
|
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
|
} else { // set the user-specified localed failed, use default LC_CTYPE as current locale
|
||||||
locale = setlocale(LC_CTYPE, tsLocale);
|
locale = setlocale(LC_CTYPE, tsLocale);
|
||||||
tscPrint("failed to set locale:%s, current locale:%s", pStr, 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));
|
strncpy(tsCharset, charset, tListLen(tsCharset));
|
||||||
cfg_charset->cfgStatus = TSDB_CFG_CSTATUS_OPTION;
|
cfg->cfgStatus = TSDB_CFG_CSTATUS_OPTION;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
tscPrint("charset:%s is not valid in locale, charset remains:%s", charset, tsCharset);
|
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);
|
tscPrint("charset remains:%s", tsCharset);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tscWarn("config option:%s, input value:%s, is configured by %s, use %s", cfg_locale->option, pStr,
|
tscWarn("config option:%s, input value:%s, is configured by %s, use %s", cfg->option, pStr,
|
||||||
tsCfgStatusStr[cfg_locale->cfgStatus], (char *)cfg_locale->ptr);
|
tsCfgStatusStr[cfg->cfgStatus], (char *)cfg->ptr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case TSDB_OPTION_CHARSET: {
|
case TSDB_OPTION_CHARSET: {
|
||||||
/* set charset will override the value of charset, assigned during system locale changed */
|
/* set charset will override the value of charset, assigned during system locale changed */
|
||||||
pStr = (char *)arg;
|
cfg = tsGetConfigOption("charset");
|
||||||
|
|
||||||
size_t len = strlen(pStr);
|
size_t len = strlen(pStr);
|
||||||
if (len == 0 || len > TSDB_LOCALE_LEN) {
|
if (len == 0 || len > TSDB_LOCALE_LEN) {
|
||||||
tscPrint("failed to set charset:%s", pStr);
|
tscPrint("failed to set charset:%s", pStr);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cfg_charset && cfg_charset->cfgStatus <= TSDB_CFG_CSTATUS_OPTION) {
|
if (cfg && cfg->cfgStatus <= TSDB_CFG_CSTATUS_OPTION) {
|
||||||
if (taosValidateEncodec(pStr)) {
|
if (taosValidateEncodec(pStr)) {
|
||||||
if (strlen(tsCharset) == 0) {
|
if (strlen(tsCharset) == 0) {
|
||||||
tscPrint("charset is set:%s", pStr);
|
tscPrint("charset is set:%s", pStr);
|
||||||
|
@ -297,40 +290,41 @@ int taos_options(TSDB_OPTION option, const void *arg, ...) {
|
||||||
}
|
}
|
||||||
|
|
||||||
strncpy(tsCharset, pStr, tListLen(tsCharset));
|
strncpy(tsCharset, pStr, tListLen(tsCharset));
|
||||||
cfg_charset->cfgStatus = TSDB_CFG_CSTATUS_OPTION;
|
cfg->cfgStatus = TSDB_CFG_CSTATUS_OPTION;
|
||||||
} else {
|
} else {
|
||||||
tscPrint("charset:%s not valid", pStr);
|
tscPrint("charset:%s not valid", pStr);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tscWarn("config option:%s, input value:%s, is configured by %s, use %s", cfg_charset->option, pStr,
|
tscWarn("config option:%s, input value:%s, is configured by %s, use %s", cfg->option, pStr,
|
||||||
tsCfgStatusStr[cfg_charset->cfgStatus], (char *)cfg_charset->ptr);
|
tsCfgStatusStr[cfg->cfgStatus], (char *)cfg->ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case TSDB_OPTION_TIMEZONE:
|
case TSDB_OPTION_TIMEZONE:
|
||||||
pStr = (char *)arg;
|
cfg = tsGetConfigOption("timezone");
|
||||||
if (cfg_timezone && cfg_timezone->cfgStatus <= TSDB_CFG_CSTATUS_OPTION) {
|
if (cfg && cfg->cfgStatus <= TSDB_CFG_CSTATUS_OPTION) {
|
||||||
strcpy(tsTimezone, pStr);
|
strcpy(tsTimezone, pStr);
|
||||||
tsSetTimeZone();
|
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);
|
tscTrace("timezone set:%s, input:%s by taos_options", tsTimezone, pStr);
|
||||||
} else {
|
} else {
|
||||||
tscWarn("config option:%s, input value:%s, is configured by %s, use %s", cfg_timezone->option, pStr,
|
tscWarn("config option:%s, input value:%s, is configured by %s, use %s", cfg->option, pStr,
|
||||||
tsCfgStatusStr[cfg_timezone->cfgStatus], (char *)cfg_timezone->ptr);
|
tsCfgStatusStr[cfg->cfgStatus], (char *)cfg->ptr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TSDB_OPTION_SOCKET_TYPE:
|
case TSDB_OPTION_SOCKET_TYPE:
|
||||||
if (cfg_socket && cfg_socket->cfgStatus <= TSDB_CFG_CSTATUS_OPTION) {
|
cfg = tsGetConfigOption("sockettype");
|
||||||
if (strcasecmp(arg, TAOS_SOCKET_TYPE_NAME_UDP) != 0 && strcasecmp(arg, TAOS_SOCKET_TYPE_NAME_TCP) != 0) {
|
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");
|
tscError("only 'tcp' or 'udp' allowed for configuring the socket type");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
strncpy(tsSocketType, arg, tListLen(tsSocketType));
|
strncpy(tsSocketType, pStr, tListLen(tsSocketType));
|
||||||
cfg_socket->cfgStatus = TSDB_CFG_CSTATUS_OPTION;
|
cfg->cfgStatus = TSDB_CFG_CSTATUS_OPTION;
|
||||||
tscPrint("socket type is set:%s", tsSocketType);
|
tscPrint("socket type is set:%s", tsSocketType);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -342,3 +336,20 @@ int taos_options(TSDB_OPTION option, const void *arg, ...) {
|
||||||
|
|
||||||
return 0;
|
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;
|
||||||
|
}
|
|
@ -247,7 +247,7 @@ typedef struct {
|
||||||
extern SGlobalConfig *tsGlobalConfig;
|
extern SGlobalConfig *tsGlobalConfig;
|
||||||
extern int tsGlobalConfigNum;
|
extern int tsGlobalConfigNum;
|
||||||
extern char * tsCfgStatusStr[];
|
extern char * tsCfgStatusStr[];
|
||||||
SGlobalConfig *tsGetConfigOption(char *option);
|
SGlobalConfig *tsGetConfigOption(const char *option);
|
||||||
|
|
||||||
#define TSDB_CFG_MAX_NUM 110
|
#define TSDB_CFG_MAX_NUM 110
|
||||||
#define TSDB_CFG_PRINT_LEN 23
|
#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();
|
tsInitGlobalConfig();
|
||||||
for (int i = 0; i < tsGlobalConfigNum; ++i) {
|
for (int i = 0; i < tsGlobalConfigNum; ++i) {
|
||||||
SGlobalConfig *cfg = tsGlobalConfig + i;
|
SGlobalConfig *cfg = tsGlobalConfig + i;
|
||||||
|
@ -374,7 +374,7 @@ SGlobalConfig *tsGetConfigOption(char *option) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tsReadConfigOption(char *option, char *value) {
|
void tsReadConfigOption(const char *option, char *value) {
|
||||||
for (int i = 0; i < tsGlobalConfigNum; ++i) {
|
for (int i = 0; i < tsGlobalConfigNum; ++i) {
|
||||||
SGlobalConfig *cfg = tsGlobalConfig + i;
|
SGlobalConfig *cfg = tsGlobalConfig + i;
|
||||||
if (!(cfg->cfgType & TSDB_CFG_CTYPE_B_CONFIG)) continue;
|
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;
|
cfg->cfgStatus = TSDB_CFG_CSTATUS_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tsInitGlobalConfig() {
|
static void doInitGlobalConfig() {
|
||||||
if (tsGlobalConfig != NULL) return;
|
|
||||||
|
|
||||||
tsGlobalConfig = (SGlobalConfig *) malloc(sizeof(SGlobalConfig) * TSDB_CFG_MAX_NUM);
|
tsGlobalConfig = (SGlobalConfig *) malloc(sizeof(SGlobalConfig) * TSDB_CFG_MAX_NUM);
|
||||||
memset(tsGlobalConfig, 0, 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);
|
tsGlobalConfigNum = (int)(cfg - tsGlobalConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static pthread_once_t initGlobalConfig = PTHREAD_ONCE_INIT;
|
||||||
|
void tsInitGlobalConfig() {
|
||||||
|
pthread_once(&initGlobalConfig, doInitGlobalConfig);
|
||||||
|
}
|
||||||
|
|
||||||
void tsReadGlobalLogConfig() {
|
void tsReadGlobalLogConfig() {
|
||||||
tsInitGlobalConfig();
|
tsInitGlobalConfig();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue