diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/build.c | 6 | ||||
-rw-r--r-- | src/test_mutex.c | 55 | ||||
-rw-r--r-- | src/tokenize.c | 23 |
3 files changed, 63 insertions, 21 deletions
diff --git a/src/build.c b/src/build.c index 09a82cbaf..8fe25968d 100644 --- a/src/build.c +++ b/src/build.c @@ -22,7 +22,7 @@ ** COMMIT ** ROLLBACK ** -** $Id: build.c,v 1.485 2008/06/15 02:51:47 drh Exp $ +** $Id: build.c,v 1.486 2008/07/08 00:06:50 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -238,6 +238,7 @@ void sqlite3FinishCoding(Parse *pParse){ void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){ va_list ap; char *zSql; + char *zErrMsg = 0; # define SAVE_SZ (sizeof(Parse) - offsetof(Parse,nVar)) char saveBuf[SAVE_SZ]; @@ -253,7 +254,8 @@ void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){ pParse->nested++; memcpy(saveBuf, &pParse->nVar, SAVE_SZ); memset(&pParse->nVar, 0, SAVE_SZ); - sqlite3RunParser(pParse, zSql, 0); + sqlite3RunParser(pParse, zSql, &zErrMsg); + sqlite3_free(zErrMsg); sqlite3_free(zSql); memcpy(&pParse->nVar, saveBuf, SAVE_SZ); pParse->nested--; diff --git a/src/test_mutex.c b/src/test_mutex.c index b24bd2e67..c2df5563a 100644 --- a/src/test_mutex.c +++ b/src/test_mutex.c @@ -10,7 +10,7 @@ ** ************************************************************************* ** -** $Id: test_mutex.c,v 1.4 2008/06/22 12:37:58 drh Exp $ +** $Id: test_mutex.c,v 1.5 2008/07/08 00:06:50 drh Exp $ */ #include "tcl.h" @@ -19,40 +19,65 @@ #include <assert.h> #include <string.h> +/* defined in test1.c */ const char *sqlite3TestErrorName(int); +/* A countable mutex */ struct sqlite3_mutex { sqlite3_mutex *pReal; int eType; }; +/* State variables */ static struct test_mutex_globals { - int isInstalled; - sqlite3_mutex_methods m; /* Interface to "real" mutex system */ - int aCounter[8]; /* Number of grabs of each type of mutex */ - sqlite3_mutex aStatic[6]; /* The six static mutexes */ + int isInstalled; /* True if installed */ + int disableInit; /* True to cause sqlite3_initalize() to fail */ + int isInit; /* True if initialized */ + sqlite3_mutex_methods m; /* Interface to "real" mutex system */ + int aCounter[8]; /* Number of grabs of each type of mutex */ + sqlite3_mutex aStatic[6]; /* The six static mutexes */ } g; +/* Return true if the countable mutex is currently held */ static int counterMutexHeld(sqlite3_mutex *p){ return g.m.xMutexHeld(p->pReal); } +/* Return true if the countable mutex is not currently held */ static int counterMutexNotheld(sqlite3_mutex *p){ return g.m.xMutexNotheld(p->pReal); } +/* Initialize the countable mutex interface +** Or, if g.disableInit is non-zero, then do not initialize but instead +** return the value of g.disableInit as the result code. This can be used +** to simulate an initialization failure. +*/ static int counterMutexInit(void){ - return g.m.xMutexInit(); + int rc; + if( g.disableInit ) return g.disableInit; + rc = g.m.xMutexInit(); + g.isInit = 1; + return rc; } +/* +** Uninitialize the mutex subsystem +*/ static int counterMutexEnd(void){ + assert( g.isInit ); + g.isInit = 0; return g.m.xMutexEnd(); } +/* +** Allocate a countable mutex +*/ static sqlite3_mutex *counterMutexAlloc(int eType){ sqlite3_mutex *pReal; sqlite3_mutex *pRet = 0; + assert( g.isInit ); assert(eType<8 && eType>=0); pReal = g.m.xMutexAlloc(eType); @@ -69,24 +94,39 @@ static sqlite3_mutex *counterMutexAlloc(int eType){ return pRet; } +/* +** Free a countable mutex +*/ static void counterMutexFree(sqlite3_mutex *p){ + assert( g.isInit ); g.m.xMutexFree(p->pReal); if( p->eType==0 || p->eType==1 ){ free(p); } } +/* +** Enter a countable mutex. Block until entry is safe. +*/ static void counterMutexEnter(sqlite3_mutex *p){ + assert( g.isInit ); g.aCounter[p->eType]++; g.m.xMutexEnter(p->pReal); } +/* +** Try to enter a mutex. Return true on success. +*/ static int counterMutexTry(sqlite3_mutex *p){ + assert( g.isInit ); g.aCounter[p->eType]++; return g.m.xMutexTry(p->pReal); } +/* Leave a mutex +*/ static void counterMutexLeave(sqlite3_mutex *p){ + assert( g.isInit ); g.m.xMutexLeave(p->pReal); } @@ -301,5 +341,8 @@ int Sqlitetest_mutex_Init(Tcl_Interp *interp){ Tcl_CreateObjCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0); } memset(&g, 0, sizeof(g)); + + Tcl_LinkVar(interp, "disable_mutex_init", + (char*)&g.disableInit, TCL_LINK_INT); return SQLITE_OK; } diff --git a/src/tokenize.c b/src/tokenize.c index 4b545a324..05622dae1 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -15,7 +15,7 @@ ** individual tokens and sends those tokens one-by-one over to the ** parser for analysis. ** -** $Id: tokenize.c,v 1.144 2008/06/15 02:51:48 drh Exp $ +** $Id: tokenize.c,v 1.145 2008/07/08 00:06:50 drh Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -374,9 +374,9 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){ /* ** Run the parser on the given SQL string. The parser structure is ** passed in. An SQLITE_ status code is returned. If an error occurs -** and pzErrMsg!=NULL then an error message might be written into -** memory obtained from sqlite3_malloc() and *pzErrMsg made to point to that -** error message. Or maybe not. +** then an and attempt is made to write an error message into +** memory obtained from sqlite3_malloc() and to make *pzErrMsg point to that +** error message. */ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ int nErr = 0; @@ -393,6 +393,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ pParse->rc = SQLITE_OK; pParse->zTail = pParse->zSql = zSql; i = 0; + assert( pzErrMsg!=0 ); pEngine = sqlite3ParserAlloc((void*(*)(size_t))sqlite3Malloc); if( pEngine==0 ){ db->mallocFailed = 1; @@ -420,19 +421,15 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ case TK_COMMENT: { if( db->u1.isInterrupted ){ pParse->rc = SQLITE_INTERRUPT; - if( pzErrMsg ){ - sqlite3SetString(pzErrMsg, "interrupt", (char*)0); - } + sqlite3SetString(pzErrMsg, "interrupt", (char*)0); goto abort_parse; } break; } case TK_ILLEGAL: { - if( pzErrMsg ){ - sqlite3_free(*pzErrMsg); - *pzErrMsg = sqlite3MPrintf(db, "unrecognized token: \"%T\"", - &pParse->sLastToken); - } + sqlite3_free(*pzErrMsg); + *pzErrMsg = sqlite3MPrintf(db, "unrecognized token: \"%T\"", + &pParse->sLastToken); nErr++; goto abort_parse; } @@ -466,7 +463,7 @@ abort_parse: sqlite3SetString(&pParse->zErrMsg, sqlite3ErrStr(pParse->rc), (char*)0); } if( pParse->zErrMsg ){ - if( pzErrMsg && *pzErrMsg==0 ){ + if( *pzErrMsg==0 ){ *pzErrMsg = pParse->zErrMsg; }else{ sqlite3_free(pParse->zErrMsg); |