1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-10 01:02:56 +03:00

All mutexing and locking appears to be in place. Now we just have to

test it and make it all work. (CVS 4264)

FossilOrigin-Name: 0f7941aef976aa4f3be3e0046edd1ae042e5d9a3
This commit is contained in:
drh
2007-08-21 20:25:39 +00:00
parent b21c8cd4f6
commit 32bc3f6e01
4 changed files with 101 additions and 35 deletions

View File

@@ -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

View File

@@ -1 +1 @@
9287276191a582c1cf7cf6b71d8399727d8e534d
0f7941aef976aa4f3be3e0046edd1ae042e5d9a3

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.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.
** 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

View 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;
}
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.
#if 0
/* 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( p->db && p->db->mallocFailed ){
p->db->mallocFailed = 0;
ret = 0;
}
#endif
}
}
return ret;
}