Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch sqlite4_env Excluding Merge-Ins
This is equivalent to a diff from 949cb749fe to dee2172b52
2012-06-25
| ||
19:34 | Merge the sqlite4_env api changes onto trunk. There is still a lot of work to be done, but it at least now passes most tests. check-in: 4192f826d1 user: drh tags: trunk | |
19:28 | Fixes to the kvwrap test interface. At this point, most tests pass, though there are still massive memory leaks. Major unresolved issues: (1) the global function. (2) API for substituting new storage engines. Leaf check-in: dee2172b52 user: drh tags: sqlite4_env | |
18:53 | Initialize the random number generator in sqlite4_initialize(). check-in: a34def59f7 user: drh tags: sqlite4_env | |
2012-06-22
| ||
20:29 | Continuing work on sqlite4_env and getting it to be used everywhere. The changes here are mostly having to do with mutexes. They compile, but there are errors. This is an incremental check-in so that I can change to work on another project where an issue has just come up. check-in: 1d65209131 user: drh tags: sqlite4_env | |
18:06 | Merge trunk changes. check-in: df818c275b user: dan tags: embedded-btree | |
16:55 | Modify sqlite4_mem_methods to remove xRoundup, add the Benign methods, and for all methods to take an environment pointer as their first argument. check-in: 949cb749fe user: drh tags: trunk | |
14:58 | Add the sqlite4_env parameter to sqlite4_threadsafe(). check-in: d3fa91fcba user: drh tags: trunk | |
Changes to src/alter.c.
︙ | ︙ | |||
75 76 77 78 79 80 81 | len = sqlite4GetToken(zCsr, &token); } while( token==TK_SPACE ); assert( len>0 ); } while( token!=TK_LP && token!=TK_USING ); zRet = sqlite4MPrintf(db, "%.*s\"%w\"%s", ((u8*)tname.z) - zSql, zSql, zTableName, tname.z+tname.n); | | > | 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | len = sqlite4GetToken(zCsr, &token); } while( token==TK_SPACE ); assert( len>0 ); } while( token!=TK_LP && token!=TK_USING ); zRet = sqlite4MPrintf(db, "%.*s\"%w\"%s", ((u8*)tname.z) - zSql, zSql, zTableName, tname.z+tname.n); sqlite4_result_text(context, zRet, -1, SQLITE_TRANSIENT); sqlite4DbFree(db, zRet); } } /* ** This C function implements an SQL user function that is used by SQL code ** generated by the ALTER TABLE ... RENAME command to modify the definition ** of any foreign key constraints that use the table being renamed as the |
︙ | ︙ | |||
137 138 139 140 141 142 143 | zInput = &z[n]; } sqlite4DbFree(db, zParent); } } zResult = sqlite4MPrintf(db, "%s%s", (zOutput?zOutput:""), zInput), | | > | 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | zInput = &z[n]; } sqlite4DbFree(db, zParent); } } zResult = sqlite4MPrintf(db, "%s%s", (zOutput?zOutput:""), zInput), sqlite4_result_text(context, zResult, -1, SQLITE_TRANSIENT); sqlite4DbFree(db, zOutput); sqlite4DbFree(db, zResult); } #endif #ifndef SQLITE_OMIT_TRIGGER /* This function is used by SQL generated to implement the ** ALTER TABLE command. The first argument is the text of a CREATE TRIGGER ** statement. The second is a table name. The table name in the CREATE |
︙ | ︙ | |||
214 215 216 217 218 219 220 | } while( dist!=2 || (token!=TK_WHEN && token!=TK_FOR && token!=TK_BEGIN) ); /* Variable tname now contains the token that is the old table-name ** in the CREATE TRIGGER statement. */ zRet = sqlite4MPrintf(db, "%.*s\"%w\"%s", ((u8*)tname.z) - zSql, zSql, zTableName, tname.z+tname.n); | | > | | | 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 | } while( dist!=2 || (token!=TK_WHEN && token!=TK_FOR && token!=TK_BEGIN) ); /* Variable tname now contains the token that is the old table-name ** in the CREATE TRIGGER statement. */ zRet = sqlite4MPrintf(db, "%.*s\"%w\"%s", ((u8*)tname.z) - zSql, zSql, zTableName, tname.z+tname.n); sqlite4_result_text(context, zRet, -1, SQLITE_TRANSIENT); sqlite4DbFree(db, zRet); } } #endif /* !SQLITE_OMIT_TRIGGER */ /* ** Register built-in functions used to help implement ALTER TABLE */ void sqlite4AlterFunctions(sqlite4_env *pEnv){ 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), #endif #ifndef SQLITE_OMIT_FOREIGN_KEY FUNCTION(sqlite_rename_parent, 3, 0, 0, renameParentFunc), #endif }; int i; FuncDefHash *pHash = &pEnv->hashGlobalFuncs; FuncDef *aFunc = (FuncDef*)aAlterTableFuncs; for(i=0; i<ArraySize(aAlterTableFuncs); i++){ sqlite4FuncDefInsert(pHash, &aFunc[i]); } } |
︙ | ︙ |
Changes to src/callback.c.
︙ | ︙ | |||
360 361 362 363 364 365 366 | ** Except, if createFlag is true, that means that we are trying to ** install a new function. Whatever FuncDef structure is returned it will ** have fields overwritten with new information appropriate for the ** new function. But the FuncDefs for built-in functions are read-only. ** So we must not search for built-ins when creating a new function. */ if( !createFlag && (pBest==0 || (db->flags & SQLITE_PreferBuiltin)!=0) ){ | | | 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 | ** Except, if createFlag is true, that means that we are trying to ** install a new function. Whatever FuncDef structure is returned it will ** have fields overwritten with new information appropriate for the ** new function. But the FuncDefs for built-in functions are read-only. ** So we must not search for built-ins when creating a new function. */ if( !createFlag && (pBest==0 || (db->flags & SQLITE_PreferBuiltin)!=0) ){ FuncDefHash *pHash = &db->pEnv->hashGlobalFuncs; bestScore = 0; p = functionSearch(pHash, h, zName, nName); while( p ){ int score = matchQuality(p, nArg, enc); if( score>bestScore ){ pBest = p; bestScore = score; |
︙ | ︙ |
Changes to src/date.c.
︙ | ︙ | |||
1112 1113 1114 1115 1116 1117 1118 | #else STR_FUNCTION(current_time, 0, "%H:%M:%S", 0, currentTimeFunc), STR_FUNCTION(current_date, 0, "%Y-%m-%d", 0, currentTimeFunc), STR_FUNCTION(current_timestamp, 0, "%Y-%m-%d %H:%M:%S", 0, currentTimeFunc), #endif }; int i; | | | 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 | #else STR_FUNCTION(current_time, 0, "%H:%M:%S", 0, currentTimeFunc), STR_FUNCTION(current_date, 0, "%Y-%m-%d", 0, currentTimeFunc), STR_FUNCTION(current_timestamp, 0, "%Y-%m-%d %H:%M:%S", 0, currentTimeFunc), #endif }; int i; FuncDefHash *pHash = &pEnv->hashGlobalFuncs; FuncDef *aFunc = (FuncDef*)aDateTimeFuncs; for(i=0; i<ArraySize(aDateTimeFuncs); i++){ sqlite4FuncDefInsert(pHash, &aFunc[i]); } } |
Changes to src/func.c.
︙ | ︙ | |||
1590 1591 1592 1593 1594 1595 1596 | #else LIKEFUNC(like, 2, &likeInfoNorm, SQLITE_FUNC_LIKE), LIKEFUNC(like, 3, &likeInfoNorm, SQLITE_FUNC_LIKE), #endif }; int i; | | | | 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 | #else LIKEFUNC(like, 2, &likeInfoNorm, SQLITE_FUNC_LIKE), LIKEFUNC(like, 3, &likeInfoNorm, SQLITE_FUNC_LIKE), #endif }; int i; FuncDefHash *pHash = &pEnv->hashGlobalFuncs; FuncDef *aFunc = (FuncDef*)aBuiltinFunc; for(i=0; i<ArraySize(aBuiltinFunc); i++){ sqlite4FuncDefInsert(pHash, &aFunc[i]); } sqlite4RegisterDateTimeFunctions(pEnv); #ifndef SQLITE_OMIT_ALTERTABLE sqlite4AlterFunctions(pEnv); #endif } |
Changes to src/global.c.
︙ | ︙ | |||
138 139 140 141 142 143 144 | 1, /* iVersion */ SQLITE_DEFAULT_MEMSTATUS, /* bMemstat */ 1, /* bCoreMutex */ SQLITE_THREADSAFE==1, /* bFullMutex */ 0x7ffffffe, /* mxStrlen */ 128, /* szLookaside */ 500, /* nLookaside */ | < | > | | < < < > > > > < < < < < < < | 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 | 1, /* iVersion */ SQLITE_DEFAULT_MEMSTATUS, /* bMemstat */ 1, /* bCoreMutex */ SQLITE_THREADSAFE==1, /* bFullMutex */ 0x7ffffffe, /* mxStrlen */ 128, /* szLookaside */ 500, /* nLookaside */ {0,0,0,0,0,0,0,0,0}, /* m */ {0,0,0,0,0,0,0,0,0,0}, /* mutex */ (void*)0, /* pHeap */ 0, /* nHeap */ 0, 0, /* mnHeap, mxHeap */ 0, /* mxParserStack */ sqlite4KVStoreOpenLsm, /* xKVFile */ sqlite4KVStoreOpenMem, /* xKVTmp */ sqlite4OsRandomness, /* xRandomness */ sqlite4OsCurrentTime, /* xCurrentTime */ /* All the rest should always be initialized to zero */ 0, /* isInit */ 0, /* pPrngMutex */ 0, 0, /* prngX, prngY */ 0, /* xLog */ 0, /* pLogArg */ 0, /* bLocaltimeFault */ 0, /* pMemMutex */ {0,0,0,0}, /* nowValue[] */ {0,0,0,0}, /* mxValue[] */ {0,} /* hashGlobalFunc */ }; /* ** Return the default environment */ sqlite4_env *sqlite4_env_default(void){ return &sqlite4DefaultEnv; } /* ** Constant tokens for values 0 and 1. */ const Token sqlite4IntTokens[] = { { "0", 1 }, { "1", 1 } }; |
︙ | ︙ |
Changes to src/main.c.
︙ | ︙ | |||
78 79 80 81 82 83 84 | ** As long as you do not compile with SQLITE_OMIT_AUTOINIT ** this routine will be called automatically by key routines such as ** sqlite4_open(). ** ** This routine is a no-op except on its very first call for a given ** sqlite4_env object, or for the first call after a call to sqlite4_shutdown. ** | | < | | < < < < < < < < < < | < < < < | < < < < < | | > > | | < < < | < < < < | < < < < < < < < < < < < < < < < < < < < | | | < < < < < | | | | | | < | | < < < | | > | < | < < < < < < < < < < < < < < < < | < | < | | < < < < < < < < < < < < < < | 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | ** As long as you do not compile with SQLITE_OMIT_AUTOINIT ** this routine will be called automatically by key routines such as ** sqlite4_open(). ** ** This routine is a no-op except on its very first call for a given ** sqlite4_env object, or for the first call after a call to sqlite4_shutdown. ** ** This routine is not threadsafe. It should be called from a single ** thread to initialized the library in a multi-threaded system. Other ** threads should avoid using the sqlite4_env object until after it has ** completely initialized. */ int sqlite4_initialize(sqlite4_env *pEnv){ MUTEX_LOGIC( sqlite4_mutex *pMaster; ) /* The main static mutex */ int rc; /* Result code */ if( pEnv==0 ) pEnv = &sqlite4DefaultEnv; /* If SQLite is already completely initialized, then this call ** to sqlite4_initialize() should be a no-op. But the initialization ** must be complete. So isInit must not be set until the very end ** of this routine. */ if( pEnv->isInit ) return SQLITE_OK; /* Initialize the mutex subsystem */ rc = sqlite4MutexInit(pEnv); if( rc ){ sqlite4MallocEnd(pEnv); return rc; } /* Initialize the memory allocation subsystem */ rc = sqlite4MallocInit(pEnv); if( rc ) return rc; /* Create required mutexes */ if( pEnv->bCoreMutex ){ pEnv->pMemMutex = sqlite4MutexAlloc(pEnv, SQLITE_MUTEX_FAST); pEnv->pPrngMutex = sqlite4MutexAlloc(pEnv, SQLITE_MUTEX_FAST); if( pEnv->pMemMutex==0 || pEnv->pPrngMutex==0 ) rc = SQLITE_NOMEM; }else{ pEnv->pMemMutex = 0; pEnv->pPrngMutex = 0; } pEnv->isInit = 1; sqlite4OsInit(pEnv); /* Register global functions */ if( rc==SQLITE_OK ){ sqlite4RegisterGlobalFunctions(pEnv); } /* The following is just a sanity check to make sure SQLite has ** been compiled correctly. It is important to run this code, but ** we don't want to run it too often and soak up CPU cycles for no ** reason. So we run it once during initialization. */ #ifndef NDEBUG #ifndef SQLITE_OMIT_FLOATING_POINT /* This section of code's only "output" is via assert() statements. */ if ( rc==SQLITE_OK ){ u64 x = (((u64)1)<<63)-1; double y; assert(sizeof(x)==8); assert(sizeof(x)==sizeof(y)); memcpy(&y, &x, 8); assert( sqlite4IsNaN(y) ); } #endif #endif return rc; } /* ** Undo the effects of sqlite4_initialize(). Must not be called while ** there are outstanding database connections or memory allocations or ** while any part of SQLite is otherwise in use in any thread. This ** routine is not threadsafe. But it is safe to invoke this routine ** on when SQLite is already shut down. If SQLite is already shut down ** when this routine is invoked, then this routine is a harmless no-op. */ int sqlite4_shutdown(sqlite4_env *pEnv){ if( pEnv==0 ) pEnv = &sqlite4DefaultEnv; if( pEnv->isInit ){ sqlite4_mutex_free(pEnv->pMemMutex); pEnv->pMemMutex = 0; sqlite4MutexEnd(pEnv); sqlite4MallocEnd(pEnv); pEnv->isInit = 0; } return SQLITE_OK; } /* ** This API allows applications to modify the configuration described by ** an sqlite4_env object. */ int sqlite4_config(sqlite4_env *pEnv, int op, ...){ va_list ap; int rc = SQLITE_OK; if( pEnv==0 ) pEnv = sqlite4_env_default(); /* sqlite4_config() shall return SQLITE_MISUSE if it is invoked while ** the SQLite library is in use. */ if( pEnv->isInit ) return SQLITE_MISUSE_BKPT; va_start(ap, op); switch( op ){ default: { rc = SQLITE_ERROR; break; } } va_end(ap); return rc; |
︙ | ︙ | |||
466 467 468 469 470 471 472 | /* ** sqlite4_env_config(pEnv, SQLITE_ENVCONFIG_KVSTORE_PUSH, zName, xFactory); ** ** Push a new KVStore factory onto the factory stack. The new factory ** takes priority over prior factories. */ case SQLITE_ENVCONFIG_KVSTORE_PUSH: { | > > > > > > | | | > > > > | > > > > > > > > > > > | > > > | 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 | /* ** sqlite4_env_config(pEnv, SQLITE_ENVCONFIG_KVSTORE_PUSH, zName, xFactory); ** ** Push a new KVStore factory onto the factory stack. The new factory ** takes priority over prior factories. */ case SQLITE_ENVCONFIG_KVSTORE_PUSH: { const char *zName = va_arg(ap, const char*); if( strcmp(zName, "temp")==0 ){ pEnv->xKVTmp = *va_arg(ap, int (*)(sqlite4_env*, KVStore **, const char *, unsigned int) ); }else{ pEnv->xKVFile = *va_arg(ap, int (*)(sqlite4_env*, KVStore **, const char *, unsigned int) ); } break; } /* ** sqlite4_env_config(pEnv, SQLITE_ENVCONFIG_KVSTORE_POP, zName); ** ** Remove a KVStore factory from the stack. */ case SQLITE_ENVCONFIG_KVSTORE_POP: { /* TBD */ break; } /* ** sqlite4_env_config(pEnv, SQLITE_ENVCONFIG_KVSTORE_GET, zName,&pxFactory); ** ** Get the current factory pointer with the given name. */ case SQLITE_ENVCONFIG_KVSTORE_GET: { const char *zName = va_arg(ap, const char*); int(*xFactory)(sqlite4_env*,KVStore**,const char*,unsigned); if( strcmp(zName, "temp")==0 ){ xFactory = pEnv->xKVTmp; }else{ xFactory = pEnv->xKVFile; } *va_arg(ap, int(**)(sqlite4_env*, KVStore**, const char*, unsigned int)) = xFactory; break; } default: { rc = SQLITE_ERROR; break; |
︙ | ︙ | |||
1751 1752 1753 1754 1755 1756 1757 | } /* Allocate the sqlite data structure */ db = sqlite4MallocZero(pEnv, sizeof(sqlite4) ); if( db==0 ) goto opendb_out; db->pEnv = pEnv; if( isThreadsafe ){ | | | 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 | } /* Allocate the sqlite data structure */ db = sqlite4MallocZero(pEnv, sizeof(sqlite4) ); if( db==0 ) goto opendb_out; db->pEnv = pEnv; if( isThreadsafe ){ db->mutex = sqlite4MutexAlloc(pEnv, SQLITE_MUTEX_RECURSIVE); if( db->mutex==0 ){ sqlite4_free(pEnv, db); db = 0; goto opendb_out; } } sqlite4_mutex_enter(db->mutex); |
︙ | ︙ | |||
2082 2083 2084 2085 2086 2087 2088 | int sqlite4_test_control(int op, ...){ int rc = 0; #ifndef SQLITE_OMIT_BUILTIN_TEST va_list ap; va_start(ap, op); switch( op ){ | < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 | int sqlite4_test_control(int op, ...){ int rc = 0; #ifndef SQLITE_OMIT_BUILTIN_TEST va_list ap; va_start(ap, op); switch( op ){ /* ** sqlite4_test_control(BENIGN_MALLOC_HOOKS, xBegin, xEnd) ** ** Register hooks to call to indicate which malloc() failures ** are benign. */ case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS: { |
︙ | ︙ |
Changes to src/malloc.c.
︙ | ︙ | |||
11 12 13 14 15 16 17 | ************************************************************************* ** ** Memory allocation functions used throughout sqlite. */ #include "sqliteInt.h" #include <stdarg.h> | < < < < < < < < < < < | | < | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | ************************************************************************* ** ** Memory allocation functions used throughout sqlite. */ #include "sqliteInt.h" #include <stdarg.h> /* ** Initialize the memory allocation subsystem. */ int sqlite4MallocInit(sqlite4_env *pEnv){ if( pEnv->m.xMalloc==0 ){ sqlite4MemSetDefault(pEnv); } return pEnv->m.xInit(pEnv->m.pMemEnv); } /* ** Deinitialize the memory allocation subsystem. */ void sqlite4MallocEnd(sqlite4_env *pEnv){ if( pEnv->m.xShutdown ){ pEnv->m.xShutdown(pEnv->m.pMemEnv); } } /* ** Return the amount of memory currently checked out. */ sqlite4_uint64 sqlite4_memory_used(sqlite4_env *pEnv){ sqlite4_uint64 n, mx; |
︙ | ︙ | |||
83 84 85 86 87 88 89 | ** signed integer value might cause an integer overflow inside of the ** xMalloc(). Hence we limit the maximum size to 0x7fffff00, giving ** 255 bytes of overhead. SQLite itself will never use anything near ** this amount. The only way to reach the limit is with sqlite4_malloc() */ p = 0; }else if( pEnv->bMemstat ){ int nFull = (n + 7)&~7; | | | | | | 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | ** signed integer value might cause an integer overflow inside of the ** xMalloc(). Hence we limit the maximum size to 0x7fffff00, giving ** 255 bytes of overhead. SQLite itself will never use anything near ** this amount. The only way to reach the limit is with sqlite4_malloc() */ p = 0; }else if( pEnv->bMemstat ){ int nFull = (n + 7)&~7; sqlite4_mutex_enter(pEnv->pMemMutex); p = pEnv->m.xMalloc(pEnv->m.pMemEnv, nFull); if( p ){ nFull = sqlite4MallocSize(pEnv, p); sqlite4StatusAdd(pEnv, SQLITE_ENVSTATUS_MEMORY_USED, nFull); sqlite4StatusAdd(pEnv, SQLITE_ENVSTATUS_MALLOC_COUNT, 1); } sqlite4StatusSet(pEnv, SQLITE_ENVSTATUS_MALLOC_SIZE, n); sqlite4_mutex_leave(pEnv->pMemMutex); }else{ p = pEnv->m.xMalloc(pEnv->m.pMemEnv, n); } assert( EIGHT_BYTE_ALIGNMENT(p) ); /* IMP: R-04675-44850 */ return p; } /* ** This version of the memory allocation is for use by the application. |
︙ | ︙ | |||
132 133 134 135 136 137 138 | ** Return the size of a memory allocation previously obtained from ** sqlite4Malloc() or sqlite4_malloc(). */ int sqlite4MallocSize(sqlite4_env *pEnv, void *p){ assert( sqlite4MemdebugHasType(p, MEMTYPE_HEAP) ); assert( sqlite4MemdebugNoType(p, MEMTYPE_DB) ); if( pEnv==0 ) pEnv = &sqlite4DefaultEnv; | | | | | | | | 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | ** Return the size of a memory allocation previously obtained from ** sqlite4Malloc() or sqlite4_malloc(). */ int sqlite4MallocSize(sqlite4_env *pEnv, void *p){ assert( sqlite4MemdebugHasType(p, MEMTYPE_HEAP) ); assert( sqlite4MemdebugNoType(p, MEMTYPE_DB) ); if( pEnv==0 ) pEnv = &sqlite4DefaultEnv; return pEnv->m.xSize(pEnv->m.pMemEnv, p); } int sqlite4DbMallocSize(sqlite4 *db, void *p){ assert( db==0 || sqlite4_mutex_held(db->mutex) ); if( db && isLookaside(db, p) ){ return db->lookaside.sz; }else{ sqlite4_env *pEnv = db->pEnv; assert( sqlite4MemdebugHasType(p, MEMTYPE_DB) ); assert( sqlite4MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) ); assert( db!=0 || sqlite4MemdebugNoType(p, MEMTYPE_LOOKASIDE) ); return pEnv->m.xSize(pEnv->m.pMemEnv, p); } } /* ** Free memory previously obtained from sqlite4Malloc(). */ void sqlite4_free(sqlite4_env *pEnv, void *p){ if( p==0 ) return; /* IMP: R-49053-54554 */ assert( sqlite4MemdebugNoType(p, MEMTYPE_DB) ); assert( sqlite4MemdebugHasType(p, MEMTYPE_HEAP) ); if( pEnv==0 ) pEnv = &sqlite4DefaultEnv; if( pEnv->bMemstat ){ sqlite4_mutex_enter(pEnv->pMemMutex); sqlite4StatusAdd(pEnv,SQLITE_ENVSTATUS_MEMORY_USED, -sqlite4MallocSize(pEnv, p)); sqlite4StatusAdd(pEnv,SQLITE_ENVSTATUS_MALLOC_COUNT, -1); pEnv->m.xFree(pEnv->m.pMemEnv, p); sqlite4_mutex_leave(pEnv->pMemMutex); }else{ pEnv->m.xFree(pEnv->m.pMemEnv, p); } } /* ** Free memory that might be associated with a particular database ** connection. */ |
︙ | ︙ | |||
215 216 217 218 219 220 221 | if( nBytes>=0x7fffff00 ){ /* The 0x7ffff00 limit term is explained in comments on sqlite4Malloc() */ return 0; } nOld = sqlite4MallocSize(pEnv, pOld); nNew = (nBytes + 7)&~7; if( pEnv->bMemstat ){ | | | | | | 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 | if( nBytes>=0x7fffff00 ){ /* The 0x7ffff00 limit term is explained in comments on sqlite4Malloc() */ return 0; } nOld = sqlite4MallocSize(pEnv, pOld); nNew = (nBytes + 7)&~7; if( pEnv->bMemstat ){ sqlite4_mutex_enter(pEnv->pMemMutex); sqlite4StatusSet(pEnv, SQLITE_ENVSTATUS_MALLOC_SIZE, nBytes); assert( sqlite4MemdebugHasType(pOld, MEMTYPE_HEAP) ); assert( sqlite4MemdebugNoType(pOld, ~MEMTYPE_HEAP) ); pNew = pEnv->m.xRealloc(pEnv->m.pMemEnv, pOld, nNew); if( pNew ){ nNew = sqlite4MallocSize(pEnv, pNew); sqlite4StatusAdd(pEnv, SQLITE_ENVSTATUS_MEMORY_USED, nNew-nOld); } sqlite4_mutex_leave(pEnv->pMemMutex); }else{ pNew = pEnv->m.xRealloc(pEnv->m.pMemEnv, pOld, nNew); } assert( EIGHT_BYTE_ALIGNMENT(pNew) ); /* IMP: R-04675-44850 */ return pNew; } /* ** The public interface to sqlite4Realloc. Make sure that the memory |
︙ | ︙ |
Changes to src/mem0.c.
︙ | ︙ | |||
52 53 54 55 56 57 58 59 60 61 | sqlite4MemInit, sqlite4MemShutdown, 0, 0, 0 }; pEnv->m = defaultMethods; } #endif /* SQLITE_ZERO_MALLOC */ | > | 52 53 54 55 56 57 58 59 60 61 62 | sqlite4MemInit, sqlite4MemShutdown, 0, 0, 0 }; pEnv->m = defaultMethods; pEnv->m.pMemEnv = (void*)pEnv; } #endif /* SQLITE_ZERO_MALLOC */ |
Changes to src/mem1.c.
︙ | ︙ | |||
275 276 277 278 279 280 281 282 283 284 | sqlite4MemInit, sqlite4MemShutdown, 0, 0, 0 }; pEnv->m = defaultMethods; } #endif /* SQLITE_SYSTEM_MALLOC */ | > | 275 276 277 278 279 280 281 282 283 284 285 | sqlite4MemInit, sqlite4MemShutdown, 0, 0, 0 }; pEnv->m = defaultMethods; pEnv->m.pMemEnv = (void*)pEnv; } #endif /* SQLITE_SYSTEM_MALLOC */ |
Changes to src/mem2.c.
︙ | ︙ | |||
182 183 184 185 186 187 188 | pHdr = sqlite4MemsysGetHeader(p); return pHdr->iSize; } /* ** Initialize the memory allocation subsystem. */ | | | > | < < | > | | | > | 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 | pHdr = sqlite4MemsysGetHeader(p); return pHdr->iSize; } /* ** Initialize the memory allocation subsystem. */ static int sqlite4MemInit(void *pMallocEnv){ sqlite4_env *pEnv = (sqlite4_env*)pMallocEnv; int rc = SQLITE_OK; assert( (sizeof(struct MemBlockHdr)&7) == 0 ); if( !pEnv->bMemstat ){ mem2.mutex = sqlite4MutexAlloc(pEnv, SQLITE_MUTEX_FAST); if( mem2.mutex==0 && pEnv->bCoreMutex ) rc = SQLITE_NOMEM; } return rc; } /* ** Deinitialize the memory allocation subsystem. */ static void sqlite4MemShutdown(void *NotUsed){ UNUSED_PARAMETER(NotUsed); sqlite4_mutex_free(mem2.mutex); mem2.mutex = 0; } /* ** Fill a buffer with pseudo-random bytes. This is used to preset ** the content of a new memory allocation to unpredictable values and ** to clear the content of a freed allocation to unpredictable values. |
︙ | ︙ | |||
390 391 392 393 394 395 396 | ** allocation p. Also return true if p==NULL. ** ** This routine is designed for use within an assert() statement, to ** verify the type of an allocation. For example: ** ** assert( sqlite4MemdebugHasType(p, MEMTYPE_DB) ); */ | | | 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 | ** allocation p. Also return true if p==NULL. ** ** This routine is designed for use within an assert() statement, to ** verify the type of an allocation. For example: ** ** assert( sqlite4MemdebugHasType(p, MEMTYPE_DB) ); */ int sqlite4MemdebugHasType(const void *p, u8 eType){ int rc = 1; if( p && sqlite4DefaultEnv.m.xMalloc==sqlite4MemMalloc ){ struct MemBlockHdr *pHdr; pHdr = sqlite4MemsysGetHeader(p); assert( pHdr->iForeGuard==FOREGUARD ); /* Allocation is valid */ if( (pHdr->eType&eType)==0 ){ rc = 0; |
︙ | ︙ | |||
412 413 414 415 416 417 418 | ** allocation p. Also return true if p==NULL. ** ** This routine is designed for use within an assert() statement, to ** verify the type of an allocation. For example: ** ** assert( sqlite4MemdebugNoType(p, MEMTYPE_DB) ); */ | | | 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 | ** allocation p. Also return true if p==NULL. ** ** This routine is designed for use within an assert() statement, to ** verify the type of an allocation. For example: ** ** assert( sqlite4MemdebugNoType(p, MEMTYPE_DB) ); */ int sqlite4MemdebugNoType(const void *p, u8 eType){ int rc = 1; if( p && sqlite4DefaultEnv.m.xMalloc==sqlite4MemMalloc ){ struct MemBlockHdr *pHdr; pHdr = sqlite4MemsysGetHeader(p); assert( pHdr->iForeGuard==FOREGUARD ); /* Allocation is valid */ if( (pHdr->eType&eType)!=0 ){ rc = 0; |
︙ | ︙ |
Changes to src/mutex.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** This file contains the C functions that implement mutexes. ** ** This file contains code that is common across all mutex implementations. */ #include "sqliteInt.h" | < < < < < < < < < < | | < < < < < < < < | | | < < < | | < < < < < | | | < < < < < | > | | | | < | | | | | | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | ** ************************************************************************* ** This file contains the C functions that implement mutexes. ** ** This file contains code that is common across all mutex implementations. */ #include "sqliteInt.h" #ifndef SQLITE_MUTEX_OMIT /* ** Initialize the mutex system. */ int sqlite4MutexInit(sqlite4_env *pEnv){ int rc = SQLITE_OK; if( !pEnv->mutex.xMutexAlloc ){ if( pEnv->bCoreMutex ){ pEnv->mutex = *sqlite4DefaultMutex(); }else{ pEnv->mutex = *sqlite4NoopMutex(); } pEnv->mutex.pMutexEnv = pEnv; } rc = pEnv->mutex.xMutexInit(pEnv->mutex.pMutexEnv); return rc; } /* ** Shutdown the mutex system. This call frees resources allocated by ** sqlite4MutexInit(). */ int sqlite4MutexEnd(sqlite4_env *pEnv){ int rc = SQLITE_OK; if( pEnv->mutex.xMutexEnd ){ rc = pEnv->mutex.xMutexEnd(pEnv->mutex.pMutexEnv); } return rc; } /* ** Retrieve a pointer to a static mutex or allocate a new dynamic one. */ sqlite4_mutex *sqlite4_mutex_alloc(sqlite4_env *pEnv, int id){ if( pEnv==0 ) pEnv = &sqlite4DefaultEnv; #ifndef SQLITE_OMIT_AUTOINIT if( sqlite4_initialize(pEnv) ) return 0; #endif return pEnv->mutex.xMutexAlloc(pEnv->mutex.pMutexEnv, id); } sqlite4_mutex *sqlite4MutexAlloc(sqlite4_env *pEnv, int id){ if( !pEnv->bCoreMutex ){ return 0; } return pEnv->mutex.xMutexAlloc(pEnv->mutex.pMutexEnv, id); } /* ** Free a dynamic mutex. */ void sqlite4_mutex_free(sqlite4_mutex *p){ if( p ){ p->pMutexMethods->xMutexFree(p); } } /* ** Obtain the mutex p. If some other thread already has the mutex, block ** until it can be obtained. */ void sqlite4_mutex_enter(sqlite4_mutex *p){ if( p ){ p->pMutexMethods->xMutexEnter(p); } } /* ** Obtain the mutex p. If successful, return SQLITE_OK. Otherwise, if another ** thread holds the mutex and it cannot be obtained, return SQLITE_BUSY. */ int sqlite4_mutex_try(sqlite4_mutex *p){ int rc = SQLITE_OK; if( p ){ return p->pMutexMethods->xMutexTry(p); } return rc; } /* ** The sqlite4_mutex_leave() routine exits a mutex that was previously ** entered by the same thread. The behavior is undefined if the mutex ** is not currently entered. If a NULL pointer is passed as an argument ** this function is a no-op. */ void sqlite4_mutex_leave(sqlite4_mutex *p){ if( p ){ p->pMutexMethods->xMutexLeave(p); } } #ifndef NDEBUG /* ** The sqlite4_mutex_held() and sqlite4_mutex_notheld() routine are ** intended for use inside assert() statements. */ int sqlite4_mutex_held(sqlite4_mutex *p){ return p==0 || p->pMutexMethods->xMutexHeld(p); } int sqlite4_mutex_notheld(sqlite4_mutex *p){ return p==0 || p->pMutexMethods->xMutexNotheld(p); } #endif #endif /* !defined(SQLITE_MUTEX_OMIT) */ |
Changes to src/mutex.h.
︙ | ︙ | |||
50 51 52 53 54 55 56 | # endif #endif #ifdef SQLITE_MUTEX_OMIT /* ** If this is a no-op implementation, implement everything as macros. */ | | | | | | 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | # endif #endif #ifdef SQLITE_MUTEX_OMIT /* ** If this is a no-op implementation, implement everything as macros. */ #define sqlite4_mutex_alloc(X,Y) ((sqlite4_mutex*)8) #define sqlite4_mutex_free(X) #define sqlite4_mutex_enter(X) #define sqlite4_mutex_try(X) SQLITE_OK #define sqlite4_mutex_leave(X) #define sqlite4_mutex_held(X) ((void)(X),1) #define sqlite4_mutex_notheld(X) ((void)(X),1) #define sqlite4MutexAlloc(X,Y) ((sqlite4_mutex*)8) #define sqlite4MutexInit(E) SQLITE_OK #define sqlite4MutexEnd(E) #define MUTEX_LOGIC(X) #else #define MUTEX_LOGIC(X) X #endif /* defined(SQLITE_MUTEX_OMIT) */ |
Changes to src/mutex_noop.c.
︙ | ︙ | |||
31 32 33 34 35 36 37 | #ifndef SQLITE_DEBUG /* ** Stub routines for all mutex methods. ** ** This routines provide no mutual exclusion or error checking. */ | | | | > < < | > | > > | | | | | | | | < | < < < | | | | < < < < < < < | < < | < | | | | < | > | 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | #ifndef SQLITE_DEBUG /* ** Stub routines for all mutex methods. ** ** This routines provide no mutual exclusion or error checking. */ static int noopMutexInit(void *p){ UNUSED_PARAMETER(p); return SQLITE_OK; } static int noopMutexEnd(void *p){ UNUSED_PARAMETER(p); return SQLITE_OK; } static sqlite4_mutex *noopMutexAlloc(sqlite4_env *pEnv, int id){ UNUSED_PARAMETER(pEnv); UNUSED_PARAMETER(id); return (sqlite4_mutex*)8; } static void noopMutexFree(sqlite4_mutex *p){ UNUSED_PARAMETER(p); return; } static void noopMutexEnter(sqlite4_mutex *p){ UNUSED_PARAMETER(p); return; } static int noopMutexTry(sqlite4_mutex *p){ UNUSED_PARAMETER(p); return SQLITE_OK; } static void noopMutexLeave(sqlite4_mutex *p){ UNUSED_PARAMETER(p); return; } sqlite4_mutex_methods const *sqlite4NoopMutex(void){ static const sqlite4_mutex_methods sMutex = { noopMutexInit, noopMutexEnd, noopMutexAlloc, noopMutexFree, noopMutexEnter, noopMutexTry, noopMutexLeave, 0, 0, 0 }; return &sMutex; } #endif /* !SQLITE_DEBUG */ #ifdef SQLITE_DEBUG /* ** In this implementation, error checking is provided for testing ** and debugging purposes. The mutexes still do not provide any ** mutual exclusion. */ /* ** The mutex object */ typedef struct sqlite4DebugMutex { sqlite4_mutex base; /* Base class. Must be first */ sqlite4_env *pEnv; /* Run-time environment */ int id; /* Type of mutex */ int cnt; /* Number of entries without a matching leave */ } sqlite4DebugMutex; /* ** The sqlite4_mutex_held() and sqlite4_mutex_notheld() routine are ** intended for use inside assert() statements. */ static int debugMutexHeld(sqlite4_mutex *pX){ sqlite4DebugMutex *p = (sqlite4DebugMutex*)pX; return p==0 || p->cnt>0; } static int debugMutexNotheld(sqlite4_mutex *pX){ sqlite4DebugMutex *p = (sqlite4DebugMutex*)pX; return p==0 || p->cnt==0; } /* ** Initialize and deinitialize the mutex subsystem. */ static int debugMutexInit(void *p){ UNUSED_PARAMETER(p); return SQLITE_OK; } static int debugMutexEnd(void *p){ UNUSED_PARAMETER(p); return SQLITE_OK; } /* ** The sqlite4_mutex_alloc() routine allocates a new ** mutex and returns a pointer to it. If it returns NULL ** that means that a mutex could not be allocated. */ static sqlite4_mutex *debugMutexAlloc(sqlite4_env *pEnv, int id){ sqlite4DebugMutex *pNew = 0; pNew = sqlite4Malloc(pEnv, sizeof(*pNew)); if( pNew ){ pNew->id = id; pNew->cnt = 0; pNew->pEnv = pEnv; } return (sqlite4_mutex*)pNew; } /* ** This routine deallocates a previously allocated mutex. */ static void debugMutexFree(sqlite4_mutex *pX){ sqlite4DebugMutex *p = (sqlite4DebugMutex*)pX; assert( p->cnt==0 ); sqlite4_free(p->pEnv, p); } /* ** The sqlite4_mutex_enter() and sqlite4_mutex_try() routines attempt ** to enter a mutex. If another thread is already within the mutex, ** sqlite4_mutex_enter() will block and sqlite4_mutex_try() will return ** SQLITE_BUSY. The sqlite4_mutex_try() interface returns SQLITE_OK ** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can ** be entered multiple times by the same thread. In such cases the, ** mutex must be exited an equal number of times before another thread ** can enter. If the same thread tries to enter any other kind of mutex ** more than once, the behavior is undefined. */ static void debugMutexEnter(sqlite4_mutex *pX){ sqlite4DebugMutex *p = (sqlite4DebugMutex*)pX; assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) ); p->cnt++; } static int debugMutexTry(sqlite4_mutex *pX){ sqlite4DebugMutex *p = (sqlite4DebugMutex*)pX; assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) ); p->cnt++; return SQLITE_OK; } /* ** The sqlite4_mutex_leave() routine exits a mutex that was ** previously entered by the same thread. The behavior ** is undefined if the mutex is not currently entered or ** is not currently allocated. SQLite will never do either. */ static void debugMutexLeave(sqlite4_mutex *pX){ sqlite4DebugMutex *p = (sqlite4DebugMutex*)pX; assert( debugMutexHeld(pX) ); p->cnt--; assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) ); } sqlite4_mutex_methods const *sqlite4NoopMutex(void){ static const sqlite4_mutex_methods sMutex = { debugMutexInit, debugMutexEnd, debugMutexAlloc, debugMutexFree, debugMutexEnter, debugMutexTry, debugMutexLeave, debugMutexHeld, debugMutexNotheld, 0 }; return &sMutex; } #endif /* SQLITE_DEBUG */ /* |
︙ | ︙ |
Changes to src/mutex_unix.c.
︙ | ︙ | |||
34 35 36 37 38 39 40 | #else # define SQLITE_MUTEX_NREF 0 #endif /* ** Each recursive mutex is an instance of the following structure. */ | | > | | > | | > | > | | | 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | #else # define SQLITE_MUTEX_NREF 0 #endif /* ** Each recursive mutex is an instance of the following structure. */ typedef struct sqlite4UnixMutex { sqlite4_mutex base; /* Base class. Must be first */ pthread_mutex_t mutex; /* Mutex controlling the lock */ #if SQLITE_MUTEX_NREF int id; /* Mutex type */ volatile int nRef; /* Number of entrances */ volatile pthread_t owner; /* Thread that is within this mutex */ int trace; /* True to trace changes */ #endif } sqlite4UnixMutex; #if SQLITE_MUTEX_NREF #define SQLITE3_MUTEX_INITIALIZER \ { 0, PTHREAD_MUTEX_INITIALIZER, 0, 0, (pthread_t)0, 0 } #else #define SQLITE3_MUTEX_INITIALIZER { 0, PTHREAD_MUTEX_INITIALIZER } #endif /* ** The sqlite4_mutex_held() and sqlite4_mutex_notheld() routine are ** intended for use only inside assert() statements. On some platforms, ** there might be race conditions that can cause these routines to ** deliver incorrect results. In particular, if pthread_equal() is ** not an atomic operation, then these routines might delivery ** incorrect results. On most platforms, pthread_equal() is a ** comparison of two integers and is therefore atomic. But we are ** told that HPUX is not such a platform. If so, then these routines ** will not always work correctly on HPUX. ** ** On those platforms where pthread_equal() is not atomic, SQLite ** should be compiled without -DSQLITE_DEBUG and with -DNDEBUG to ** make sure no assert() statements are evaluated and hence these ** routines are never called. */ #if !defined(NDEBUG) || defined(SQLITE_DEBUG) static int pthreadMutexHeld(sqlite4_mutex *pMutex){ sqlite4UnixMutex *p = (sqlite4UnixMutex*)pMutex; return (p->nRef!=0 && pthread_equal(p->owner, pthread_self())); } static int pthreadMutexNotheld(sqlite4_mutex *pMutex){ sqlite4UnixMutex *p = (sqlite4UnixMutex*)pMutex; return p->nRef==0 || pthread_equal(p->owner, pthread_self())==0; } #endif /* ** Initialize and deinitialize the mutex subsystem. */ static int pthreadMutexInit(void *p){ UNUSED_PARAMETER(p); return SQLITE_OK; } static int pthreadMutexEnd(void *p){ UNUSED_PARAMETER(p); return SQLITE_OK; } /* ** The sqlite4_mutex_alloc() routine allocates a new ** mutex and returns a pointer to it. If it returns NULL ** that means that a mutex could not be allocated. SQLite ** will unwind its stack and return an error. The argument ** to sqlite4_mutex_alloc() is one of these integer constants: |
︙ | ︙ | |||
122 123 124 125 126 127 128 | ** ** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST ** or SQLITE_MUTEX_RECURSIVE) is used then sqlite4_mutex_alloc() ** returns a different mutex on every call. But for the static ** mutex types, the same mutex is returned on every call that has ** the same type number. */ | | | < < < < < < < | | > | > > < < < < | < | | > > > | | > | | 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 | ** ** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST ** or SQLITE_MUTEX_RECURSIVE) is used then sqlite4_mutex_alloc() ** returns a different mutex on every call. But for the static ** mutex types, the same mutex is returned on every call that has ** the same type number. */ static sqlite4_mutex *pthreadMutexAlloc(void *pMutexEnv, int iType){ sqlite4_env *pEnv = (sqlite4_env*)pMutexEnv; sqlite4UnixMutex *p; switch( iType ){ case SQLITE_MUTEX_RECURSIVE: { p = sqlite4MallocZero(pEnv, sizeof(*p) ); if( p ){ #ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX /* If recursive mutexes are not available, we will have to ** build our own. See below. */ pthread_mutex_init(&p->mutex, 0); #else /* Use a recursive mutex if it is available */ pthread_mutexattr_t recursiveAttr; pthread_mutexattr_init(&recursiveAttr); pthread_mutexattr_settype(&recursiveAttr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(&p->mutex, &recursiveAttr); pthread_mutexattr_destroy(&recursiveAttr); #endif #if SQLITE_MUTEX_NREF p->id = iType; #endif p->base.pMutexMethods = &pEnv->mutex; } break; } case SQLITE_MUTEX_FAST: { p = sqlite4MallocZero(pEnv, sizeof(*p) ); if( p ){ #if SQLITE_MUTEX_NREF p->id = iType; #endif pthread_mutex_init(&p->mutex, 0); p->base.pMutexMethods = &pEnv->mutex; assert( p->base.pMutexMethods->pMutexEnv==(void*)pEnv ); } break; } default: { p = 0; break; } } return (sqlite4_mutex*)p; } /* ** This routine deallocates a previously ** allocated mutex. SQLite is careful to deallocate every ** mutex that it allocates. */ static void pthreadMutexFree(sqlite4_mutex *pMutex){ sqlite4UnixMutex *p = (sqlite4UnixMutex*)pMutex; sqlite4_env *pEnv; assert( p->nRef==0 ); assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ); pthread_mutex_destroy(&p->mutex); pEnv = (sqlite4_env*)p->base.pMutexMethods->pMutexEnv; sqlite4_free(pEnv, p); } /* ** The sqlite4_mutex_enter() and sqlite4_mutex_try() routines attempt ** to enter a mutex. If another thread is already within the mutex, ** sqlite4_mutex_enter() will block and sqlite4_mutex_try() will return ** SQLITE_BUSY. The sqlite4_mutex_try() interface returns SQLITE_OK ** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can ** be entered multiple times by the same thread. In such cases the, ** mutex must be exited an equal number of times before another thread ** can enter. If the same thread tries to enter any other kind of mutex ** more than once, the behavior is undefined. */ static void pthreadMutexEnter(sqlite4_mutex *pMutex){ sqlite4UnixMutex *p = (sqlite4UnixMutex*)pMutex; assert( p->id==SQLITE_MUTEX_RECURSIVE || pthreadMutexNotheld(pMutex) ); #ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX /* If recursive mutexes are not available, then we have to grow ** our own. This implementation assumes that pthread_equal() ** is atomic - that it cannot be deceived into thinking self ** and p->owner are equal if p->owner changes between two values ** that are not equal to self while the comparison is taking place. |
︙ | ︙ | |||
243 244 245 246 247 248 249 | #ifdef SQLITE_DEBUG if( p->trace ){ printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); } #endif } | | > | | 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 | #ifdef SQLITE_DEBUG if( p->trace ){ printf("enter mutex %p (%d) with nRef=%d\n", p, p->trace, p->nRef); } #endif } static int pthreadMutexTry(sqlite4_mutex *pMutex){ int rc; sqlite4UnixMutex *p = (sqlite4UnixMutex*)pMutex; assert( p->id==SQLITE_MUTEX_RECURSIVE || pthreadMutexNotheld(pMutex) ); #ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX /* If recursive mutexes are not available, then we have to grow ** our own. This implementation assumes that pthread_equal() ** is atomic - that it cannot be deceived into thinking self ** and p->owner are equal if p->owner changes between two values ** that are not equal to self while the comparison is taking place. |
︙ | ︙ | |||
300 301 302 303 304 305 306 | /* ** The sqlite4_mutex_leave() routine exits a mutex that was ** previously entered by the same thread. The behavior ** is undefined if the mutex is not currently entered or ** is not currently allocated. SQLite will never do either. */ | | > | | 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 | /* ** The sqlite4_mutex_leave() routine exits a mutex that was ** previously entered by the same thread. The behavior ** is undefined if the mutex is not currently entered or ** is not currently allocated. SQLite will never do either. */ static void pthreadMutexLeave(sqlite4_mutex *pMutex){ sqlite4UnixMutex *p = (sqlite4UnixMutex*)pMutex; assert( pthreadMutexHeld(pMutex) ); #if SQLITE_MUTEX_NREF p->nRef--; if( p->nRef==0 ) p->owner = 0; #endif assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE ); #ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX |
︙ | ︙ | |||
334 335 336 337 338 339 340 | pthreadMutexAlloc, pthreadMutexFree, pthreadMutexEnter, pthreadMutexTry, pthreadMutexLeave, #ifdef SQLITE_DEBUG pthreadMutexHeld, | | | > | 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 | pthreadMutexAlloc, pthreadMutexFree, pthreadMutexEnter, pthreadMutexTry, pthreadMutexLeave, #ifdef SQLITE_DEBUG pthreadMutexHeld, pthreadMutexNotheld, #else 0, 0, #endif 0 }; return &sMutex; } #endif /* SQLITE_MUTEX_PTHREADS */ |
Changes to src/os.c.
︙ | ︙ | |||
13 14 15 16 17 18 19 | ** This file contains OS interface code that is common to all ** architectures. */ #define _SQLITE_OS_C_ 1 #include "sqliteInt.h" #undef _SQLITE_OS_C_ | < < | < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | ** This file contains OS interface code that is common to all ** architectures. */ #define _SQLITE_OS_C_ 1 #include "sqliteInt.h" #undef _SQLITE_OS_C_ #if SQLITE_OS_UNIX #include <sys/time.h> #endif /* ** The following variable, if set to a non-zero value, is interpreted as ** the number of seconds since 1970 and is used to set the result of ** sqlite4OsCurrentTime() during testing. */ unsigned int sqlite4_current_time = 0; /* Fake system time */ int sqlite4OsCurrentTime(sqlite4_env *pEnv, sqlite4_uint64 *pTimeOut){ int rc = SQLITE_OK; if( sqlite4_current_time ){ *pTimeOut = (sqlite4_uint64)sqlite4_current_time * 1000; return SQLITE_OK; } #if SQLITE_OS_UNIX static const sqlite4_int64 unixEpoch = 24405875*(sqlite4_int64)8640000; struct timeval sNow; if( gettimeofday(&sNow, 0)==0 ){ *pTimeOut = unixEpoch + 1000*(sqlite4_int64)sNow.tv_sec + sNow.tv_usec/1000; }else{ rc = SQLITE_ERROR; } UNUSED_PARAMETER(pEnv); #endif #if SQLITE_OS_WIN FILETIME ft; static const sqlite4_int64 winFiletimeEpoch = 23058135*(sqlite4_int64)8640000; /* 2^32 - to avoid use of LL and warnings in gcc */ static const sqlite4_int64 max32BitValue = (sqlite4_int64)2000000000 + (sqlite4_int64)2000000000 + (sqlite4_int64)294967296; GetSystemTimeAsFileTime( &ft ); *pTimeOut = winFiletimeEpoch + ((((sqlite4_int64)ft.dwHighDateTime)*max32BitValue) + (sqlite4_int64)ft.dwLowDateTime)/(sqlite4_int64)10000; UNUSED_PARAMETER(pEnv); #endif return rc; } /* ** Write nByte bytes of randomness into zBufOut[]. This is used to initialize ** the PRNGs. nByte will always be 8. */ int sqlite4OsRandomness(sqlite4_env *pEnv, int nByte, unsigned char *zBufOut){ static sqlite4_uint64 cnt = 0; unsigned char *p; int i; sqlite4_uint64 now; sqlite4_uint64 x = 0; #if 0 && SQLITE_OS_UNIX int fd = open("/dev/urandom", O_RDONLY, 0); if( fd>=0 ){ read(fd, zBufOut, nByte); close(fd); } x = getpid(); #endif sqlite4OsCurrentTime(pEnv, &now); x ^= now; memset(zBufOut, 0, nByte); cnt++; x ^= cnt; p = (unsigned char*)&x; for(i=0; i<8; i++) zBufOut[i%nByte] ^= p[i]; return SQLITE_OK; } /* ** This function is a wrapper around the OS specific implementation of ** sqlite4_os_init(). The purpose of the wrapper is to provide the ** ability to simulate a malloc failure, so that the handling of an ** error in sqlite4_os_init() by the upper layers can be tested. */ int sqlite4OsInit(sqlite4_env *pEnv){ void *p = sqlite4_malloc(pEnv, 10); if( p==0 ) return SQLITE_NOMEM; sqlite4_free(pEnv, p); sqlite4OsRandomness(pEnv, 8, (unsigned char*)&pEnv->prngX); return SQLITE_OK; /*sqlite4_os_init();*/ } |
Changes to src/random.c.
︙ | ︙ | |||
14 15 16 17 18 19 20 | ** ** Random numbers are used by some of the database backends in order ** to generate random integer keys for tables or random filenames. */ #include "sqliteInt.h" | < < < < < < < < < | < < < < < < < < < < < < | < | | < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < | | | < < < < < < < < < < < < < < < < < < < < < < | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | ** ** Random numbers are used by some of the database backends in order ** to generate random integer keys for tables or random filenames. */ #include "sqliteInt.h" /* ** Get a single 8-bit random value from the PRNG. The Mutex ** must be held while executing this routine. */ static u8 randomByte(sqlite4_env *pEnv){ pEnv->prngX = (pEnv->prngX>>1) ^ ((-(pEnv->prngX&1)) & 0xd0000001); pEnv->prngY = pEnv->prngY*1103515245 + 12345; return (u8)((pEnv->prngX ^ pEnv->prngY)&0xff); } /* ** Return N random bytes. */ void sqlite4_randomness(sqlite4_env *pEnv, int N, void *pBuf){ unsigned char *zBuf = pBuf; if( pEnv==0 ) pEnv = &sqlite4DefaultEnv; sqlite4_mutex_enter(pEnv->pPrngMutex); while( N-- ){ *(zBuf++) = randomByte(pEnv); } sqlite4_mutex_leave(pEnv->pPrngMutex); } |
Changes to src/shell.c.
︙ | ︙ | |||
2117 2118 2119 2120 2121 2122 2123 | }else if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){ static const struct { const char *zCtrlName; /* Name of a test-control option */ int ctrlCode; /* Integer code for that option */ } aCtrl[] = { | < < < | 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 | }else if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){ static const struct { const char *zCtrlName; /* Name of a test-control option */ int ctrlCode; /* Integer code for that option */ } aCtrl[] = { { "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL }, { "benign_malloc_hooks", SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS }, { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE }, { "assert", SQLITE_TESTCTRL_ASSERT }, { "always", SQLITE_TESTCTRL_ALWAYS }, { "reserve", SQLITE_TESTCTRL_RESERVE }, { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS }, |
︙ | ︙ | |||
2165 2166 2167 2168 2169 2170 2171 | int opt = (int)strtol(azArg[2], 0, 0); rc = sqlite4_test_control(testctrl, p->db, opt); printf("%d (0x%08x)\n", rc, rc); } else { fprintf(stderr,"Error: testctrl %s takes a single int option\n", azArg[1]); } | < < < < < < < < < < < < | 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 | int opt = (int)strtol(azArg[2], 0, 0); rc = sqlite4_test_control(testctrl, p->db, opt); printf("%d (0x%08x)\n", rc, rc); } else { fprintf(stderr,"Error: testctrl %s takes a single int option\n", azArg[1]); } break; /* sqlite4_test_control(int, uint) */ case SQLITE_TESTCTRL_PENDING_BYTE: if( nArg==3 ){ unsigned int opt = (unsigned int)atoi(azArg[2]); rc = sqlite4_test_control(testctrl, opt); |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
119 120 121 122 123 124 125 126 127 128 129 130 131 132 | #define SQLITE_ENVCONFIG_MALLOC 7 /* sqlite4_mem_methods* */ #define SQLITE_ENVCONFIG_GETMALLOC 8 /* sqlite4_mem_methods* */ #define SQLITE_ENVCONFIG_MEMSTATUS 9 /* boolean */ #define SQLITE_ENVCONFIG_LOOKASIDE 10 /* size, count */ #define SQLITE_ENVCONFIG_LOG 11 /* xLog, pArg */ #define SQLITE_ENVCONFIG_KVSTORE_PUSH 12 /* name, factory */ #define SQLITE_ENVCONFIG_KVSTORE_POP 13 /* name */ /* ** CAPIREF: Compile-Time Library Version Numbers ** ** ^(The [SQLITE_VERSION] C preprocessor macro in the sqlite4.h header ** evaluates to a string literal that is the SQLite version in the | > | 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | #define SQLITE_ENVCONFIG_MALLOC 7 /* sqlite4_mem_methods* */ #define SQLITE_ENVCONFIG_GETMALLOC 8 /* sqlite4_mem_methods* */ #define SQLITE_ENVCONFIG_MEMSTATUS 9 /* boolean */ #define SQLITE_ENVCONFIG_LOOKASIDE 10 /* size, count */ #define SQLITE_ENVCONFIG_LOG 11 /* xLog, pArg */ #define SQLITE_ENVCONFIG_KVSTORE_PUSH 12 /* name, factory */ #define SQLITE_ENVCONFIG_KVSTORE_POP 13 /* name */ #define SQLITE_ENVCONFIG_KVSTORE_GET 14 /* name, *factor */ /* ** CAPIREF: Compile-Time Library Version Numbers ** ** ^(The [SQLITE_VERSION] C preprocessor macro in the sqlite4.h header ** evaluates to a string literal that is the SQLite version in the |
︙ | ︙ | |||
531 532 533 534 535 536 537 538 539 540 541 542 543 544 | ** abstract type for a mutex object. The SQLite core never looks ** at the internal representation of an [sqlite4_mutex]. It only ** deals with pointers to the [sqlite4_mutex] object. ** ** Mutexes are created using [sqlite4_mutex_alloc()]. */ typedef struct sqlite4_mutex sqlite4_mutex; /* ** CAPIREF: Initialize The SQLite Library ** ** ^The sqlite4_initialize(A) routine initializes an sqlite4_env object A. ** ^The sqlite4_shutdown(A) routine ** deallocates any resources that were allocated by sqlite4_initialize(A). | > > > > | 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 | ** abstract type for a mutex object. The SQLite core never looks ** at the internal representation of an [sqlite4_mutex]. It only ** deals with pointers to the [sqlite4_mutex] object. ** ** Mutexes are created using [sqlite4_mutex_alloc()]. */ typedef struct sqlite4_mutex sqlite4_mutex; struct sqlite4_mutex { struct sqlite4_mutex_methods *pMutexMethods; /* Subclasses will typically add additional fields */ }; /* ** CAPIREF: Initialize The SQLite Library ** ** ^The sqlite4_initialize(A) routine initializes an sqlite4_env object A. ** ^The sqlite4_shutdown(A) routine ** deallocates any resources that were allocated by sqlite4_initialize(A). |
︙ | ︙ | |||
646 647 648 649 650 651 652 | ** CAPIREF: Memory Allocation Routines ** ** An instance of this object defines the interface between SQLite ** and low-level memory allocation routines. ** ** This object is used in only one place in the SQLite interface. ** A pointer to an instance of this object is the argument to | | | | | 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 | ** CAPIREF: Memory Allocation Routines ** ** An instance of this object defines the interface between SQLite ** and low-level memory allocation routines. ** ** This object is used in only one place in the SQLite interface. ** A pointer to an instance of this object is the argument to ** [sqlite4_env_config()] when the configuration option is ** [SQLITE_ENVCONFIG_MALLOC] or [SQLITE_ENVCONFIG_GETMALLOC]. ** By creating an instance of this object ** and passing it to [sqlite4_env_config]([SQLITE_ENVCONFIG_MALLOC]) ** during configuration, an application can specify an alternative ** memory allocation subsystem for SQLite to use for all of its ** dynamic memory needs. ** ** Note that SQLite comes with several [built-in memory allocators] ** that are perfectly adequate for the overwhelming majority of applications ** and that this object is only useful to a tiny minority of applications |
︙ | ︙ | |||
684 685 686 687 688 689 690 | ** or [sqlite4_realloc()] first calls xRoundup. If xRoundup returns 0, ** that causes the corresponding memory allocation to fail. ** ** The xInit method initializes the memory allocator. (For example, ** it might allocate any require mutexes or initialize internal data ** structures. The xShutdown method is invoked (indirectly) by ** [sqlite4_shutdown()] and should deallocate any resources acquired | | | 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 | ** or [sqlite4_realloc()] first calls xRoundup. If xRoundup returns 0, ** that causes the corresponding memory allocation to fail. ** ** The xInit method initializes the memory allocator. (For example, ** it might allocate any require mutexes or initialize internal data ** structures. The xShutdown method is invoked (indirectly) by ** [sqlite4_shutdown()] and should deallocate any resources acquired ** by xInit. The pMemEnv pointer is used as the only parameter to ** xInit and xShutdown. ** ** SQLite holds the [SQLITE_MUTEX_STATIC_MASTER] mutex when it invokes ** the xInit method, so the xInit method need not be threadsafe. The ** xShutdown method is only called from [sqlite4_shutdown()] so it does ** not need to be threadsafe either. For all other methods, SQLite ** holds the [SQLITE_MUTEX_STATIC_MEM] mutex as long as the |
︙ | ︙ | |||
711 712 713 714 715 716 717 | void (*xFree)(void*,void*); /* Free a prior allocation */ void *(*xRealloc)(void*,void*,int); /* Resize an allocation */ sqlite4_size_t (*xSize)(void*,void*); /* Return the size of an allocation */ int (*xInit)(void*); /* Initialize the memory allocator */ void (*xShutdown)(void*); /* Deinitialize the allocator */ void (*xBeginBenign)(void*); /* Enter a benign malloc region */ void (*xEndBenign)(void*); /* Leave a benign malloc region */ | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 | void (*xFree)(void*,void*); /* Free a prior allocation */ void *(*xRealloc)(void*,void*,int); /* Resize an allocation */ sqlite4_size_t (*xSize)(void*,void*); /* Return the size of an allocation */ int (*xInit)(void*); /* Initialize the memory allocator */ void (*xShutdown)(void*); /* Deinitialize the allocator */ void (*xBeginBenign)(void*); /* Enter a benign malloc region */ void (*xEndBenign)(void*); /* Leave a benign malloc region */ void *pMemEnv; /* 1st argument to all routines */ }; /* ** CAPIREF: Database Connection Configuration Options ** ** These constants are the available integer configuration options that ** can be passed as the second argument to the [sqlite4_db_config()] interface. ** |
︙ | ︙ | |||
3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 | ** of the new function always causes an exception to be thrown. So ** the new function is not good for anything by itself. Its only ** purpose is to be a placeholder function that can be overloaded ** by a [virtual table]. */ int sqlite4_overload_function(sqlite4*, const char *zFuncName, int nArg); /* ** CAPIREF: Mutexes ** ** The SQLite core uses these routines for thread ** synchronization. Though they are intended for internal ** use by SQLite, code that links against SQLite is ** permitted to use any of these routines. | > > > | 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 | ** of the new function always causes an exception to be thrown. So ** the new function is not good for anything by itself. Its only ** purpose is to be a placeholder function that can be overloaded ** by a [virtual table]. */ int sqlite4_overload_function(sqlite4*, const char *zFuncName, int nArg); /* ** /* ** CAPIREF: Mutexes ** ** The SQLite core uses these routines for thread ** synchronization. Though they are intended for internal ** use by SQLite, code that links against SQLite is ** permitted to use any of these routines. |
︙ | ︙ | |||
3715 3716 3717 3718 3719 3720 3721 | ** that means that a mutex could not be allocated. ^SQLite ** will unwind its stack and return an error. ^(The argument ** to sqlite4_mutex_alloc() is one of these integer constants: ** ** <ul> ** <li> SQLITE_MUTEX_FAST ** <li> SQLITE_MUTEX_RECURSIVE | < < < < < < < < | < < < < < < < < < < < < < < < | < < < < | 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 | ** that means that a mutex could not be allocated. ^SQLite ** will unwind its stack and return an error. ^(The argument ** to sqlite4_mutex_alloc() is one of these integer constants: ** ** <ul> ** <li> SQLITE_MUTEX_FAST ** <li> SQLITE_MUTEX_RECURSIVE ** </ul>)^ ** ** ^The new mutex is recursive when SQLITE_MUTEX_RECURSIVE ** is used but not necessarily so when SQLITE_MUTEX_FAST is used. ** The mutex implementation does not need to make a distinction ** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does ** not want to. ^SQLite will only request a recursive mutex in ** cases where it really needs one. ^If a faster non-recursive mutex ** implementation is available on the host platform, the mutex subsystem ** might return such a mutex in response to SQLITE_MUTEX_FAST. ** ** ^The sqlite4_mutex_free() routine deallocates a previously ** allocated mutex. ** ** ^The sqlite4_mutex_enter() and sqlite4_mutex_try() routines attempt ** to enter a mutex. ^If another thread is already within the mutex, ** sqlite4_mutex_enter() will block and sqlite4_mutex_try() will return ** SQLITE_BUSY. ^The sqlite4_mutex_try() interface returns [SQLITE_OK] ** upon successful entry. ^(Mutexes created using ** SQLITE_MUTEX_RECURSIVE can be entered multiple times by the same thread. |
︙ | ︙ | |||
3786 3787 3788 3789 3790 3791 3792 | ** ** ^If the argument to sqlite4_mutex_enter(), sqlite4_mutex_try(), or ** sqlite4_mutex_leave() is a NULL pointer, then all three routines ** behave as no-ops. ** ** See also: [sqlite4_mutex_held()] and [sqlite4_mutex_notheld()]. */ | | | 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 | ** ** ^If the argument to sqlite4_mutex_enter(), sqlite4_mutex_try(), or ** sqlite4_mutex_leave() is a NULL pointer, then all three routines ** behave as no-ops. ** ** See also: [sqlite4_mutex_held()] and [sqlite4_mutex_notheld()]. */ sqlite4_mutex *sqlite4_mutex_alloc(sqlite4_env*, int); void sqlite4_mutex_free(sqlite4_mutex*); void sqlite4_mutex_enter(sqlite4_mutex*); int sqlite4_mutex_try(sqlite4_mutex*); void sqlite4_mutex_leave(sqlite4_mutex*); /* ** CAPIREF: Mutex Methods Object |
︙ | ︙ | |||
3859 3860 3861 3862 3863 3864 3865 | ** ^SQLite will invoke the xMutexEnd() method when [sqlite4_shutdown()] is ** called, but only if the prior call to xMutexInit returned SQLITE_OK. ** If xMutexInit fails in any way, it is expected to clean up after itself ** prior to returning. */ typedef struct sqlite4_mutex_methods sqlite4_mutex_methods; struct sqlite4_mutex_methods { | | | | > | 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 | ** ^SQLite will invoke the xMutexEnd() method when [sqlite4_shutdown()] is ** called, but only if the prior call to xMutexInit returned SQLITE_OK. ** If xMutexInit fails in any way, it is expected to clean up after itself ** prior to returning. */ typedef struct sqlite4_mutex_methods sqlite4_mutex_methods; struct sqlite4_mutex_methods { int (*xMutexInit)(void*); int (*xMutexEnd)(void*); sqlite4_mutex *(*xMutexAlloc)(void*,int); void (*xMutexFree)(sqlite4_mutex *); void (*xMutexEnter)(sqlite4_mutex *); int (*xMutexTry)(sqlite4_mutex *); void (*xMutexLeave)(sqlite4_mutex *); int (*xMutexHeld)(sqlite4_mutex *); int (*xMutexNotheld)(sqlite4_mutex *); void *pMutexEnv; }; /* ** CAPIREF: Mutex Verification Routines ** ** The sqlite4_mutex_held() and sqlite4_mutex_notheld() routines ** are intended for use inside assert() statements. ^The SQLite core |
︙ | ︙ | |||
3916 3917 3918 3919 3920 3921 3922 | ** ** The set of static mutexes may change from one SQLite release to the ** next. Applications that override the built-in mutex logic must be ** prepared to accommodate additional static mutexes. */ #define SQLITE_MUTEX_FAST 0 #define SQLITE_MUTEX_RECURSIVE 1 | < < < < < < < < | 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 | ** ** The set of static mutexes may change from one SQLite release to the ** next. Applications that override the built-in mutex logic must be ** prepared to accommodate additional static mutexes. */ #define SQLITE_MUTEX_FAST 0 #define SQLITE_MUTEX_RECURSIVE 1 /* ** CAPIREF: Retrieve the mutex for a database connection ** ** ^This interface returns a pointer the [sqlite4_mutex] object that ** serializes access to the [database connection] given in the argument ** when the [threading mode] is Serialized. |
︙ | ︙ | |||
4008 4009 4010 4011 4012 4013 4014 | ** as the first argument to [sqlite4_test_control()]. ** ** These parameters and their meanings are subject to change ** without notice. These values are for testing purposes only. ** Applications should not use any of these parameters or the ** [sqlite4_test_control()] interface. */ | | < < < | | | | | | | | | | | | 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 | ** as the first argument to [sqlite4_test_control()]. ** ** These parameters and their meanings are subject to change ** without notice. These values are for testing purposes only. ** Applications should not use any of these parameters or the ** [sqlite4_test_control()] interface. */ #define SQLITE_TESTCTRL_FIRST 1 #define SQLITE_TESTCTRL_FAULT_INSTALL 2 #define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 3 #define SQLITE_TESTCTRL_PENDING_BYTE 4 #define SQLITE_TESTCTRL_ASSERT 5 #define SQLITE_TESTCTRL_ALWAYS 6 #define SQLITE_TESTCTRL_RESERVE 7 #define SQLITE_TESTCTRL_OPTIMIZATIONS 8 #define SQLITE_TESTCTRL_ISKEYWORD 9 #define SQLITE_TESTCTRL_LOCALTIME_FAULT 10 #define SQLITE_TESTCTRL_EXPLAIN_STMT 11 #define SQLITE_TESTCTRL_LAST 11 /* ** CAPIREF: SQLite Runtime Status ** ** ^This interface is used to retrieve runtime status information ** about the performance of SQLite, and optionally to reset various ** highwater marks. ^The first argument is an integer code for |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
2409 2410 2411 2412 2413 2414 2415 | int (*xKVFile)(sqlite4_env*, KVStore**, const char*, unsigned int); int (*xKVTmp)(sqlite4_env*, KVStore**, const char*, unsigned int); int (*xRandomness)(sqlite4_env*, int, unsigned char*); int (*xCurrentTime)(sqlite4_env*, sqlite4_uint64*); /* The above might be initialized to non-zero. The following need to always ** initially be zero, however. */ int isInit; /* True after initialization has finished */ | < < < | | > > | 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 | int (*xKVFile)(sqlite4_env*, KVStore**, const char*, unsigned int); int (*xKVTmp)(sqlite4_env*, KVStore**, const char*, unsigned int); int (*xRandomness)(sqlite4_env*, int, unsigned char*); int (*xCurrentTime)(sqlite4_env*, sqlite4_uint64*); /* The above might be initialized to non-zero. The following need to always ** initially be zero, however. */ int isInit; /* True after initialization has finished */ sqlite4_mutex *pPrngMutex; /* Mutex for the PRNG */ u32 prngX, prngY; /* State of the PRNG */ void (*xLog)(void*,int,const char*); /* Function for logging */ void *pLogArg; /* First argument to xLog() */ int bLocaltimeFault; /* True to fail localtime() calls */ sqlite4_mutex *pMemMutex; /* Mutex for nowValue[] and mxValue[] */ sqlite4_uint64 nowValue[4]; /* sqlite4_env_status() current values */ sqlite4_uint64 mxValue[4]; /* sqlite4_env_status() max values */ FuncDefHash hashGlobalFuncs; /* Hash table of global functions */ }; /* ** Context pointer passed down through the tree-walk. */ struct Walker { int (*xExprCallback)(Walker*, Expr*); /* Callback for expressions */ |
︙ | ︙ | |||
2568 2569 2570 2571 2572 2573 2574 | const sqlite4_mem_methods *sqlite4MemGetMemsys5(void); #endif #ifndef SQLITE_MUTEX_OMIT sqlite4_mutex_methods const *sqlite4DefaultMutex(void); sqlite4_mutex_methods const *sqlite4NoopMutex(void); | | | | | 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 | const sqlite4_mem_methods *sqlite4MemGetMemsys5(void); #endif #ifndef SQLITE_MUTEX_OMIT sqlite4_mutex_methods const *sqlite4DefaultMutex(void); sqlite4_mutex_methods const *sqlite4NoopMutex(void); sqlite4_mutex *sqlite4MutexAlloc(sqlite4_env*,int); int sqlite4MutexInit(sqlite4_env*); int sqlite4MutexEnd(sqlite4_env*); #endif void sqlite4StatusAdd(sqlite4_env*, int, sqlite4_int64); void sqlite4StatusSet(sqlite4_env*, int, sqlite4_uint64); #ifndef SQLITE_OMIT_FLOATING_POINT int sqlite4IsNaN(double); |
︙ | ︙ | |||
2955 2956 2957 2958 2959 2960 2961 | extern SQLITE_WSD FuncDefHash sqlite4GlobalFunctions; #ifndef SQLITE_OMIT_WSD extern int sqlite4PendingByte; #endif #endif void sqlite4RootPageMoved(sqlite4*, int, int, int); void sqlite4Reindex(Parse*, Token*, Token*); | | | 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 | extern SQLITE_WSD FuncDefHash sqlite4GlobalFunctions; #ifndef SQLITE_OMIT_WSD extern int sqlite4PendingByte; #endif #endif void sqlite4RootPageMoved(sqlite4*, int, int, int); void sqlite4Reindex(Parse*, Token*, Token*); void sqlite4AlterFunctions(sqlite4_env*); void sqlite4AlterRenameTable(Parse*, SrcList*, Token*); int sqlite4GetToken(const unsigned char *, int *); void sqlite4NestedParse(Parse*, const char*, ...); void sqlite4ExpirePreparedStatements(sqlite4*); int sqlite4CodeSubselect(Parse *, Expr *, int, int); void sqlite4SelectPrep(Parse*, Select*, NameContext*); int sqlite4ResolveExprNames(NameContext*, Expr*); |
︙ | ︙ | |||
3194 3195 3196 3197 3198 3199 3200 | ** this constraint. ** ** All of this is no-op for a production build. It only comes into ** play when the SQLITE_MEMDEBUG compile-time option is used. */ #ifdef SQLITE_MEMDEBUG void sqlite4MemdebugSetType(void*,u8); | | | | 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 | ** this constraint. ** ** All of this is no-op for a production build. It only comes into ** play when the SQLITE_MEMDEBUG compile-time option is used. */ #ifdef SQLITE_MEMDEBUG void sqlite4MemdebugSetType(void*,u8); int sqlite4MemdebugHasType(const void*,u8); int sqlite4MemdebugNoType(const void*,u8); #else # define sqlite4MemdebugSetType(X,Y) /* no-op */ # define sqlite4MemdebugHasType(X,Y) 1 # define sqlite4MemdebugNoType(X,Y) 1 #endif #define MEMTYPE_HEAP 0x01 /* General heap allocations */ #define MEMTYPE_LOOKASIDE 0x02 /* Might have been lookaside memory */ #define MEMTYPE_SCRATCH 0x04 /* Scratch allocations */ #define MEMTYPE_DB 0x10 /* Uses sqlite4DbMalloc, not sqlite_malloc */ #endif /* _SQLITEINT_H_ */ |
Changes to src/vdbeapi.c.
︙ | ︙ | |||
191 192 193 194 195 196 197 198 199 200 201 202 203 204 | static void setResultStrOrError( sqlite4_context *pCtx, /* Function context */ const char *z, /* String pointer */ int n, /* Bytes in string, or negative */ u8 enc, /* Encoding of z. 0 for BLOBs */ void (*xDel)(void*) /* Destructor function */ ){ if( sqlite4VdbeMemSetStr(&pCtx->s, z, n, enc, xDel)==SQLITE_TOOBIG ){ sqlite4_result_error_toobig(pCtx); } } void sqlite4_result_blob( sqlite4_context *pCtx, const void *z, | > > > > > | 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | static void setResultStrOrError( sqlite4_context *pCtx, /* Function context */ const char *z, /* String pointer */ int n, /* Bytes in string, or negative */ u8 enc, /* Encoding of z. 0 for BLOBs */ void (*xDel)(void*) /* Destructor function */ ){ if( xDel==SQLITE_DYNAMIC ){ assert( sqlite4MemdebugHasType(z, MEMTYPE_HEAP) ); assert( sqlite4MemdebugNoType(z, ~MEMTYPE_HEAP) ); sqlite4MemdebugSetType(z, MEMTYPE_DB | MEMTYPE_HEAP); } if( sqlite4VdbeMemSetStr(&pCtx->s, z, n, enc, xDel)==SQLITE_TOOBIG ){ sqlite4_result_error_toobig(pCtx); } } void sqlite4_result_blob( sqlite4_context *pCtx, const void *z, |
︙ | ︙ |
Changes to test/log1.test.
︙ | ︙ | |||
434 435 436 437 438 439 440 441 442 443 444 445 446 447 | copy_db_files test.db test.db2 sqlite4 db2 test.db2 execsql { SELECT count(*) FROM t1 ; PRAGMA integrity_check } db2 } {21 ok} db2 close do_test 11.21 { sqlite4_lsm_work db main -flush } {0} do_execsql_test 11.22 { INSERT INTO t1 VALUES(randstr(10,10), randstr(100,100)); } do_test 11.23 { sqlite4_lsm_info db main log-structure } {1335 1482 0 1259 1483 1908} do_test 11.24 { sqlite4_lsm_work db main -checkpoint } {0} | > | 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 | copy_db_files test.db test.db2 sqlite4 db2 test.db2 execsql { SELECT count(*) FROM t1 ; PRAGMA integrity_check } db2 } {21 ok} db2 close do_test 11.21 { sqlite4_lsm_work db main -flush } {0} db eval {SELECT randstr(5,5)} do_execsql_test 11.22 { INSERT INTO t1 VALUES(randstr(10,10), randstr(100,100)); } do_test 11.23 { sqlite4_lsm_info db main log-structure } {1335 1482 0 1259 1483 1908} do_test 11.24 { sqlite4_lsm_work db main -checkpoint } {0} |
︙ | ︙ |
Changes to test/test_main.c.
︙ | ︙ | |||
3969 3970 3971 3972 3973 3974 3975 | } if( Tcl_GetIntFromObj(interp, objv[3], &val) ) return TCL_ERROR; rc = sqlite4_limit(db, id, val); Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); return TCL_OK; } | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 | } if( Tcl_GetIntFromObj(interp, objv[3], &val) ) return TCL_ERROR; rc = sqlite4_limit(db, id, val); Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); return TCL_OK; } #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY static void test_unlock_notify_cb(void **aArg, int nArg){ int ii; for(ii=0; ii<nArg; ii++){ Tcl_EvalEx((Tcl_Interp *)aArg[ii], "unlock_notify", -1, TCL_EVAL_GLOBAL); } |
︙ | ︙ | |||
4503 4504 4505 4506 4507 4508 4509 | { "sqlite4_stmt_busy", test_stmt_busy ,0 }, { "uses_stmt_journal", uses_stmt_journal ,0 }, { "sqlite4_db_release_memory", test_db_release_memory, 0}, { "sqlite4_limit", test_limit, 0}, | < < < | 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 | { "sqlite4_stmt_busy", test_stmt_busy ,0 }, { "uses_stmt_journal", uses_stmt_journal ,0 }, { "sqlite4_db_release_memory", test_db_release_memory, 0}, { "sqlite4_limit", test_limit, 0}, { "optimization_control", optimization_control,0}, #if SQLITE_OS_WIN { "lock_win32_file", win32_file_lock, 0 }, #endif { "tcl_objproc", runAsObjProc, 0 }, /* sqlite4_column_*() API */ |
︙ | ︙ |
Changes to test/test_malloc.c.
︙ | ︙ | |||
71 72 73 74 75 76 77 | ** A version of sqlite4_mem_methods.xMalloc() that includes fault simulation ** logic. */ static void *faultsimMalloc(void *pMem, sqlite4_size_t n){ void *p = 0; assert( pMem==(void*)&memfault ); if( !faultsimStep() ){ | | | | | | | | 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | ** A version of sqlite4_mem_methods.xMalloc() that includes fault simulation ** logic. */ static void *faultsimMalloc(void *pMem, sqlite4_size_t n){ void *p = 0; assert( pMem==(void*)&memfault ); if( !faultsimStep() ){ p = memfault.m.xMalloc(memfault.m.pMemEnv, n); } return p; } /* ** A version of sqlite4_mem_methods.xRealloc() that includes fault simulation ** logic. */ static void *faultsimRealloc(void *pMem, void *pOld, sqlite4_size_t n){ void *p = 0; assert( pMem==(void*)&memfault ); if( !faultsimStep() ){ p = memfault.m.xRealloc(memfault.m.pMemEnv, pOld, n); } return p; } /* ** The following method calls are passed directly through to the underlying ** malloc system: ** ** xFree ** xSize ** xInit ** xShutdown */ static void faultsimFree(void *pMem, void *p){ assert( pMem==(void*)&memfault ); memfault.m.xFree(memfault.m.pMemEnv, p); } static sqlite4_size_t faultsimSize(void *pMem, void *p){ assert( pMem==(void*)&memfault ); return memfault.m.xSize(memfault.m.pMemEnv, p); } static int faultsimInit(void *pMem){ return memfault.m.xInit(memfault.m.pMemEnv); } static void faultsimShutdown(void *pMem){ memfault.m.xShutdown(memfault.m.pMemEnv); } /* ** This routine configures the malloc failure simulation. After ** calling this routine, the next nDelay mallocs will succeed, followed ** by a block of nRepeat failures, after which malloc() calls will begin ** to succeed again. |
︙ | ︙ | |||
187 188 189 190 191 192 193 | faultsimFree, /* xFree */ faultsimRealloc, /* xRealloc */ faultsimSize, /* xSize */ faultsimInit, /* xInit */ faultsimShutdown, /* xShutdown */ faultsimBeginBenign, /* xBeginBenign */ faultsimEndBenign, /* xEndBenign */ | | | 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 | faultsimFree, /* xFree */ faultsimRealloc, /* xRealloc */ faultsimSize, /* xSize */ faultsimInit, /* xInit */ faultsimShutdown, /* xShutdown */ faultsimBeginBenign, /* xBeginBenign */ faultsimEndBenign, /* xEndBenign */ (void*)&memfault /* pMemEnv */ }; int rc; install = (install ? 1 : 0); assert(memfault.isInstalled==1 || memfault.isInstalled==0); if( install==memfault.isInstalled ){ |
︙ | ︙ |
Changes to test/test_mutex.c.
︙ | ︙ | |||
19 20 21 22 23 24 25 | #include <assert.h> #include <string.h> /* defined in test1.c */ const char *sqlite4TestErrorName(int); /* A countable mutex */ | | > < > < | > | > | | | | | | | < < | < < < < | | > | > | > | > | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | #include <assert.h> #include <string.h> /* defined in test1.c */ const char *sqlite4TestErrorName(int); /* A countable mutex */ typedef struct sqlite4CounterMutex { sqlite4_mutex base; /* Base class. Must be first */ sqlite4_mutex *pReal; int eType; } sqlite4CounterMutex; /* State variables */ static struct test_mutex_globals { int isInstalled; /* True if installed */ int disableInit; /* True to cause sqlite4_initalize() to fail */ int disableTry; /* True to force sqlite4_mutex_try() to fail */ int isInit; /* True if initialized */ sqlite4_mutex_methods m; /* Interface to "real" mutex system */ int aCounter[8]; /* Number of grabs of each type of mutex */ } g = {0}; /* Return true if the countable mutex is currently held */ static int counterMutexHeld(sqlite4_mutex *pMutex){ sqlite4CounterMutex *p = (sqlite4CounterMutex*)pMutex; return g.m.xMutexHeld(p->pReal); } /* Return true if the countable mutex is not currently held */ static int counterMutexNotheld(sqlite4_mutex *pMutex){ sqlite4CounterMutex *p = (sqlite4CounterMutex*)pMutex; 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 *p){ int rc; if( g.disableInit ) return g.disableInit; rc = g.m.xMutexInit(p); g.isInit = 1; return rc; } /* ** Uninitialize the mutex subsystem */ static int counterMutexEnd(void *p){ g.isInit = 0; return g.m.xMutexEnd(p); } /* ** Allocate a countable mutex */ static sqlite4_mutex *counterMutexAlloc(void *pMutexEnv, int eType){ sqlite4_mutex *pReal; sqlite4CounterMutex *pRet = 0; assert( g.isInit ); assert(eType<8 && eType>=0); pReal = g.m.xMutexAlloc(g.m.pMutexEnv, eType); if( !pReal ) return 0; pRet = (sqlite4CounterMutex *)malloc(sizeof(*pRet)); pRet->eType = eType; pRet->pReal = pReal; return (sqlite4_mutex*)pRet; } /* ** Free a countable mutex */ static void counterMutexFree(sqlite4_mutex *pMutex){ sqlite4CounterMutex *p = (sqlite4CounterMutex*)pMutex; assert( g.isInit ); g.m.xMutexFree(p->pReal); if( p->eType==SQLITE_MUTEX_FAST || p->eType==SQLITE_MUTEX_RECURSIVE ){ free(p); } } /* ** Enter a countable mutex. Block until entry is safe. */ static void counterMutexEnter(sqlite4_mutex *pMutex){ sqlite4CounterMutex *p = (sqlite4CounterMutex*)pMutex; assert( g.isInit ); g.aCounter[p->eType]++; g.m.xMutexEnter(p->pReal); } /* ** Try to enter a mutex. Return true on success. */ static int counterMutexTry(sqlite4_mutex *pMutex){ sqlite4CounterMutex *p = (sqlite4CounterMutex*)pMutex; assert( g.isInit ); g.aCounter[p->eType]++; if( g.disableTry ) return SQLITE_BUSY; return g.m.xMutexTry(p->pReal); } /* Leave a mutex */ static void counterMutexLeave(sqlite4_mutex *pMutex){ sqlite4CounterMutex *p = (sqlite4CounterMutex*)pMutex; assert( g.isInit ); g.m.xMutexLeave(p->pReal); } /* ** sqlite4_shutdown */ |
︙ | ︙ | |||
190 191 192 193 194 195 196 | counterMutexEnd, counterMutexAlloc, counterMutexFree, counterMutexEnter, counterMutexTry, counterMutexLeave, counterMutexHeld, | | > | 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 | counterMutexEnd, counterMutexAlloc, counterMutexFree, counterMutexEnter, counterMutexTry, counterMutexLeave, counterMutexHeld, counterMutexNotheld, 0 }; if( objc!=2 ){ Tcl_WrongNumArgs(interp, 1, objv, "BOOLEAN"); return TCL_ERROR; } if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[1], &isInstall) ){ |
︙ | ︙ | |||
297 298 299 300 301 302 303 | static int test_alloc_mutex( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ #if SQLITE_THREADSAFE | | | 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 | static int test_alloc_mutex( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ #if SQLITE_THREADSAFE sqlite4_mutex *p = sqlite4_mutex_alloc(0, SQLITE_MUTEX_FAST); char zBuf[100]; sqlite4_mutex_free(p); sqlite4_snprintf(zBuf, sizeof(zBuf), "%p", p); Tcl_AppendResult(interp, zBuf, (char*)0); #endif return TCL_OK; } |
︙ | ︙ |
Changes to test/test_storage2.c.
︙ | ︙ | |||
285 286 287 288 289 290 291 | static int kvwrap_install_cmd(Tcl_Interp *interp, int objc, Tcl_Obj **objv){ if( objc!=2 ){ Tcl_WrongNumArgs(interp, 2, objv, ""); return TCL_ERROR; } if( kvwg.xFactory==0 ){ | | | | 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 | static int kvwrap_install_cmd(Tcl_Interp *interp, int objc, Tcl_Obj **objv){ if( objc!=2 ){ Tcl_WrongNumArgs(interp, 2, objv, ""); return TCL_ERROR; } if( kvwg.xFactory==0 ){ sqlite4_env_config(0, SQLITE_ENVCONFIG_KVSTORE_GET, "main", &kvwg.xFactory); sqlite4_env_config(0, SQLITE_ENVCONFIG_KVSTORE_PUSH, "main",newFileStorage); } return TCL_OK; } static int kvwrap_seek_cmd(Tcl_Interp *interp, int objc, Tcl_Obj **objv){ if( objc!=2 ){ Tcl_WrongNumArgs(interp, 2, objv, ""); |
︙ | ︙ |
Changes to test/tester.tcl.
︙ | ︙ | |||
1034 1035 1036 1037 1038 1039 1040 | # TEMPORARY: For 3.5.9, disable testing of extended result codes. There are # a couple of obscure IO errors that do not return them. set ::ioerropts(-erc) 0 set ::go 1 #reset_prng_state | | | 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 | # TEMPORARY: For 3.5.9, disable testing of extended result codes. There are # a couple of obscure IO errors that do not return them. set ::ioerropts(-erc) 0 set ::go 1 #reset_prng_state #save_prng_state for {set n $::ioerropts(-start)} {$::go} {incr n} { set ::TN $n incr ::ioerropts(-count) -1 if {$::ioerropts(-count)<0} break # Skip this IO error if it was specified with the "-exclude" option. if {[info exists ::ioerropts(-exclude)]} { |
︙ | ︙ | |||
1457 1458 1459 1460 1461 1462 1463 | if {$tail != $::G(start:file) && $tail!="$::G(start:file).test"} return unset ::G(start:file) } # Run the test script in a slave interpreter. # unset -nocomplain ::run_thread_tests_called | | | 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 | if {$tail != $::G(start:file) && $tail!="$::G(start:file).test"} return unset ::G(start:file) } # Run the test script in a slave interpreter. # unset -nocomplain ::run_thread_tests_called #reset_prng_state set time [time { slave_test_script [list source $zFile] }] set ms [expr [lindex $time 0] / 1000] # Add some info to the output. # puts "Time: $tail $ms ms" show_memstats |
︙ | ︙ |
Changes to test/where.test.
︙ | ︙ | |||
12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # focus of this file is testing the use of indices in WHERE clases. # # $Id: where.test,v 1.50 2008/11/03 09:06:06 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Build some test data # do_test where-1.0 { execsql { CREATE TABLE t1(w int, x int, y int); CREATE TABLE t2(p int, q int, r int, s int); } | > > > > | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | # focus of this file is testing the use of indices in WHERE clases. # # $Id: where.test,v 1.50 2008/11/03 09:06:06 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl db close kvwrap install sqlite4 db test.db # Build some test data # do_test where-1.0 { execsql { CREATE TABLE t1(w int, x int, y int); CREATE TABLE t2(p int, q int, r int, s int); } |
︙ | ︙ |