]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Adding more thread locking code. This is an incremental check-in. (CVS 4262)
authordrh <drh@noemail.net>
Tue, 21 Aug 2007 16:15:55 +0000 (16:15 +0000)
committerdrh <drh@noemail.net>
Tue, 21 Aug 2007 16:15:55 +0000 (16:15 +0000)
FossilOrigin-Name: 7428732b1fa04b83eda0a3539834693ef351313e

manifest
manifest.uuid
src/main.c
src/sqlite.h.in
src/vdbeapi.c

index 123eaf6b835c64c9be9b03195e937c68272ebe4f..2d12762f24e55b5bef0edf3c69fcde13f9586172 100644 (file)
--- a/manifest
+++ b/manifest
@@ -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
index 082b6ce149c857d53f96cceb874221ba7ef22f6e..d6a9e84d4acdb06be73337446eb442dfaded93ac 100644 (file)
@@ -1 +1 @@
-3787563e90d7210d349ee36484c3f008c955552e
\ No newline at end of file
+7428732b1fa04b83eda0a3539834693ef351313e
\ No newline at end of file
index 0cdda648e186de2f69da6b9d3c07c95153470aa2..b0aa877d5c275756ee18d8414d37762ab45b60e2 100644 (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;
 }
index 55f9204220c49a7276d29d2831c5054c67af3fdd..abecd1d190d8d6970f15e6046f9addf69d51c74e 100644 (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.
-**
-** 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.
+** 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.
+**
+** 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.
-**
-** 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.
+** 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.
 **
-** 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
 **
index ffe89b24c80235443ad308e148623447415e680e..253b477801f57a9c7306c01eb7f9e3e65a4c44b8 100644 (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.