]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
All mutexing and locking appears to be in place. Now we just have to
authordrh <drh@noemail.net>
Tue, 21 Aug 2007 20:25:39 +0000 (20:25 +0000)
committerdrh <drh@noemail.net>
Tue, 21 Aug 2007 20:25:39 +0000 (20:25 +0000)
test it and make it all work. (CVS 4264)

FossilOrigin-Name: 0f7941aef976aa4f3be3e0046edd1ae042e5d9a3

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

index cc0aa52cb7546e1137c6e95e8a49be3f6a89a4d7..fa52920b334a1e5b88bb903ea99b5cf5f8a97f15 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C The\ssqlite3_value\sobject\snow\scarries\san\ssqlite3*\spointer\sto\suse\sfor\nrecording\smalloc\sfailures.\s\sThis\seliminates\sthe\sneed\sto\spass\ssqlite3*\npointers\sinto\smany\sinternal\sinterfaces.\s\sAlso\sadded\smore\smutexing.\s(CVS\s4263)
-D 2007-08-21T19:33:56
+C All\smutexing\sand\slocking\sappears\sto\sbe\sin\splace.\s\sNow\swe\sjust\shave\sto\ntest\sit\sand\smake\sit\sall\swork.\s(CVS\s4264)
+D 2007-08-21T20:25:40
 F Makefile.in 0c0e53720f658c7a551046442dd7afba0b72bfbe
 F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499
 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@@ -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 95e159919060f9c6e060ff420ce17490f7b6a0f3
+F src/sqlite.h.in b2a7484c024c42f2e639f289beb7c8db36513a2c
 F src/sqlite3ext.h 647a6b8a8f76ff6c9611e4a071531d8e63ff2d6b
 F src/sqliteInt.h 23eb6a5b1f10d5d3d34c3c7846b7c3b93acf1276
 F src/sqliteLimit.h f14609c27636ebc217c9603ade26dbdd7d0f6afa
@@ -159,7 +159,7 @@ F src/vacuum.c 318ccae7c4e3ddf241aeaee4d2611bfe1949a373
 F src/vdbe.c 9d4d00589c174aad9a616f1615464ddddebba0ec
 F src/vdbe.h 001c5b257567c1d3de7feb2203aac71d0d7b16a3
 F src/vdbeInt.h 39fb069ce04137545ca0bc790f80ddc64a8c99d9
-F src/vdbeapi.c 09eb4fe5ce6e8e4558ca3fa1e22241f2d3895bf0
+F src/vdbeapi.c e12f99aa859118afbffff67eb32df36d564b5c80
 F src/vdbeaux.c b0aeed4ff33352904b392ee6c7408bae5b141b9b
 F src/vdbeblob.c d12ed95dac0992e1e372d079d76af047cc42f7c7
 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 7428732b1fa04b83eda0a3539834693ef351313e
-R 913d5d6bd631d176ac289a9e0cf82ff0
+P 9287276191a582c1cf7cf6b71d8399727d8e534d
+R c2481d632c284d895f66ae3d4866a0ab
 U drh
-Z c581f4a42a4b4dc59e9659821c9fdece
+Z aa5c15d669e0ef0f762ec1f2d438a5a0
index d5508f39d3478089b05639652ca5e8af093766ba..780479153af77e6a9843e78403abcba02dd87056 100644 (file)
@@ -1 +1 @@
-9287276191a582c1cf7cf6b71d8399727d8e534d
\ No newline at end of file
+0f7941aef976aa4f3be3e0046edd1ae042e5d9a3
\ No newline at end of file
index ba1731864d8a852aabe9875bb6292ea023c1a0cf..a4bd04f53e6aaa6d90ab713786171f9e51a41db8 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.234 2007/08/21 19:33:56 drh Exp $
+** @(#) $Id: sqlite.h.in,v 1.235 2007/08/21 20:25:40 drh Exp $
 */
 #ifndef _SQLITE3_H_
 #define _SQLITE3_H_
@@ -1745,6 +1745,10 @@ const void *sqlite3_column_name16(sqlite3_stmt*, int N);
 **
 ** These APIs are only available if the library was compiled with the 
 ** SQLITE_ENABLE_COLUMN_METADATA preprocessor symbol defined.
+**
+** If two or more threads call one or more of these routines against the same
+** prepared statement and column at the same time then the results are
+** undefined.
 */
 const char *sqlite3_column_database_name(sqlite3_stmt*,int);
 const void *sqlite3_column_database_name16(sqlite3_stmt*,int);
@@ -1905,17 +1909,27 @@ int sqlite3_data_count(sqlite3_stmt *pStmt);
 /*
 ** CAPI3REF: Results Values From A Query
 **
-** These routines return information about the information
-** in a single column of the current result row of a query.  In every
+** These routines return information about
+** a single column of the current result row of a query.  In every
 ** case the first argument is a pointer to the 
 ** [sqlite3_stmt | SQL statement] that is being
-** evaluate (the [sqlite3_stmt*] that was returned from 
+** evaluated (the [sqlite3_stmt*] that was returned from 
 ** [sqlite3_prepare_v2()] or one of its variants) and
 ** the second argument is the index of the column for which information 
-** should be returned.  The left-most column has an index of 0.
+** should be returned.  The left-most column of the result set
+** has an index of 0.
 **
 ** If the SQL statement is not currently point to a valid row, or if the
-** the column index is out of range, the result is undefined.
+** the column index is out of range, the result is undefined. 
+** These routines may only be called when the most recent call to
+** [sqlite3_step()] has returned [SQLITE_ROW] and neither
+** [sqlite3_reset()] nor [sqlite3_finalize()] has been call subsequently.
+** If any of these routines are called after [sqlite3_reset()] or
+** [sqlite3_finalize()] or after [sqlite3_step()] has returned
+** something other than [SQLITE_ROW], the results are undefined.
+** If [sqlite3_step()] or [sqlite3_reset()] or [sqlite3_finalize()]
+** are called from a different thread while any of these routines
+** are pending, then the results are undefined.  
 **
 ** The sqlite3_column_type() routine returns 
 ** [SQLITE_INTEGER | datatype code] for the initial data type
@@ -2019,6 +2033,13 @@ int sqlite3_data_count(sqlite3_stmt *pStmt);
 ** find the size of the result.  Do not mix call to sqlite3_column_text() or
 ** sqlite3_column_blob() with calls to sqlite3_column_bytes16().  And do not
 ** mix calls to sqlite3_column_text16() with calls to sqlite3_column_bytes().
+**
+** The pointers returned are valid until a type conversion occurs as
+** described above, or until [sqlite3_step()] or [sqlite3_reset()] or
+** [sqlite3_finalize()] is called.  The memory space used to hold strings
+** and blobs is freed automatically.  Do <b>not</b> pass the pointers returned
+** [sqlite3_column_blob()], [sqlite_column_text()], etc. into 
+** [sqlite3_free()].
 */
 const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
 int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
@@ -2211,6 +2232,9 @@ void sqlite3_thread_cleanup(void);
 **
 ** These routines must be called from the same thread as
 ** the SQL function that supplied the sqlite3_value* parameters.
+** Or, if the sqlite3_value* argument comes from the [sqlite3_column_value()]
+** interface, then these routines should be called from the same thread
+** that ran [sqlite3_column_value()].
 */
 const void *sqlite3_value_blob(sqlite3_value*);
 int sqlite3_value_bytes(sqlite3_value*);
@@ -3311,6 +3335,13 @@ int sqlite3_mutex_try(sqlite3_mutex*);
 void sqlite3_mutex_leave(sqlite3_mutex*);
 int sqlite3_mutex_held(sqlite3_mutex*);
 int sqlite3_mutex_notheld(sqlite3_mutex*);
+
+/*
+** CAPI3REF: Mutex Types
+**
+** The [sqlite3_mutex_alloc()] interface takes a single argument
+** which is one of these integer constants.
+*/
 #define SQLITE_MUTEX_FAST             0
 #define SQLITE_MUTEX_RECURSIVE        1
 #define SQLITE_MUTEX_STATIC_MASTER    2
index 20767fd62841a17f1464a0636915a4916956d2b2..cf8b6dc5ff72a495bad082a7f035ae6960af879b 100644 (file)
@@ -137,7 +137,6 @@ const void *sqlite3_value_text16le(sqlite3_value *pVal){
 int sqlite3_value_type(sqlite3_value* pVal){
   return pVal->type;
 }
-/* sqlite3_value_numeric_type() defined in vdbe.c */
 
 /**************************** sqlite3_result_  *******************************
 ** The following routines are used by user-defined functions to specify
@@ -150,28 +149,35 @@ void sqlite3_result_blob(
   void (*xDel)(void *)
 ){
   assert( n>=0 );
+  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
   sqlite3VdbeMemSetStr(&pCtx->s, z, n, 0, xDel);
 }
 void sqlite3_result_double(sqlite3_context *pCtx, double rVal){
+  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
   sqlite3VdbeMemSetDouble(&pCtx->s, rVal);
 }
 void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
+  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
   pCtx->isError = 1;
   sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF8, SQLITE_TRANSIENT);
 }
 #ifndef SQLITE_OMIT_UTF16
 void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){
+  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
   pCtx->isError = 1;
   sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT);
 }
 #endif
 void sqlite3_result_int(sqlite3_context *pCtx, int iVal){
+  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
   sqlite3VdbeMemSetInt64(&pCtx->s, (i64)iVal);
 }
 void sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){
+  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
   sqlite3VdbeMemSetInt64(&pCtx->s, iVal);
 }
 void sqlite3_result_null(sqlite3_context *pCtx){
+  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
   sqlite3VdbeMemSetNull(&pCtx->s);
 }
 void sqlite3_result_text(
@@ -180,6 +186,7 @@ void sqlite3_result_text(
   int n,
   void (*xDel)(void *)
 ){
+  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
   sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF8, xDel);
 }
 #ifndef SQLITE_OMIT_UTF16
@@ -189,6 +196,7 @@ void sqlite3_result_text16(
   int n, 
   void (*xDel)(void *)
 ){
+  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
   sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16NATIVE, xDel);
 }
 void sqlite3_result_text16be(
@@ -197,6 +205,7 @@ void sqlite3_result_text16be(
   int n, 
   void (*xDel)(void *)
 ){
+  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
   sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16BE, xDel);
 }
 void sqlite3_result_text16le(
@@ -205,18 +214,22 @@ void sqlite3_result_text16le(
   int n, 
   void (*xDel)(void *)
 ){
+  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
   sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16LE, xDel);
 }
 #endif /* SQLITE_OMIT_UTF16 */
 void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){
+  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
   sqlite3VdbeMemCopy(&pCtx->s, pValue);
 }
 void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){
+  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
   sqlite3VdbeMemSetZeroBlob(&pCtx->s, n);
 }
 
 /* Force an SQLITE_TOOBIG error. */
 void sqlite3_result_error_toobig(sqlite3_context *pCtx){
+  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
   sqlite3VdbeMemSetZeroBlob(&pCtx->s, SQLITE_MAX_LENGTH+1);
 }
 
@@ -535,14 +548,21 @@ int sqlite3_data_count(sqlite3_stmt *pStmt){
 ** of NULL.
 */
 static Mem *columnMem(sqlite3_stmt *pStmt, int i){
-  Vdbe *pVm = (Vdbe *)pStmt;
-  int vals = sqlite3_data_count(pStmt);
-  if( pVm==0 || pVm->resOnStack==0 || i>=pVm->nResColumn || i<0 ){
+  Vdbe *pVm;
+  int vals;
+  Mem *pOut;
+
+  pVm = (Vdbe *)pStmt;
+  if( pVm && pVm->resOnStack && i<pVm->nResColumn && i>=0 ){
+    sqlite3_mutex_enter(pVm->db->mutex);
+    vals = sqlite3_data_count(pStmt);
+    pOut = &pVm->pTos[(1-vals)+i];
+  }else{
     static const Mem nullMem = {{0}, 0.0, 0, "", 0, MEM_Null, SQLITE_NULL };
     sqlite3Error(pVm->db, SQLITE_RANGE, 0);
-    return (Mem*)&nullMem;
+    pOut = (Mem*)&nullMem;
   }
-  return &pVm->pTos[(1-vals)+i];
+  return pOut;
 }
 
 /*
@@ -552,7 +572,7 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){
 ** malloc() has failed, the threads mallocFailed flag is cleared and the result
 ** code of statement pStmt set to SQLITE_NOMEM.
 **
-** Specificly, this is called from within:
+** Specifically, this is called from within:
 **
 **     sqlite3_column_int()
 **     sqlite3_column_int64()
@@ -572,7 +592,10 @@ static void columnMallocFailure(sqlite3_stmt *pStmt)
   ** and _finalize() will return NOMEM.
   */
   Vdbe *p = (Vdbe *)pStmt;
-  p->rc = sqlite3ApiExit(0, p->rc);
+  if( p ){
+    p->rc = sqlite3ApiExit(p->db, p->rc);
+    sqlite3_mutex_leave(p->db->mutex);
+  }
 }
 
 /**************************** sqlite3_column_  *******************************
@@ -620,7 +643,9 @@ const unsigned char *sqlite3_column_text(sqlite3_stmt *pStmt, int i){
   return val;
 }
 sqlite3_value *sqlite3_column_value(sqlite3_stmt *pStmt, int i){
-  return columnMem(pStmt, i);
+  sqlite3_value *pOut = columnMem(pStmt, i);
+  columnMallocFailure(pStmt);
+  return pOut;
 }
 #ifndef SQLITE_OMIT_UTF16
 const void *sqlite3_column_text16(sqlite3_stmt *pStmt, int i){
@@ -630,7 +655,9 @@ const void *sqlite3_column_text16(sqlite3_stmt *pStmt, int i){
 }
 #endif /* SQLITE_OMIT_UTF16 */
 int sqlite3_column_type(sqlite3_stmt *pStmt, int i){
-  return sqlite3_value_type( columnMem(pStmt,i) );
+  int iType = sqlite3_value_type( columnMem(pStmt,i) );
+  columnMallocFailure(pStmt);
+  return iType;
 }
 
 /* The following function is experimental and subject to change or
@@ -662,20 +689,28 @@ static const void *columnName(
   const void *(*xFunc)(Mem*),
   int useType
 ){
-  const void *ret;
+  const void *ret = 0;
   Vdbe *p = (Vdbe *)pStmt;
-  int n = sqlite3_column_count(pStmt);
+  int n;
+  
 
-  if( p==0 || N>=n || N<0 ){
-    return 0;
-  }
-  N += useType*n;
-  ret = xFunc(&p->aColName[N]);
+  if( p!=0 ){
+    n = sqlite3_column_count(pStmt);
+    if( N<n && N>=0 ){
+      N += useType*n;
+      ret = xFunc(&p->aColName[N]);
 
-  /* A malloc may have failed inside of the xFunc() call. If this is the case,
-  ** clear the mallocFailed flag and return NULL.
-  */
-  sqlite3ApiExit(0, 0);
+#if 0
+      /* A malloc may have failed inside of the xFunc() call. If this
+      ** is the case, clear the mallocFailed flag and return NULL.
+      */
+      if( p->db && p->db->mallocFailed ){
+        p->db->mallocFailed = 0;
+        ret = 0;
+      }
+#endif
+    }
+  }
   return ret;
 }