Adding more thread locking code. This is an incremental check-in. (CVS 4262)

FossilOrigin-Name: 7428732b1fa04b83eda0a3539834693ef351313e
This commit is contained in:
drh 2007-08-21 16:15:55 +00:00
parent 605264d2d8
commit e30f442622
5 changed files with 195 additions and 136 deletions

View File

@ -1,5 +1,5 @@
C Readded\sthe\ssqlite3_open_v2()\sinterface.\s\sNo\stest\scases\syet.\nAdditional\sprogress\stoward\sadding\smutexes\sto\sall\sinterfaces.\s(CVS\s4261)
D 2007-08-21T15:13:19
C Adding\smore\sthread\slocking\scode.\s\sThis\sis\san\sincremental\scheck-in.\s(CVS\s4262)
D 2007-08-21T16:15:56
F Makefile.in 0c0e53720f658c7a551046442dd7afba0b72bfbe
F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@ -97,7 +97,7 @@ F src/insert.c 633322aef1799f6604fa805e12488bc628570b0c
F src/legacy.c a83519a8fbb488c3155fca577b010d590ec479e9
F src/limits.h 71ab25f17e35e0a9f3f6f234b8ed49cc56731d35
F src/loadext.c 780748f3f55a3b5af6ed0adfd58035f728cde4ca
F src/main.c 5f6ab3380477a7f134f7c664e3fdcdbf12a3d9dc
F src/main.c 1f6f46975182c589c4942c708c9821db7c5d5772
F src/malloc.c c2f5da620d8e030c6974a0ddcaeb7b408c9bdb3d
F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217
F src/mem1.c 30bf8be3846f92fdf88c490c5e5378512383bcbe
@ -124,7 +124,7 @@ F src/random.c 4a22746501bf36b0a088c66e38dde5daba6a35da
F src/select.c 98c367bce3f38c5adfcc97de9ab5c79b0e5dc2b2
F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
F src/shell.c ac29402b538515fa4697282387be9c1205e6e9eb
F src/sqlite.h.in 62a2cb5d0ce867e206a0b5465dedd5dfd941cc37
F src/sqlite.h.in c691ae04f7c064d853710a1eff4707549a54e1f8
F src/sqlite3ext.h 647a6b8a8f76ff6c9611e4a071531d8e63ff2d6b
F src/sqliteInt.h c9ba3861d1e8835caeb0c89fca7cddd12779e1ac
F src/sqliteLimit.h f14609c27636ebc217c9603ade26dbdd7d0f6afa
@ -159,7 +159,7 @@ F src/vacuum.c 318ccae7c4e3ddf241aeaee4d2611bfe1949a373
F src/vdbe.c f1a9a29da48ccfa49042df478abb478520589f37
F src/vdbe.h 001c5b257567c1d3de7feb2203aac71d0d7b16a3
F src/vdbeInt.h 8e360d326328e7a66100f468697edf9cfb4567dc
F src/vdbeapi.c 16268e7a2614051c9c7f93679d9102b03206c129
F src/vdbeapi.c b4a1f4d56906a43f40c2bc47d7b142db3759c14e
F src/vdbeaux.c 14b48bfc6334682e5e5858a0835f8b00d8751953
F src/vdbeblob.c ac223e6d3acaa3321ce09c11c47bf0d05b37372f
F src/vdbefifo.c 334c838c8f42d61a94813d136019ee566b5dc2f6
@ -558,7 +558,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
P 3fb97a63ef70662abdba18ce8b480e6b0badcfb1
R ebd0701e4b840e7f444fe74a84efea35
P 3787563e90d7210d349ee36484c3f008c955552e
R 059b95f5c37a602e37abf433f570fd9a
U drh
Z 4a9c7281bbaf4cab164c43383497e97b
Z da09ba003aea60219dd1a004da17c3aa

View File

@ -1 +1 @@
3787563e90d7210d349ee36484c3f008c955552e
7428732b1fa04b83eda0a3539834693ef351313e

View File

@ -14,7 +14,7 @@
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.391 2007/08/21 15:13:19 drh Exp $
** $Id: main.c,v 1.392 2007/08/21 16:15:56 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
@ -231,6 +231,7 @@ int sqlite3_close(sqlite3 *db){
void sqlite3RollbackAll(sqlite3 *db){
int i;
int inTrans = 0;
assert( sqlite3_mutex_held(db->mutex) );
for(i=0; i<db->nDb; i++){
if( db->aDb[i].pBt ){
if( sqlite3BtreeIsInTrans(db->aDb[i].pBt) ){
@ -366,9 +367,11 @@ int sqlite3_busy_handler(
if( sqlite3SafetyCheck(db) ){
return SQLITE_MISUSE;
}
sqlite3_mutex_enter(db->mutex);
db->busyHandler.xFunc = xBusy;
db->busyHandler.pArg = pArg;
db->busyHandler.nBusy = 0;
sqlite3_mutex_leave(db->mutex);
return SQLITE_OK;
}
@ -385,6 +388,7 @@ void sqlite3_progress_handler(
void *pArg
){
if( !sqlite3SafetyCheck(db) ){
sqlite3_mutex_enter(db->mutex);
if( nOps>0 ){
db->xProgress = xProgress;
db->nProgressOps = nOps;
@ -394,6 +398,7 @@ void sqlite3_progress_handler(
db->nProgressOps = 0;
db->pProgressArg = 0;
}
sqlite3_mutex_leave(db->mutex);
}
}
#endif
@ -445,6 +450,7 @@ int sqlite3CreateFunc(
FuncDef *p;
int nName;
assert( sqlite3_mutex_held(db->mutex) );
if( sqlite3SafetyCheck(db) ){
return SQLITE_MISUSE;
}
@ -472,10 +478,13 @@ int sqlite3CreateFunc(
int rc;
rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF8,
pUserData, xFunc, xStep, xFinal);
if( rc!=SQLITE_OK ) return rc;
rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF16LE,
pUserData, xFunc, xStep, xFinal);
if( rc!=SQLITE_OK ) return rc;
if( rc==SQLITE_OK ){
rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF16LE,
pUserData, xFunc, xStep, xFinal);
}
if( rc!=SQLITE_OK ){
return rc;
}
enc = SQLITE_UTF16BE;
}
#else
@ -525,10 +534,12 @@ int sqlite3_create_function(
void (*xFinal)(sqlite3_context*)
){
int rc;
sqlite3_mutex_enter(db->mutex);
assert( !db->mallocFailed );
rc = sqlite3CreateFunc(db, zFunctionName, nArg, enc, p, xFunc, xStep, xFinal);
return sqlite3ApiExit(db, rc);
rc = sqlite3ApiExit(db, rc);
sqlite3_mutex_leave(db->mutex);
return rc;
}
#ifndef SQLITE_OMIT_UTF16
@ -544,13 +555,14 @@ int sqlite3_create_function16(
){
int rc;
char *zFunc8;
sqlite3_mutex_enter(db->mutex);
assert( !db->mallocFailed );
zFunc8 = sqlite3Utf16to8(db, zFunctionName, -1);
rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xFunc, xStep, xFinal);
sqlite3_free(zFunc8);
return sqlite3ApiExit(db, rc);
rc = sqlite3ApiExit(db, rc);
sqlite3_mutex_leave(db->mutex);
return rc;
}
#endif
@ -573,11 +585,15 @@ int sqlite3_overload_function(
int nArg
){
int nName = strlen(zName);
int rc;
sqlite3_mutex_enter(db->mutex);
if( sqlite3FindFunction(db, zName, nName, nArg, SQLITE_UTF8, 0)==0 ){
sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8,
0, sqlite3InvalidFunction, 0, 0);
}
return sqlite3ApiExit(db, SQLITE_OK);
rc = sqlite3ApiExit(db, SQLITE_OK);
sqlite3_mutex_leave(db->mutex);
return rc;
}
#ifndef SQLITE_OMIT_TRACE
@ -590,9 +606,12 @@ int sqlite3_overload_function(
** SQL statement.
*/
void *sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){
void *pOld = db->pTraceArg;
void *pOld;
sqlite3_mutex_enter(db->mutex);
pOld = db->pTraceArg;
db->xTrace = xTrace;
db->pTraceArg = pArg;
sqlite3_mutex_leave(db->mutex);
return pOld;
}
/*
@ -608,9 +627,12 @@ void *sqlite3_profile(
void (*xProfile)(void*,const char*,sqlite_uint64),
void *pArg
){
void *pOld = db->pProfileArg;
void *pOld;
sqlite3_mutex_enter(db->mutex);
pOld = db->pProfileArg;
db->xProfile = xProfile;
db->pProfileArg = pArg;
sqlite3_mutex_leave(db->mutex);
return pOld;
}
#endif /* SQLITE_OMIT_TRACE */
@ -626,9 +648,12 @@ void *sqlite3_commit_hook(
int (*xCallback)(void*), /* Function to invoke on each commit */
void *pArg /* Argument to the function */
){
void *pOld = db->pCommitArg;
void *pOld;
sqlite3_mutex_enter(db->mutex);
pOld = db->pCommitArg;
db->xCommitCallback = xCallback;
db->pCommitArg = pArg;
sqlite3_mutex_leave(db->mutex);
return pOld;
}
@ -641,9 +666,12 @@ void *sqlite3_update_hook(
void (*xCallback)(void*,int,char const *,char const *,sqlite_int64),
void *pArg /* Argument to the function */
){
void *pRet = db->pUpdateArg;
void *pRet;
sqlite3_mutex_enter(db->mutex);
pRet = db->pUpdateArg;
db->xUpdateCallback = xCallback;
db->pUpdateArg = pArg;
sqlite3_mutex_leave(db->mutex);
return pRet;
}
@ -656,9 +684,12 @@ void *sqlite3_rollback_hook(
void (*xCallback)(void*), /* Callback function */
void *pArg /* Argument to the function */
){
void *pRet = db->pRollbackArg;
void *pRet;
sqlite3_mutex_enter(db->mutex);
pRet = db->pRollbackArg;
db->xRollbackCallback = xCallback;
db->pRollbackArg = pArg;
sqlite3_mutex_leave(db->mutex);
return pRet;
}
@ -697,6 +728,7 @@ int sqlite3BtreeFactory(
int btree_flags = 0;
int rc;
assert( sqlite3_mutex_held(db->mutex) );
assert( ppBtree != 0);
if( omitJournal ){
btree_flags |= BTREE_OMIT_JOURNAL;
@ -738,6 +770,7 @@ const char *sqlite3_errmsg(sqlite3 *db){
if( !db ){
return sqlite3ErrStr(SQLITE_NOMEM);
}
sqlite3_mutex_enter(db->mutex);
assert( !db->mallocFailed );
if( sqlite3SafetyCheck(db) || db->errCode==SQLITE_MISUSE ){
return sqlite3ErrStr(SQLITE_MISUSE);
@ -746,6 +779,7 @@ const char *sqlite3_errmsg(sqlite3 *db){
if( z==0 ){
z = sqlite3ErrStr(db->errCode);
}
sqlite3_mutex_leave(db->mutex);
return z;
}
@ -775,13 +809,14 @@ const void *sqlite3_errmsg16(sqlite3 *db){
};
const void *z;
assert( !db->mallocFailed );
if( !db ){
return (void *)(&outOfMemBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]);
}
if( sqlite3SafetyCheck(db) || db->errCode==SQLITE_MISUSE ){
return (void *)(&misuseBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]);
}
sqlite3_mutex_enter(db->mutex);
assert( !db->mallocFailed );
z = sqlite3_value_text16(db->pErr);
if( z==0 ){
sqlite3ValueSetStr(db, db->pErr, -1, sqlite3ErrStr(db->errCode),
@ -789,6 +824,7 @@ const void *sqlite3_errmsg16(sqlite3 *db){
z = sqlite3_value_text16(db->pErr);
}
sqlite3ApiExit(0, 0);
sqlite3_mutex_leave(db->mutex);
return z;
}
#endif /* SQLITE_OMIT_UTF16 */
@ -825,6 +861,7 @@ static int createCollation(
if( sqlite3SafetyCheck(db) ){
return SQLITE_MISUSE;
}
assert( sqlite3_mutex_held(db->mutex) );
/* If SQLITE_UTF16 is specified as the encoding type, transform this
** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the
@ -1098,45 +1135,6 @@ int sqlite3_open16(
}
#endif /* SQLITE_OMIT_UTF16 */
/*
** The following routine destroys a virtual machine that is created by
** the sqlite3_compile() routine. The integer returned is an SQLITE_
** success/failure code that describes the result of executing the virtual
** machine.
**
** This routine sets the error code and string returned by
** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16().
*/
int sqlite3_finalize(sqlite3_stmt *pStmt){
int rc;
if( pStmt==0 ){
rc = SQLITE_OK;
}else{
rc = sqlite3VdbeFinalize((Vdbe*)pStmt);
}
return rc;
}
/*
** Terminate the current execution of an SQL statement and reset it
** back to its starting state so that it can be reused. A success code from
** the prior execution is returned.
**
** This routine sets the error code and string returned by
** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16().
*/
int sqlite3_reset(sqlite3_stmt *pStmt){
int rc;
if( pStmt==0 ){
rc = SQLITE_OK;
}else{
rc = sqlite3VdbeReset((Vdbe*)pStmt);
sqlite3VdbeMakeReady((Vdbe*)pStmt, -1, 0, 0, 0);
assert( (rc & (sqlite3_db_handle(pStmt)->errMask))==rc );
}
return rc;
}
/*
** Register a new collation sequence with the database handle db.
*/
@ -1148,9 +1146,12 @@ int sqlite3_create_collation(
int(*xCompare)(void*,int,const void*,int,const void*)
){
int rc;
sqlite3_mutex_enter(db->mutex);
assert( !db->mallocFailed );
rc = createCollation(db, zName, enc, pCtx, xCompare, 0);
return sqlite3ApiExit(db, rc);
rc = sqlite3ApiExit(db, rc);
sqlite3_mutex_leave(db->mutex);
return rc;
}
/*
@ -1165,9 +1166,12 @@ int sqlite3_create_collation_v2(
void(*xDel)(void*)
){
int rc;
sqlite3_mutex_enter(db->mutex);
assert( !db->mallocFailed );
rc = createCollation(db, zName, enc, pCtx, xCompare, xDel);
return sqlite3ApiExit(db, rc);
rc = sqlite3ApiExit(db, rc);
sqlite3_mutex_leave(db->mutex);
return rc;
}
#ifndef SQLITE_OMIT_UTF16
@ -1183,13 +1187,16 @@ int sqlite3_create_collation16(
){
int rc = SQLITE_OK;
char *zName8;
sqlite3_mutex_enter(db->mutex);
assert( !db->mallocFailed );
zName8 = sqlite3Utf16to8(db, zName, -1);
if( zName8 ){
rc = createCollation(db, zName8, enc, pCtx, xCompare, 0);
sqlite3_free(zName8);
}
return sqlite3ApiExit(db, rc);
rc = sqlite3ApiExit(db, rc);
sqlite3_mutex_leave(db->mutex);
return rc;
}
#endif /* SQLITE_OMIT_UTF16 */
@ -1205,9 +1212,11 @@ int sqlite3_collation_needed(
if( sqlite3SafetyCheck(db) ){
return SQLITE_MISUSE;
}
sqlite3_mutex_enter(db->mutex);
db->xCollNeeded = xCollNeeded;
db->xCollNeeded16 = 0;
db->pCollNeededArg = pCollNeededArg;
sqlite3_mutex_leave(db->mutex);
return SQLITE_OK;
}
@ -1224,9 +1233,11 @@ int sqlite3_collation_needed16(
if( sqlite3SafetyCheck(db) ){
return SQLITE_MISUSE;
}
sqlite3_mutex_enter(db->mutex);
db->xCollNeeded = 0;
db->xCollNeeded16 = xCollNeeded16;
db->pCollNeededArg = pCollNeededArg;
sqlite3_mutex_leave(db->mutex);
return SQLITE_OK;
}
#endif /* SQLITE_OMIT_UTF16 */
@ -1306,6 +1317,7 @@ int sqlite3_table_column_metadata(
if( sqlite3SafetyOn(db) ){
return SQLITE_MISUSE;
}
sqlite3_mutex_enter(db->mutex);
rc = sqlite3Init(db, &zErrMsg);
if( SQLITE_OK!=rc ){
goto error_out;
@ -1383,39 +1395,34 @@ error_out:
}
sqlite3Error(db, rc, (zErrMsg?"%s":0), zErrMsg);
sqlite3_free(zErrMsg);
return sqlite3ApiExit(db, rc);
}
#endif
/*
** Set all the parameters in the compiled SQL statement to NULL.
*/
int sqlite3_clear_bindings(sqlite3_stmt *pStmt){
int i;
int rc = SQLITE_OK;
for(i=1; rc==SQLITE_OK && i<=sqlite3_bind_parameter_count(pStmt); i++){
rc = sqlite3_bind_null(pStmt, i);
}
rc = sqlite3ApiExit(db, rc);
sqlite3_mutex_leave(db->mutex);
return rc;
}
#endif
/*
** Sleep for a little while. Return the amount of time slept.
*/
int sqlite3_sleep(int ms){
sqlite3_vfs *pVfs;
int rc;
pVfs = sqlite3_vfs_find(0);
/* This function works in milliseconds, but the underlying OsSleep()
** API uses microseconds. Hence the 1000's.
*/
return (sqlite3OsSleep(pVfs, 1000*ms)/1000);
rc = (sqlite3OsSleep(pVfs, 1000*ms)/1000);
sqlite3_vfs_release(pVfs);
return rc;
}
/*
** Enable or disable the extended result codes.
*/
int sqlite3_extended_result_codes(sqlite3 *db, int onoff){
sqlite3_mutex_enter(db->mutex);
db->errMask = onoff ? 0xffffffff : 0xff;
sqlite3_mutex_leave(db->mutex);
return SQLITE_OK;
}

View File

@ -30,7 +30,7 @@
** the version number) and changes its name to "sqlite3.h" as
** part of the build process.
**
** @(#) $Id: sqlite.h.in,v 1.232 2007/08/21 15:13:19 drh Exp $
** @(#) $Id: sqlite.h.in,v 1.233 2007/08/21 16:15:56 drh Exp $
*/
#ifndef _SQLITE3_H_
#define _SQLITE3_H_
@ -169,6 +169,12 @@ typedef sqlite_uint64 sqlite3_uint64;
** [sqlite3_prepare16_v2()] must be destroyed using [sqlite3_finalize()]
** before this routine is called. Otherwise, SQLITE_BUSY is returned and the
** database connection remains open.
**
** Passing this routine a database connection that has already been
** closed results in undefined behavior. If other interfaces that
** reference the same database connection are pending (either in the
** same thread or in different threads) when this routine is called,
** then the behavior is undefined and is almost certainly undesirable.
*/
int sqlite3_close(sqlite3 *);
@ -695,6 +701,10 @@ int sqlite3_extended_result_codes(sqlite3*, int onoff);
** is running. But once the trigger terminates, the value returned
** by this routine reverts to the last value inserted before the
** trigger fired.
**
** If another thread does a new insert on the same database connection
** while this routine is running and thus changes the last insert rowid,
** then the return value of this routine is undefined.
*/
sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
@ -728,6 +738,10 @@ sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
** zero regardless of the number of elements that were originally in the
** table. To get an accurate count of the number of rows deleted, use
** "DELETE FROM table WHERE 1" instead.
**
** If another thread makes changes on the same database connection
** while this routine is running then the return value of this routine
** is undefined.
*/
int sqlite3_changes(sqlite3*);
@ -750,6 +764,10 @@ int sqlite3_changes(sqlite3*);
** zero regardless of the number of elements that were originally in the
** table. To get an accurate count of the number of rows deleted, use
** "DELETE FROM table WHERE 1" instead.
**
** If another thread makes changes on the same database connection
** while this routine is running then the return value of this routine
** is undefined.
*/
int sqlite3_total_changes(sqlite3*);
@ -1344,7 +1362,7 @@ int sqlite3_open16(
sqlite3 **ppDb /* OUT: SQLite db handle */
);
int sqlite3_open_v2(
const void *filename, /* Database filename (UTF-16) */
const void *filename, /* Database filename (UTF-8) */
sqlite3 **ppDb, /* OUT: SQLite db handle */
int flags, /* Flags */
const char *zVfs /* Name of VFS module to use */
@ -2150,7 +2168,7 @@ int sqlite3_aggregate_count(sqlite3_context*);
int sqlite3_expired(sqlite3_stmt*);
int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*);
int sqlite3_global_recover(void);
void sqlite3_thread_cleanup(void);
/*
** CAPI3REF: Obtaining SQL Function Parameter Values
@ -2503,6 +2521,10 @@ SQLITE_EXTERN char *sqlite3_temp_directory;
** mode. Return TRUE if it is and FALSE if not. Autocommit mode is on
** by default. Autocommit is disabled by a BEGIN statement and reenabled
** by the next COMMIT or ROLLBACK.
**
** If another thread changes the autocommit status of the database
** connection while this routine is running, then the return value
** is undefined.
*/
int sqlite3_get_autocommit(sqlite3*);
@ -2581,28 +2603,14 @@ void *sqlite3_update_hook(
** Sharing is enabled if the argument is true and disabled if the argument
** is false.
**
** Cache sharing is enabled and disabled on a thread-by-thread basis.
** Each call to this routine enables or disables cache sharing only for
** connections created in the same thread in which this routine is called.
** There is no mechanism for sharing cache between database connections
** running in different threads.
** Beginning in SQLite version 3.5.0, cache sharing is enabled and disabled
** for an entire process. In prior versions of SQLite, sharing was
** enabled or disabled for each thread separately.
**
** Sharing must be disabled prior to shutting down a thread or else
** the thread will leak memory. Call this routine with an argument of
** 0 to turn off sharing. Or use the sqlite3_thread_cleanup() API.
**
** This routine must not be called when any database connections
** are active in the current thread. Enabling or disabling shared
** cache while there are active database connections will result
** in memory corruption.
**
** When the shared cache is enabled, the
** following routines must always be called from the same thread:
** [sqlite3_open()], [sqlite3_prepare_v2()], [sqlite3_step()],
** [sqlite3_reset()], [sqlite3_finalize()], and [sqlite3_close()].
** This is due to the fact that the shared cache makes use of
** thread-specific storage so that it will be available for sharing
** with other connections.
** The cache sharing mode set by this interface effects all subsequent
** calls to [sqlite3_open()], [sqlite3_open_v2()], and [sqlite3_open16()].
** Existing database connections continue use the sharing mode that was
** in effect at the time they were opened.
**
** Virtual tables cannot be used with a shared cache. When shared
** cache is enabled, the sqlite3_create_module() API used to register
@ -2631,21 +2639,18 @@ int sqlite3_release_memory(int);
/*
** CAPI3REF: Impose A Limit On Heap Size
**
** Place a "soft" limit on the amount of heap memory that may be allocated by
** SQLite within the current thread. If an internal allocation is requested
** that would exceed the specified limit, [sqlite3_release_memory()] is invoked
** one or more times to free up some space before the allocation is made.
** Place a "soft" limit on the amount of heap memory that may be allocated
** by SQLite. If an internal allocation is requested
** that would exceed the specified limit, [sqlite3_release_memory()] is
** invoked one or more times to free up some space before the allocation
** is made.
**
** The limit is called "soft", because if [sqlite3_release_memory()] cannot free
** sufficient memory to prevent the limit from being exceeded, the memory is
** allocated anyway and the current operation proceeds.
**
** Prior to shutting down a thread sqlite3_soft_heap_limit() must be set to
** zero (the default) or else the thread will leak memory. Alternatively, use
** the [sqlite3_thread_cleanup()] API.
** The limit is called "soft", because if [sqlite3_release_memory()] cannot
** free sufficient memory to prevent the limit from being exceeded,
** the memory is allocated anyway and the current operation proceeds.
**
** A negative or zero value for N means that there is no soft heap limit and
** [sqlite3_release_memory()] will only be called when memory is exhaused.
** [sqlite3_release_memory()] will only be called when memory is exhausted.
** The default value for the soft heap limit is zero.
**
** SQLite makes a best effort to honor the soft heap limit. But if it
@ -2653,27 +2658,13 @@ int sqlite3_release_memory(int);
** continue without error or notification. This is why the limit is
** called a "soft" limit. It is advisory only.
**
** This function is only available if the library was compiled with the
** SQLITE_ENABLE_MEMORY_MANAGEMENT option set.
** memory-management has been enabled.
** Prior to SQLite version 3.5.0, this routine only constrained the memory
** allocated by a single thread - the same thread in which this routine
** runs. Beginning with SQLite version 3.5.0, the soft heap limit is
** applied cumulatively to all threads.
*/
void sqlite3_soft_heap_limit(int);
/*
** CAPI3REF: Clean Up Thread Local Storage
**
** This routine makes sure that all thread-local storage has been
** deallocated for the current thread.
**
** This routine is not technically necessary. All thread-local storage
** will be automatically deallocated once memory-management and
** shared-cache are disabled and the soft heap limit has been set
** to zero. This routine is provided as a convenience for users who
** want to make absolutely sure they have not forgotten something
** prior to killing off a thread.
*/
void sqlite3_thread_cleanup(void);
/*
** CAPI3REF: Extract Metadata About A Column Of A Table
**

View File

@ -29,6 +29,67 @@ int sqlite3_expired(sqlite3_stmt *pStmt){
return p==0 || p->expired;
}
/*
** The following routine destroys a virtual machine that is created by
** the sqlite3_compile() routine. The integer returned is an SQLITE_
** success/failure code that describes the result of executing the virtual
** machine.
**
** This routine sets the error code and string returned by
** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16().
*/
int sqlite3_finalize(sqlite3_stmt *pStmt){
int rc;
if( pStmt==0 ){
rc = SQLITE_OK;
}else{
Vdbe *v = (Vdbe*)pStmt;
sqlite3_mutex_enter(v->db->mutex);
rc = sqlite3VdbeFinalize(v);
sqlite3_mutex_leave(v->db->mutex);
}
return rc;
}
/*
** Terminate the current execution of an SQL statement and reset it
** back to its starting state so that it can be reused. A success code from
** the prior execution is returned.
**
** This routine sets the error code and string returned by
** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16().
*/
int sqlite3_reset(sqlite3_stmt *pStmt){
int rc;
if( pStmt==0 ){
rc = SQLITE_OK;
}else{
Vdbe *v = (Vdbe*)pStmt;
sqlite3_mutex_enter(v->db->mutex);
rc = sqlite3VdbeReset(v);
sqlite3VdbeMakeReady(v, -1, 0, 0, 0);
assert( (rc & (v->db->errMask))==rc );
sqlite3_mutex_leave(v->db->mutex);
}
return rc;
}
/*
** Set all the parameters in the compiled SQL statement to NULL.
*/
int sqlite3_clear_bindings(sqlite3_stmt *pStmt){
int i;
int rc = SQLITE_OK;
Vdbe *v = (Vdbe*)pStmt;
sqlite3_mutex_enter(v->db->mutex);
for(i=1; rc==SQLITE_OK && i<=sqlite3_bind_parameter_count(pStmt); i++){
rc = sqlite3_bind_null(pStmt, i);
}
sqlite3_mutex_leave(v->db->mutex);
return rc;
}
/**************************** sqlite3_value_ *******************************
** The following routines extract information from a Mem or sqlite3_value
** structure.