From c93d35b54213049c86be76b8d0e74948fecfbf4b Mon Sep 17 00:00:00 2001 From: Danny Couture Date: Thu, 22 Jun 2017 12:36:07 -0400 Subject: [PATCH] Fix SQLITE_OMIT_WSD feature regression This can cause multiple threads to initialize the builtin functions at the same time when using SQLITE_OMIT_WSD feature along with SQLITE_THREADSAFE = 0 (no mutex) so that each sqlite connection acts like it is in a separate process for read scalability reasons. For this case to work, there must be no shared globals between threads. --- src/alter.c | 4 ++-- src/callback.c | 8 +++++--- src/date.c | 4 ++-- src/func.c | 6 +++--- src/global.c | 2 +- src/main.c | 2 +- src/sqliteInt.h | 2 +- src/vdbemem.c | 4 ++-- 8 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/alter.c b/src/alter.c index 067cbb896d..675e76e6d6 100644 --- a/src/alter.c +++ b/src/alter.c @@ -229,7 +229,7 @@ static void renameTriggerFunc( ** Register built-in functions used to help implement ALTER TABLE */ void sqlite3AlterFunctions(void){ - static FuncDef aAlterTableFuncs[] = { + static SQLITE_WSD FuncDef aAlterTableFuncs[] = { FUNCTION(sqlite_rename_table, 2, 0, 0, renameTableFunc), #ifndef SQLITE_OMIT_TRIGGER FUNCTION(sqlite_rename_trigger, 2, 0, 0, renameTriggerFunc), @@ -238,7 +238,7 @@ void sqlite3AlterFunctions(void){ FUNCTION(sqlite_rename_parent, 3, 0, 0, renameParentFunc), #endif }; - sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs)); + sqlite3InsertBuiltinFuncs(&GLOBAL(FuncDef, aAlterTableFuncs), ArraySize(aAlterTableFuncs)); } /* diff --git a/src/callback.c b/src/callback.c index 2351178867..65cd85d9a1 100644 --- a/src/callback.c +++ b/src/callback.c @@ -288,7 +288,7 @@ static FuncDef *functionSearch( const char *zFunc /* Name of function */ ){ FuncDef *p; - for(p=sqlite3BuiltinFunctions.a[h]; p; p=p->u.pHash){ + for(p=GLOBAL(FuncDefHash, sqlite3BuiltinFunctions).a[h]; p; p=p->u.pHash){ if( sqlite3StrICmp(p->zName, zFunc)==0 ){ return p; } @@ -303,6 +303,8 @@ void sqlite3InsertBuiltinFuncs( FuncDef *aDef, /* List of global functions to be inserted */ int nDef /* Length of the apDef[] list */ ){ + FuncDefHash *builtinFunctions = &GLOBAL(FuncDefHash, sqlite3BuiltinFunctions); + int i; for(i=0; ipNext = &aDef[i]; }else{ aDef[i].pNext = 0; - aDef[i].u.pHash = sqlite3BuiltinFunctions.a[h]; - sqlite3BuiltinFunctions.a[h] = &aDef[i]; + aDef[i].u.pHash = builtinFunctions->a[h]; + builtinFunctions->a[h] = &aDef[i]; } } } diff --git a/src/date.c b/src/date.c index f668ad0a84..905fa1d41f 100644 --- a/src/date.c +++ b/src/date.c @@ -1229,7 +1229,7 @@ static void currentTimeFunc( ** external linkage. */ void sqlite3RegisterDateTimeFunctions(void){ - static FuncDef aDateTimeFuncs[] = { + static SQLITE_WSD FuncDef aDateTimeFuncs[] = { #ifndef SQLITE_OMIT_DATETIME_FUNCS DFUNCTION(julianday, -1, 0, 0, juliandayFunc ), DFUNCTION(date, -1, 0, 0, dateFunc ), @@ -1245,5 +1245,5 @@ void sqlite3RegisterDateTimeFunctions(void){ STR_FUNCTION(current_timestamp, 0, "%Y-%m-%d %H:%M:%S", 0, currentTimeFunc), #endif }; - sqlite3InsertBuiltinFuncs(aDateTimeFuncs, ArraySize(aDateTimeFuncs)); + sqlite3InsertBuiltinFuncs(&GLOBAL(FuncDef, aDateTimeFuncs), ArraySize(aDateTimeFuncs)); } diff --git a/src/func.c b/src/func.c index 3d5a059a9f..a355f9c81b 100644 --- a/src/func.c +++ b/src/func.c @@ -1755,7 +1755,7 @@ void sqlite3RegisterBuiltinFunctions(void){ ** ** For peak efficiency, put the most frequently used function last. */ - static FuncDef aBuiltinFunc[] = { + static SQLITE_WSD FuncDef aBuiltinFunc[] = { #ifdef SQLITE_SOUNDEX FUNCTION(soundex, 1, 0, 0, soundexFunc ), #endif @@ -1850,7 +1850,7 @@ void sqlite3RegisterBuiltinFunctions(void){ sqlite3AnalyzeFunctions(); #endif sqlite3RegisterDateTimeFunctions(); - sqlite3InsertBuiltinFuncs(aBuiltinFunc, ArraySize(aBuiltinFunc)); + sqlite3InsertBuiltinFuncs(&GLOBAL(FuncDef, aBuiltinFunc), ArraySize(aBuiltinFunc)); #if 0 /* Enable to print out how the built-in functions are hashed */ { @@ -1858,7 +1858,7 @@ void sqlite3RegisterBuiltinFunctions(void){ FuncDef *p; for(i=0; iu.pHash){ + for(p=GLOBAL(FuncDefHash, sqlite3BuiltinFunctions).a[i]; p; p=p->u.pHash){ int n = sqlite3Strlen30(p->zName); int h = p->zName[0] + n; printf(" %s(%d)", p->zName, h); diff --git a/src/global.c b/src/global.c index fe63bbe140..f7263224f1 100644 --- a/src/global.c +++ b/src/global.c @@ -250,7 +250,7 @@ SQLITE_WSD struct Sqlite3Config sqlite3Config = { ** database connections. After initialization, this table is ** read-only. */ -FuncDefHash sqlite3BuiltinFunctions; +SQLITE_WSD FuncDefHash sqlite3BuiltinFunctions; /* ** Constant tokens for values 0 and 1. diff --git a/src/main.c b/src/main.c index 1aa80d9496..be4db79b63 100644 --- a/src/main.c +++ b/src/main.c @@ -225,7 +225,7 @@ int sqlite3_initialize(void){ sqlite3_init_sqllog(); } #endif - memset(&sqlite3BuiltinFunctions, 0, sizeof(sqlite3BuiltinFunctions)); + memset(&GLOBAL(FuncDefHash, sqlite3BuiltinFunctions), 0, sizeof(sqlite3BuiltinFunctions)); sqlite3RegisterBuiltinFunctions(); if( sqlite3GlobalConfig.isPCacheInit==0 ){ rc = sqlite3PcacheInitialize(); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index fc24885e28..c8330b0f17 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -4009,7 +4009,7 @@ extern const unsigned char sqlite3UpperToLower[]; extern const unsigned char sqlite3CtypeMap[]; extern const Token sqlite3IntTokens[]; extern SQLITE_WSD struct Sqlite3Config sqlite3Config; -extern FuncDefHash sqlite3BuiltinFunctions; +extern SQLITE_WSD FuncDefHash sqlite3BuiltinFunctions; #ifndef SQLITE_OMIT_WSD extern int sqlite3PendingByte; #endif diff --git a/src/vdbemem.c b/src/vdbemem.c index e95a8d1b9d..adcb78930a 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -1444,10 +1444,10 @@ static void recordFunc( ** Register built-in functions used to help read ANALYZE data. */ void sqlite3AnalyzeFunctions(void){ - static FuncDef aAnalyzeTableFuncs[] = { + static SQLITE_WSD FuncDef aAnalyzeTableFuncs[] = { FUNCTION(sqlite_record, 1, 0, 0, recordFunc), }; - sqlite3InsertBuiltinFuncs(aAnalyzeTableFuncs, ArraySize(aAnalyzeTableFuncs)); + sqlite3InsertBuiltinFuncs(&GLOBAL(FuncDef, aAnalyzeTableFuncs), ArraySize(aAnalyzeTableFuncs)); } /*