mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Automatically deallocate thread-specific data when it is no longer
being used. Ticket #1601. Also implemented the suggestion of ticket #1603. Memory management is now off by default at compile-time. The sqlite3_enable_memory_management() API has been removed. (CVS 2919) FossilOrigin-Name: 5d9c6aa964305c3f36741ff0058da5b5f3ce0d24
This commit is contained in:
70
manifest
70
manifest
@@ -1,5 +1,5 @@
|
||||
C Ensure\sthe\sdatabase\sattached\sas\spart\sof\sVACUUM\scan\sbe\sdetached\ssuccessfully\safter\sa\smalloc()\sfailure.\s(CVS\s2918)
|
||||
D 2006-01-11T16:10:20
|
||||
C Automatically\sdeallocate\sthread-specific\sdata\swhen\sit\sis\sno\slonger\nbeing\sused.\s\sTicket\s#1601.\s\sAlso\simplemented\sthe\ssuggestion\sof\nticket\s#1603.\sMemory\smanagement\sis\snow\soff\sby\sdefault\sat\scompile-time.\nThe\ssqlite3_enable_memory_management()\sAPI\shas\sbeen\sremoved.\s(CVS\s2919)
|
||||
D 2006-01-11T21:41:21
|
||||
F Makefile.in ab3ffd8d469cef4477257169b82810030a6bb967
|
||||
F Makefile.linux-gcc aee18d8a05546dcf1888bd4547e442008a49a092
|
||||
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
|
||||
@@ -28,52 +28,52 @@ F publish.sh ed0aba4ffdfadb36597d03ce8efdae96efc038cb
|
||||
F spec.template b2f6c4e488cbc3b993a57deba22cbc36203c4da3
|
||||
F sqlite.pc.in 30552343140c53304c2a658c080fbe810cd09ca2
|
||||
F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
|
||||
F sqlite3.def ccf06c86eaa2c123271db41352d2b3c9e4ec42a5
|
||||
F sqlite3.def 99ac9728b515bb49d1af29153d64c8e7aad7bcc3
|
||||
F sqlite3.pc.in 985b9bf34192a549d7d370e0f0b6b34a4f61369a
|
||||
F src/alter.c d0dd079b9ef0d551ff4a4ce09ee270c07b307bbb
|
||||
F src/alter.c 4139c8f1d0f12b1759e767b1d09dd594e2b5ac1d
|
||||
F src/analyze.c 7d2b7ab9a9c2fd6e55700f69064dfdd3e36d7a8a
|
||||
F src/attach.c fb93d00ab7cb392579ea7db0a1247196d7220788
|
||||
F src/attach.c d4b9d8bd71d72409720946355be41cafb6c09079
|
||||
F src/auth.c cdec356a5cd8b217c346f816c5912221537fe87f
|
||||
F src/btree.c e1f6b2e22484d754b79b7c9b43e7a09af259f0f6
|
||||
F src/btree.c b407273cb22f39606acc27b8a4a74c6272c7a9d2
|
||||
F src/btree.h 5663c4f43e8521546ccebc8fc95acb013b8f3184
|
||||
F src/build.c c7847f299ded7fec899bfda74d4d31ba9f80aa75
|
||||
F src/callback.c 51fe813309f7cf69d3d19a2e7be2103130186efd
|
||||
F src/build.c 652a3932292c2b8d1900219f537f1b5e21490afa
|
||||
F src/callback.c ba3e6cc7a6beb562e7a66f92e26fabcb21aab1e2
|
||||
F src/complete.c df1681cef40dec33a286006981845f87b194e7a4
|
||||
F src/date.c a927bdbb51296ac398d2f667086a7072c099e5ab
|
||||
F src/delete.c b242a0d9462d2b7054e38c5250bdbe94d6772a8e
|
||||
F src/delete.c c7bd5708a629585e073ce34cf3b1fcb52c2fef38
|
||||
F src/experimental.c 50c1e3b34f752f4ac10c36f287db095c2b61766d
|
||||
F src/expr.c b90fa835a2216edd6808b4bb5da6bbf3b8ee29b9
|
||||
F src/expr.c 3b6acdb4e254027fe72ce70054ea6b71c7d423a3
|
||||
F src/func.c e013c3b6c607c6a1654f5260eab59f5609a5ce4a
|
||||
F src/hash.c 8747cf51d12de46512880dfcf1b68b4e24072863
|
||||
F src/hash.h 1b0c445e1c89ff2aaad9b4605ba61375af001e84
|
||||
F src/insert.c 337785137430a012ff0f1c181d4a4d55d2a942d3
|
||||
F src/legacy.c f651ccd3700f99fa05766ac53506bf9a0694761b
|
||||
F src/main.c 3fe4b606db7d269d7a57c7b51ab3d9ff488e4b98
|
||||
F src/insert.c a5595cf8d1d8ba087b676a63f1f7277ea44b5ac1
|
||||
F src/legacy.c 9bf7ee1b63c99aac6669533986a5240b16101458
|
||||
F src/main.c 39d073fb1f95f874ee0c98366e99005cf14742dd
|
||||
F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217
|
||||
F src/os.c 1d1a61cdf150e9f9520a3bc787c8465148ea2e78
|
||||
F src/os.h 8710c0068f3386a73a37f8ad242b92c7580464df
|
||||
F src/os.h 9debc3d3ca4cdafde222a0ea74a4c8415aef4f22
|
||||
F src/os_common.h 78bcc34dded9b625b3c16d072b7e5b76d075a674
|
||||
F src/os_test.c 49833426101f99aee4bb5f6a44b7c4b2029fda1c
|
||||
F src/os_test.h 903c93554c23d88f34f667f1979e4a1cee792af3
|
||||
F src/os_unix.c 8943febbedc79649d21ec1ed14de14ad8214c899
|
||||
F src/os_unix.c 557a21c563496a1ccef32b1d57376d135884eac5
|
||||
F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e
|
||||
F src/os_win.c 8ef250a0965a55dbcd8ef785e03f9f3292e6ade2
|
||||
F src/os_win.c b67dd34bf1ae796851910a229bd94026b42d942f
|
||||
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
|
||||
F src/pager.c 0a59a320b0da6b22d2dd4411d16e300ff1b947c8
|
||||
F src/pager.c a96b9c43664670576e41eac699277c7862d604d8
|
||||
F src/pager.h e0acb095b3ad0bca48f2ab00c87346665643f64f
|
||||
F src/parse.y 83df51fea35f68f7e07384d75dce83d1ed30434c
|
||||
F src/pragma.c d439d257c1bcacbc09d38820ac578749df900562
|
||||
F src/prepare.c 65b166b806e4af6e0035acdd5f6a24e2ec02b66d
|
||||
F src/prepare.c 60c1f5e3d2901d651f8ca9f06e39e2ff3f335844
|
||||
F src/printf.c f47a2f4b5387cd2ebb12e9117a1a5d6bd9a2b812
|
||||
F src/random.c d40f8d356cecbd351ccfab6eaedd7ec1b54f5261
|
||||
F src/select.c 579cfdd250c5598de7c867134f7d35a2099b1dcc
|
||||
F src/select.c 7b19d350cb2a18ae4a59d6b87049aa2ce9c671ae
|
||||
F src/server.c 519e308651e30102dd3d1f4053ac64c14267e44c
|
||||
F src/shell.c 66b073375efbdee19045e7e0cd38b85f9aff71da
|
||||
F src/sqlite.h.in 821b93f918d126c54d9a91fc928434945655edc3
|
||||
F src/sqliteInt.h 829f8c22767ceaed717042087e7fb4d599a3c44c
|
||||
F src/sqlite.h.in 4320cff369e37897d2839d526c2b8917a2756d60
|
||||
F src/sqliteInt.h bd3fba6d7163ef402b5633191ee5d7de5b7f6e80
|
||||
F src/table.c 486dcfce532685b53b5a2b5da8bba0ded6fb2316
|
||||
F src/tclsqlite.c d650bea0248fc0a310ddc2cb94273a3a5021fddf
|
||||
F src/test1.c b2923fd22ec44cf05d6d51dc460e8ed8e0d5f241
|
||||
F src/test1.c d38c9f4da2136c5e1747517d7b564ba88a91fbee
|
||||
F src/test2.c ca74a1d8aeb7d9606e8f6b762c5daf85c1a3f92b
|
||||
F src/test3.c 9742aa146eb750cab81c1d5605286c3a0eb88054
|
||||
F src/test4.c a8fd681e139e1c61f22a77d07fc3a99cb28fff3f
|
||||
@@ -81,20 +81,20 @@ F src/test5.c 7162f8526affb771c4ed256826eee7bb9eca265f
|
||||
F src/test6.c 74d91b487c68154156eded457925d96aa2a3fdbb
|
||||
F src/test7.c bfe36c62cae189509660acfeeb891ffb9da8ef0c
|
||||
F src/test_async.c 6776f5027ca6378c116ff5ccc2fe41b908e33772
|
||||
F src/tokenize.c 196486012c871cdcad6cc84a820cc988603f1b9d
|
||||
F src/trigger.c 883b5f3b97137fbe417e3337c3fa20ac8e9c1ae5
|
||||
F src/update.c cd8ad5bb1a29f2056347481308fca4a59f2f4764
|
||||
F src/tokenize.c b75d24cbb419eef9ae7be286dd66723a2ee49f4f
|
||||
F src/trigger.c 694b247476d2fc0dce003af564f79e8752fc1158
|
||||
F src/update.c 261d75c702c2852d1a64274d7c414485e6f2d177
|
||||
F src/utf.c b7bffac4260177ae7f83c01d025fe0f5ed70ce71
|
||||
F src/util.c 3616a0a1f1b89cfb376240c75434431b8028681e
|
||||
F src/util.c 8a147f96099ce716e4ee750142a8f53f1aed3286
|
||||
F src/vacuum.c cd56995ecea281b3ac306ef88128ebc8a2117f84
|
||||
F src/vdbe.c aa4360d28c4476e435c84e92ad3fbd65a8944156
|
||||
F src/vdbe.c db592ade9a0e381f5e6a7a35a67e81c2722480b5
|
||||
F src/vdbe.h 8729a4ee16ff9aeab2af9667df3cf300ff978e13
|
||||
F src/vdbeInt.h 5451cf71f229e366ac543607c0a17f36e5737ea9
|
||||
F src/vdbeapi.c 6d20e92de62b90ae27aeea3a7b18653734b0b1cb
|
||||
F src/vdbeaux.c e4b8f492e41e3b8ecee8f66045e897dae92d1356
|
||||
F src/vdbeapi.c afd3837cea0dec93dcb4724d073c84fa0da68e23
|
||||
F src/vdbeaux.c fca3a799a1e9d5b595a4e5d140f182601258287a
|
||||
F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5
|
||||
F src/vdbemem.c 2ada7cae76da9c840cd0d3c01d2b3987d97141c6
|
||||
F src/where.c 4fecfccf8f35ec7b325d666f0cd2fb016a53da43
|
||||
F src/vdbemem.c 66e05857c3bd52436161d6bf96a95725f03225a5
|
||||
F src/where.c a8ba7f4aa2f38166e9f89ecc5dafbdbf41942031
|
||||
F tclinstaller.tcl 046e3624671962dc50f0481d7c25b38ef803eb42
|
||||
F test/all.test a23fcbbf1f53515bde840d78732a6d94c673b327
|
||||
F test/alter.test b94b640063e725d062b2997bd2810ac39195c718
|
||||
@@ -340,7 +340,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
|
||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||
F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
|
||||
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
|
||||
P 3970eb875d1830d35b3a70a7583a8ab6b238cad6
|
||||
R 5d634fd31ace904b5b4a4cd1fc441144
|
||||
U danielk1977
|
||||
Z 11d0cd52f201ef748e551ed33dbe55f7
|
||||
P 8c26893c65574b0667bb84bde3ca49751079cc8d
|
||||
R a464a0f33259fc5b6aae2e3199e401a7
|
||||
U drh
|
||||
Z 7760f8b5862256854e201380c09a40e6
|
||||
|
@@ -1 +1 @@
|
||||
8c26893c65574b0667bb84bde3ca49751079cc8d
|
||||
5d9c6aa964305c3f36741ff0058da5b5f3ce0d24
|
@@ -84,6 +84,7 @@ sqlite3_set_auxdata
|
||||
sqlite3_snprintf
|
||||
sqlite3_soft_heap_limit
|
||||
sqlite3_step
|
||||
sqlite3_thread_cleanup
|
||||
sqlite3_total_changes
|
||||
sqlite3_trace
|
||||
sqlite3_transfer_bindings
|
||||
|
@@ -12,7 +12,7 @@
|
||||
** This file contains C code routines that used to generate VDBE code
|
||||
** that implements the ALTER TABLE command.
|
||||
**
|
||||
** $Id: alter.c,v 1.15 2006/01/09 06:29:48 danielk1977 Exp $
|
||||
** $Id: alter.c,v 1.16 2006/01/11 21:41:21 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
@@ -267,7 +267,7 @@ void sqlite3AlterRenameTable(
|
||||
char *zWhere = 0; /* Where clause to locate temp triggers */
|
||||
#endif
|
||||
|
||||
if( sqlite3ThreadData()->mallocFailed ) goto exit_rename_table;
|
||||
if( sqlite3ThreadDataReadOnly()->mallocFailed ) goto exit_rename_table;
|
||||
assert( pSrc->nSrc==1 );
|
||||
|
||||
pTab = sqlite3LocateTable(pParse, pSrc->a[0].zName, pSrc->a[0].zDatabase);
|
||||
@@ -501,7 +501,7 @@ void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){
|
||||
|
||||
/* Look up the table being altered. */
|
||||
assert( pParse->pNewTable==0 );
|
||||
if( sqlite3ThreadData()->mallocFailed ) goto exit_begin_add_column;
|
||||
if( sqlite3ThreadDataReadOnly()->mallocFailed ) goto exit_begin_add_column;
|
||||
pTab = sqlite3LocateTable(pParse, pSrc->a[0].zName, pSrc->a[0].zDatabase);
|
||||
if( !pTab ) goto exit_begin_add_column;
|
||||
|
||||
|
@@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** This file contains code used to implement the ATTACH and DETACH commands.
|
||||
**
|
||||
** $Id: attach.c,v 1.45 2006/01/11 14:09:31 danielk1977 Exp $
|
||||
** $Id: attach.c,v 1.46 2006/01/11 21:41:22 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@@ -272,7 +272,7 @@ static void codeAttach(
|
||||
sqlite3* db = pParse->db;
|
||||
|
||||
#ifndef SQLITE_OMIT_AUTHORIZATION
|
||||
assert( sqlite3ThreadData()->mallocFailed || pAuthArg );
|
||||
assert( sqlite3ThreadDataReadOnly()->mallocFailed || pAuthArg );
|
||||
if( pAuthArg ){
|
||||
char *zAuthArg = sqlite3NameFromToken(&pAuthArg->span);
|
||||
if( !zAuthArg ){
|
||||
@@ -303,7 +303,7 @@ static void codeAttach(
|
||||
sqlite3ExprCode(pParse, pDbname);
|
||||
sqlite3ExprCode(pParse, pKey);
|
||||
|
||||
assert(v || sqlite3ThreadData()->mallocFailed);
|
||||
assert(v || sqlite3ThreadDataReadOnly()->mallocFailed);
|
||||
if( v ){
|
||||
sqlite3VdbeAddOp(v, OP_Function, 0, nFunc);
|
||||
pFunc = sqlite3FindFunction(db, zFunc, strlen(zFunc), nFunc, SQLITE_UTF8,0);
|
||||
|
40
src/btree.c
40
src/btree.c
@@ -9,7 +9,7 @@
|
||||
** May you share freely, never taking more than you give.
|
||||
**
|
||||
*************************************************************************
|
||||
** $Id: btree.c,v 1.290 2006/01/11 14:09:31 danielk1977 Exp $
|
||||
** $Id: btree.c,v 1.291 2006/01/11 21:41:22 drh Exp $
|
||||
**
|
||||
** This file implements a external (disk-based) database using BTrees.
|
||||
** For a detailed discussion of BTrees, refer to
|
||||
@@ -557,7 +557,7 @@ static int saveCursorPosition(BtCursor *pCur){
|
||||
*/
|
||||
static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){
|
||||
BtCursor *p;
|
||||
if( sqlite3ThreadData()->useSharedData ){
|
||||
if( sqlite3ThreadDataReadOnly()->useSharedData ){
|
||||
for(p=pBt->pCursor; p; p=p->pNext){
|
||||
if( p!=pExcept && p->pgnoRoot==iRoot && p->eState==CURSOR_VALID ){
|
||||
int rc = saveCursorPosition(p);
|
||||
@@ -584,7 +584,7 @@ static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){
|
||||
static int restoreCursorPosition(BtCursor *pCur, int doSeek){
|
||||
int rc = SQLITE_OK;
|
||||
if( pCur->eState==CURSOR_REQUIRESEEK ){
|
||||
assert( sqlite3ThreadData()->useSharedData );
|
||||
assert( sqlite3ThreadDataReadOnly()->useSharedData );
|
||||
if( doSeek ){
|
||||
rc = sqlite3BtreeMoveto(pCur, pCur->pKey, pCur->nKey, &pCur->skip);
|
||||
}else{
|
||||
@@ -610,7 +610,7 @@ static int queryTableLock(Btree *p, Pgno iTab, u8 eLock){
|
||||
BtLock *pIter;
|
||||
|
||||
/* This is a no-op if the shared-cache is not enabled */
|
||||
if( 0==sqlite3ThreadData()->useSharedData ){
|
||||
if( 0==sqlite3ThreadDataReadOnly()->useSharedData ){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
@@ -658,7 +658,7 @@ static int lockTable(Btree *p, Pgno iTable, u8 eLock){
|
||||
BtLock *pIter;
|
||||
|
||||
/* This is a no-op if the shared-cache is not enabled */
|
||||
if( 0==sqlite3ThreadData()->useSharedData ){
|
||||
if( 0==sqlite3ThreadDataReadOnly()->useSharedData ){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
@@ -723,7 +723,7 @@ static void unlockAllTables(Btree *p){
|
||||
** locks in the BtShared.pLock list, making this procedure a no-op. Assert
|
||||
** that this is the case.
|
||||
*/
|
||||
assert( sqlite3ThreadData()->useSharedData || 0==*ppIter );
|
||||
assert( sqlite3ThreadDataReadOnly()->useSharedData || 0==*ppIter );
|
||||
|
||||
while( *ppIter ){
|
||||
BtLock *pLock = *ppIter;
|
||||
@@ -1546,8 +1546,8 @@ int sqlite3BtreeOpen(
|
||||
int rc;
|
||||
int nReserve;
|
||||
unsigned char zDbHeader[100];
|
||||
#ifndef SQLITE_OMIT_SHARED_CACHE
|
||||
ThreadData *pTsd = sqlite3ThreadData();
|
||||
#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
|
||||
const ThreadData *pTsdro;
|
||||
#endif
|
||||
|
||||
/* Set the variable isMemdb to true for an in-memory database, or
|
||||
@@ -1572,13 +1572,14 @@ int sqlite3BtreeOpen(
|
||||
|
||||
/* Try to find an existing Btree structure opened on zFilename. */
|
||||
#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
|
||||
if( pTsd->useSharedData && zFilename && !isMemdb ){
|
||||
pTsdro = sqlite3ThreadDataReadOnly();
|
||||
if( pTsdro->useSharedData && zFilename && !isMemdb ){
|
||||
char *zFullPathname = sqlite3OsFullPathname(zFilename);
|
||||
if( !zFullPathname ){
|
||||
sqliteFree(p);
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
for(pBt=pTsd->pBtree; pBt; pBt=pBt->pNext){
|
||||
for(pBt=pTsdro->pBtree; pBt; pBt=pBt->pNext){
|
||||
assert( pBt->nRef>0 );
|
||||
if( 0==strcmp(zFullPathname, sqlite3pager_filename(pBt->pPager)) ){
|
||||
p->pBt = pBt;
|
||||
@@ -1660,9 +1661,9 @@ int sqlite3BtreeOpen(
|
||||
|
||||
#ifndef SQLITE_OMIT_SHARED_CACHE
|
||||
/* Add the new btree to the linked list starting at ThreadData.pBtree */
|
||||
if( pTsd->useSharedData && zFilename && !isMemdb ){
|
||||
pBt->pNext = pTsd->pBtree;
|
||||
pTsd->pBtree = pBt;
|
||||
if( pTsdro->useSharedData && zFilename && !isMemdb ){
|
||||
pBt->pNext = pTsdro->pBtree;
|
||||
sqlite3ThreadData()->pBtree = pBt;
|
||||
}
|
||||
#endif
|
||||
pBt->nRef = 1;
|
||||
@@ -1678,7 +1679,7 @@ int sqlite3BtreeClose(Btree *p){
|
||||
BtCursor *pCur;
|
||||
|
||||
#ifndef SQLITE_OMIT_SHARED_CACHE
|
||||
ThreadData *pTsd = sqlite3ThreadData();
|
||||
ThreadData *pTsd;
|
||||
#endif
|
||||
|
||||
/* Drop any table-locks */
|
||||
@@ -1708,6 +1709,7 @@ int sqlite3BtreeClose(Btree *p){
|
||||
}
|
||||
|
||||
/* Remove the shared-btree from the thread wide list */
|
||||
pTsd = sqlite3ThreadData();
|
||||
if( pTsd->pBtree==pBt ){
|
||||
pTsd->pBtree = pBt->pNext;
|
||||
}else{
|
||||
@@ -6500,7 +6502,12 @@ int sqlite3BtreeLockTable(Btree *p, int iTab, u8 isWriteLock){
|
||||
return rc;
|
||||
}
|
||||
|
||||
#if defined(SQLITE_TEST) && !defined(NO_TCL)
|
||||
/*
|
||||
** The following debugging interface has to be in this file (rather
|
||||
** than in, for example, test1.c) so that it can get access to
|
||||
** the definition of BtShared.
|
||||
*/
|
||||
#if defined(SQLITE_TEST) && defined(TCLSH)
|
||||
#include <tcl.h>
|
||||
int sqlite3_shared_cache_report(
|
||||
void * clientData,
|
||||
@@ -6508,7 +6515,7 @@ int sqlite3_shared_cache_report(
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
ThreadData *pTd = sqlite3ThreadData();
|
||||
const ThreadData *pTd = sqlite3ThreadDataReadOnly();
|
||||
if( pTd->useSharedData ){
|
||||
BtShared *pBt;
|
||||
Tcl_Obj *pRet = Tcl_NewObj();
|
||||
@@ -6522,4 +6529,3 @@ int sqlite3_shared_cache_report(
|
||||
return TCL_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
32
src/build.c
32
src/build.c
@@ -22,7 +22,7 @@
|
||||
** COMMIT
|
||||
** ROLLBACK
|
||||
**
|
||||
** $Id: build.c,v 1.376 2006/01/11 14:09:32 danielk1977 Exp $
|
||||
** $Id: build.c,v 1.377 2006/01/11 21:41:22 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
@@ -66,9 +66,8 @@ void sqlite3TableLock(
|
||||
int i;
|
||||
int nBytes;
|
||||
TableLock *p;
|
||||
ThreadData *pTsd = sqlite3ThreadData();
|
||||
|
||||
if( 0==pTsd->useSharedData || iDb<0 ){
|
||||
if( 0==sqlite3ThreadDataReadOnly()->useSharedData || iDb<0 ){
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -98,7 +97,7 @@ void sqlite3TableLock(
|
||||
static void codeTableLocks(Parse *pParse){
|
||||
int i;
|
||||
Vdbe *pVdbe;
|
||||
assert( sqlite3ThreadData()->useSharedData || pParse->nTableLock==0 );
|
||||
assert( sqlite3ThreadDataReadOnly()->useSharedData || pParse->nTableLock==0 );
|
||||
|
||||
if( 0==(pVdbe = sqlite3GetVdbe(pParse)) ){
|
||||
return;
|
||||
@@ -131,7 +130,7 @@ void sqlite3FinishCoding(Parse *pParse){
|
||||
sqlite3 *db;
|
||||
Vdbe *v;
|
||||
|
||||
if( sqlite3ThreadData()->mallocFailed ) return;
|
||||
if( sqlite3ThreadDataReadOnly()->mallocFailed ) return;
|
||||
if( pParse->nested ) return;
|
||||
if( !pParse->pVdbe ){
|
||||
if( pParse->rc==SQLITE_OK && pParse->nErr ){
|
||||
@@ -1363,7 +1362,7 @@ void sqlite3EndTable(
|
||||
int iDb;
|
||||
|
||||
if( (pEnd==0 && pSelect==0) ||
|
||||
pParse->nErr || sqlite3ThreadData()->mallocFailed ) {
|
||||
pParse->nErr || sqlite3ThreadDataReadOnly()->mallocFailed ) {
|
||||
return;
|
||||
}
|
||||
p = pParse->pNewTable;
|
||||
@@ -1600,7 +1599,7 @@ void sqlite3CreateView(
|
||||
*/
|
||||
p->pSelect = sqlite3SelectDup(pSelect);
|
||||
sqlite3SelectDelete(pSelect);
|
||||
if( sqlite3ThreadData()->mallocFailed ){
|
||||
if( sqlite3ThreadDataReadOnly()->mallocFailed ){
|
||||
return;
|
||||
}
|
||||
if( !pParse->db->init.busy ){
|
||||
@@ -1842,7 +1841,9 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){
|
||||
sqlite3 *db = pParse->db;
|
||||
int iDb;
|
||||
|
||||
if( pParse->nErr || sqlite3ThreadData()->mallocFailed ) goto exit_drop_table;
|
||||
if( pParse->nErr || sqlite3ThreadDataReadOnly()->mallocFailed ){
|
||||
goto exit_drop_table;
|
||||
}
|
||||
assert( pName->nSrc==1 );
|
||||
pTab = sqlite3LocateTable(pParse, pName->a[0].zName, pName->a[0].zDatabase);
|
||||
|
||||
@@ -2201,7 +2202,7 @@ void sqlite3CreateIndex(
|
||||
int nExtra = 0;
|
||||
char *zExtra;
|
||||
|
||||
if( pParse->nErr || sqlite3ThreadData()->mallocFailed ){
|
||||
if( pParse->nErr || sqlite3ThreadDataReadOnly()->mallocFailed ){
|
||||
goto exit_create_index;
|
||||
}
|
||||
|
||||
@@ -2355,7 +2356,7 @@ void sqlite3CreateIndex(
|
||||
nName + 1 + /* Index.zName */
|
||||
nExtra /* Collation sequence names */
|
||||
);
|
||||
if( sqlite3ThreadData()->mallocFailed ) goto exit_create_index;
|
||||
if( sqlite3ThreadDataReadOnly()->mallocFailed ) goto exit_create_index;
|
||||
pIndex->aiColumn = (int *)(&pIndex[1]);
|
||||
pIndex->aiRowEst = (int *)(&pIndex->aiColumn[nCol]);
|
||||
pIndex->azColl = (char **)(&pIndex->aiRowEst[nCol+1]);
|
||||
@@ -2642,7 +2643,7 @@ void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists){
|
||||
sqlite3 *db = pParse->db;
|
||||
int iDb;
|
||||
|
||||
if( pParse->nErr || sqlite3ThreadData()->mallocFailed ){
|
||||
if( pParse->nErr || sqlite3ThreadDataReadOnly()->mallocFailed ){
|
||||
goto exit_drop_index;
|
||||
}
|
||||
assert( pName->nSrc==1 );
|
||||
@@ -2851,7 +2852,7 @@ SrcList *sqlite3SrcListAppend(SrcList *pList, Token *pTable, Token *pDatabase){
|
||||
void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){
|
||||
int i;
|
||||
struct SrcList_item *pItem;
|
||||
assert(pList || sqlite3ThreadData()->mallocFailed);
|
||||
assert(pList || sqlite3ThreadDataReadOnly()->mallocFailed);
|
||||
if( pList ){
|
||||
for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
|
||||
if( pItem->iCursor>=0 ) break;
|
||||
@@ -2900,7 +2901,7 @@ void sqlite3BeginTransaction(Parse *pParse, int type){
|
||||
int i;
|
||||
|
||||
if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
|
||||
if( pParse->nErr || sqlite3ThreadData()->mallocFailed ) return;
|
||||
if( pParse->nErr || sqlite3ThreadDataReadOnly()->mallocFailed ) return;
|
||||
if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0, 0) ) return;
|
||||
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
@@ -2921,7 +2922,7 @@ void sqlite3CommitTransaction(Parse *pParse){
|
||||
Vdbe *v;
|
||||
|
||||
if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
|
||||
if( pParse->nErr || sqlite3ThreadData()->mallocFailed ) return;
|
||||
if( pParse->nErr || sqlite3ThreadDataReadOnly()->mallocFailed ) return;
|
||||
if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0, 0) ) return;
|
||||
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
@@ -2938,7 +2939,7 @@ void sqlite3RollbackTransaction(Parse *pParse){
|
||||
Vdbe *v;
|
||||
|
||||
if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
|
||||
if( pParse->nErr || sqlite3ThreadData()->mallocFailed ) return;
|
||||
if( pParse->nErr || sqlite3ThreadDataReadOnly()->mallocFailed ) return;
|
||||
if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "ROLLBACK", 0, 0) ) return;
|
||||
|
||||
v = sqlite3GetVdbe(pParse);
|
||||
@@ -3212,4 +3213,3 @@ KeyInfo *sqlite3IndexKeyinfo(Parse *pParse, Index *pIdx){
|
||||
}
|
||||
return pKey;
|
||||
}
|
||||
|
||||
|
@@ -13,7 +13,7 @@
|
||||
** This file contains functions used to access the internal hash tables
|
||||
** of user defined functions and collation sequences.
|
||||
**
|
||||
** $Id: callback.c,v 1.10 2006/01/10 17:58:23 danielk1977 Exp $
|
||||
** $Id: callback.c,v 1.11 2006/01/11 21:41:22 drh Exp $
|
||||
*/
|
||||
|
||||
#include "sqliteInt.h"
|
||||
@@ -178,7 +178,8 @@ static CollSeq *findCollSeqEntry(
|
||||
** return the pColl pointer to be deleted (because it wasn't added
|
||||
** to the hash table).
|
||||
*/
|
||||
assert( !pDel || (sqlite3ThreadData()->mallocFailed && pDel==pColl) );
|
||||
assert( !pDel ||
|
||||
(sqlite3ThreadDataReadOnly()->mallocFailed && pDel==pColl) );
|
||||
sqliteFree(pDel);
|
||||
}
|
||||
}
|
||||
|
@@ -12,7 +12,7 @@
|
||||
** This file contains C code routines that are called by the parser
|
||||
** in order to generate code for DELETE FROM statements.
|
||||
**
|
||||
** $Id: delete.c,v 1.117 2006/01/10 17:58:23 danielk1977 Exp $
|
||||
** $Id: delete.c,v 1.118 2006/01/11 21:41:22 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@@ -108,7 +108,7 @@ void sqlite3DeleteFrom(
|
||||
#endif
|
||||
|
||||
sContext.pParse = 0;
|
||||
if( pParse->nErr || sqlite3ThreadData()->mallocFailed ){
|
||||
if( pParse->nErr || sqlite3ThreadDataReadOnly()->mallocFailed ){
|
||||
goto delete_from_cleanup;
|
||||
}
|
||||
db = pParse->db;
|
||||
|
13
src/expr.c
13
src/expr.c
@@ -12,7 +12,7 @@
|
||||
** This file contains routines used for analyzing expressions and
|
||||
** for generating VDBE code that evaluates expressions in SQLite.
|
||||
**
|
||||
** $Id: expr.c,v 1.247 2006/01/10 17:58:23 danielk1977 Exp $
|
||||
** $Id: expr.c,v 1.248 2006/01/11 21:41:22 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include <ctype.h>
|
||||
@@ -263,7 +263,7 @@ Expr *sqlite3ExprAnd(Expr *pLeft, Expr *pRight){
|
||||
void sqlite3ExprSpan(Expr *pExpr, Token *pLeft, Token *pRight){
|
||||
assert( pRight!=0 );
|
||||
assert( pLeft!=0 );
|
||||
if( !sqlite3ThreadData()->mallocFailed && pRight->z && pLeft->z ){
|
||||
if( !sqlite3ThreadDataReadOnly()->mallocFailed && pRight->z && pLeft->z ){
|
||||
assert( pLeft->dyn==0 || pLeft->z[pLeft->n]==0 );
|
||||
if( pLeft->dyn==0 && pRight->dyn==0 ){
|
||||
pExpr->span.z = pLeft->z;
|
||||
@@ -358,7 +358,7 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){
|
||||
sqlite3ReallocOrFree((void**)&pParse->apVarExpr,
|
||||
pParse->nVarExprAlloc*sizeof(pParse->apVarExpr[0]) );
|
||||
}
|
||||
if( !sqlite3ThreadData()->mallocFailed ){
|
||||
if( !sqlite3ThreadDataReadOnly()->mallocFailed ){
|
||||
assert( pParse->apVarExpr!=0 );
|
||||
pParse->apVarExpr[pParse->nVarExpr++] = pExpr;
|
||||
}
|
||||
@@ -462,7 +462,8 @@ ExprList *sqlite3ExprListDup(ExprList *p){
|
||||
sqlite3TokenCopy(&pNewExpr->span, &pOldExpr->span);
|
||||
}
|
||||
assert( pNewExpr==0 || pNewExpr->span.z!=0
|
||||
|| pOldExpr->span.z==0 || sqlite3ThreadData()->mallocFailed );
|
||||
|| pOldExpr->span.z==0
|
||||
|| sqlite3ThreadDataReadOnly()->mallocFailed );
|
||||
pItem->zName = sqliteStrDup(pOldItem->zName);
|
||||
pItem->sortOrder = pOldItem->sortOrder;
|
||||
pItem->isAgg = pOldItem->isAgg;
|
||||
@@ -831,7 +832,7 @@ static int lookupName(
|
||||
zDb = sqlite3NameFromToken(pDbToken);
|
||||
zTab = sqlite3NameFromToken(pTableToken);
|
||||
zCol = sqlite3NameFromToken(pColumnToken);
|
||||
if( sqlite3ThreadData()->mallocFailed ){
|
||||
if( sqlite3ThreadDataReadOnly()->mallocFailed ){
|
||||
goto lookupname_end;
|
||||
}
|
||||
|
||||
@@ -1308,7 +1309,7 @@ void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
|
||||
int mem = pParse->nMem++;
|
||||
sqlite3VdbeAddOp(v, OP_MemLoad, mem, 0);
|
||||
testAddr = sqlite3VdbeAddOp(v, OP_If, 0, 0);
|
||||
assert( testAddr>0 || sqlite3ThreadData()->mallocFailed );
|
||||
assert( testAddr>0 || sqlite3ThreadDataReadOnly()->mallocFailed );
|
||||
sqlite3VdbeAddOp(v, OP_MemInt, 1, mem);
|
||||
}
|
||||
|
||||
|
10
src/insert.c
10
src/insert.c
@@ -12,7 +12,7 @@
|
||||
** This file contains C code routines that are called by the parser
|
||||
** to handle INSERT statements in SQLite.
|
||||
**
|
||||
** $Id: insert.c,v 1.156 2006/01/10 17:58:23 danielk1977 Exp $
|
||||
** $Id: insert.c,v 1.157 2006/01/11 21:41:22 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@@ -225,7 +225,9 @@ void sqlite3Insert(
|
||||
int counterRowid; /* Memory cell holding rowid of autoinc counter */
|
||||
#endif
|
||||
|
||||
if( pParse->nErr || sqlite3ThreadData()->mallocFailed ) goto insert_cleanup;
|
||||
if( pParse->nErr || sqlite3ThreadDataReadOnly()->mallocFailed ){
|
||||
goto insert_cleanup;
|
||||
}
|
||||
db = pParse->db;
|
||||
|
||||
/* Locate the table into which we will be inserting new information.
|
||||
@@ -331,7 +333,9 @@ void sqlite3Insert(
|
||||
|
||||
/* Resolve the expressions in the SELECT statement and execute it. */
|
||||
rc = sqlite3Select(pParse, pSelect, SRT_Subroutine, iInsertBlock,0,0,0,0);
|
||||
if( rc || pParse->nErr || sqlite3ThreadData()->mallocFailed ) goto insert_cleanup;
|
||||
if( rc || pParse->nErr || sqlite3ThreadDataReadOnly()->mallocFailed ){
|
||||
goto insert_cleanup;
|
||||
}
|
||||
|
||||
iCleanup = sqlite3VdbeMakeLabel(v);
|
||||
sqlite3VdbeAddOp(v, OP_Goto, 0, iCleanup);
|
||||
|
@@ -14,7 +14,7 @@
|
||||
** other files are for internal use by SQLite and should not be
|
||||
** accessed by users of the library.
|
||||
**
|
||||
** $Id: legacy.c,v 1.10 2006/01/09 06:29:49 danielk1977 Exp $
|
||||
** $Id: legacy.c,v 1.11 2006/01/11 21:41:22 drh Exp $
|
||||
*/
|
||||
|
||||
#include "sqliteInt.h"
|
||||
@@ -121,7 +121,7 @@ exec_out:
|
||||
if( pStmt ) sqlite3_finalize(pStmt);
|
||||
if( azCols ) sqliteFree(azCols);
|
||||
|
||||
if( sqlite3ThreadData()->mallocFailed ){
|
||||
if( sqlite3ThreadDataReadOnly()->mallocFailed ){
|
||||
rc = SQLITE_NOMEM;
|
||||
sqlite3MallocClearFailed();
|
||||
}
|
||||
|
25
src/main.c
25
src/main.c
@@ -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.322 2006/01/10 13:58:48 drh Exp $
|
||||
** $Id: main.c,v 1.323 2006/01/11 21:41:22 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "os.h"
|
||||
@@ -176,9 +176,9 @@ int sqlite3_close(sqlite3 *db){
|
||||
** structure?
|
||||
*/
|
||||
sqliteFree(db->aDb[1].pSchema);
|
||||
|
||||
sqliteFree(db);
|
||||
sqlite3MallocAllow();
|
||||
sqlite3ReleaseThreadData();
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
@@ -645,7 +645,7 @@ int sqlite3BtreeFactory(
|
||||
*/
|
||||
const char *sqlite3_errmsg(sqlite3 *db){
|
||||
const char *z;
|
||||
if( sqlite3ThreadData()->mallocFailed ){
|
||||
if( sqlite3ThreadDataReadOnly()->mallocFailed ){
|
||||
return sqlite3ErrStr(SQLITE_NOMEM);
|
||||
}
|
||||
if( sqlite3SafetyCheck(db) || db->errCode==SQLITE_MISUSE ){
|
||||
@@ -684,7 +684,7 @@ const void *sqlite3_errmsg16(sqlite3 *db){
|
||||
};
|
||||
|
||||
const void *z;
|
||||
if( sqlite3ThreadData()->mallocFailed ){
|
||||
if( sqlite3ThreadDataReadOnly()->mallocFailed ){
|
||||
return (void *)(&outOfMemBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]);
|
||||
}
|
||||
if( sqlite3SafetyCheck(db) || db->errCode==SQLITE_MISUSE ){
|
||||
@@ -705,7 +705,7 @@ const void *sqlite3_errmsg16(sqlite3 *db){
|
||||
** passed to this function, we assume a malloc() failed during sqlite3_open().
|
||||
*/
|
||||
int sqlite3_errcode(sqlite3 *db){
|
||||
if( !db || sqlite3ThreadData()->mallocFailed ){
|
||||
if( !db || sqlite3ThreadDataReadOnly()->mallocFailed ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
if( sqlite3SafetyCheck(db) ){
|
||||
@@ -727,7 +727,7 @@ static int openDatabase(
|
||||
int rc;
|
||||
CollSeq *pColl;
|
||||
|
||||
assert( !sqlite3ThreadData()->mallocFailed );
|
||||
assert( !sqlite3ThreadDataReadOnly()->mallocFailed );
|
||||
|
||||
/* Allocate the sqlite data structure */
|
||||
db = sqliteMalloc( sizeof(sqlite3) );
|
||||
@@ -854,7 +854,7 @@ int sqlite3_open16(
|
||||
rc = sqlite3_exec(*ppDb, "PRAGMA encoding = 'UTF-16'", 0, 0, 0);
|
||||
}
|
||||
}else{
|
||||
assert( sqlite3ThreadData()->mallocFailed );
|
||||
assert( sqlite3ThreadDataReadOnly()->mallocFailed );
|
||||
sqlite3MallocClearFailed();
|
||||
}
|
||||
sqlite3ValueFree(pVal);
|
||||
@@ -1077,6 +1077,17 @@ int sqlite3_enable_shared_cache(int enable){
|
||||
}
|
||||
|
||||
pTd->useSharedData = enable;
|
||||
sqlite3ReleaseThreadData();
|
||||
return SQLITE_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** This is a convenience routine that makes sure that all thread-specific
|
||||
** data for this thread has been deallocated.
|
||||
*/
|
||||
void sqlite3_thread_cleanup(void){
|
||||
ThreadData *pTd = sqlite3ThreadData();
|
||||
memset(pTd, 0, sizeof(*pTd));
|
||||
sqlite3ReleaseThreadData();
|
||||
}
|
||||
|
4
src/os.h
4
src/os.h
@@ -292,7 +292,7 @@ int sqlite3OsCurrentTime(double*);
|
||||
void sqlite3OsEnterMutex(void);
|
||||
void sqlite3OsLeaveMutex(void);
|
||||
int sqlite3OsInMutex(void);
|
||||
void *sqlite3OsThreadSpecificData(int);
|
||||
ThreadData *sqlite3OsThreadSpecificData(int);
|
||||
void *sqlite3OsMalloc(int);
|
||||
void *sqlite3OsRealloc(void *, int);
|
||||
void sqlite3OsFree(void *);
|
||||
@@ -335,7 +335,7 @@ struct sqlite3OsVtbl {
|
||||
void (*xEnterMutex)(void);
|
||||
void (*xLeaveMutex)(void);
|
||||
int (*xInMutex)(void);
|
||||
void *(*xThreadSpecificData)(int);
|
||||
ThreadData *(*xThreadSpecificData)(int);
|
||||
|
||||
void *(*xMalloc)(int);
|
||||
void *(*xRealloc)(void *, int);
|
||||
|
@@ -1627,38 +1627,27 @@ int sqlite3UnixInMutex(){
|
||||
}
|
||||
|
||||
/*
|
||||
** This function is called automatically when a thread exists to delete
|
||||
** the threads ThreadData structure.
|
||||
** If called with allocateFlag==1, then return a pointer to thread
|
||||
** specific data for the current thread. Allocate and zero the
|
||||
** thread-specific data if it does not already exist necessary.
|
||||
**
|
||||
** Because the ThreadData structure is required by higher level routines
|
||||
** such as sqliteMalloc() we use OsFree() and OsMalloc() directly to
|
||||
** allocate the thread specific data.
|
||||
** If called with allocateFlag==0, then check the current thread
|
||||
** specific data. If it exists and is all zeros, then deallocate it.
|
||||
** Return a pointer to the thread specific data or NULL if it is
|
||||
** unallocated.
|
||||
*/
|
||||
#ifdef SQLITE_UNIX_THREADS
|
||||
static void deleteTsd(void *pTsd){
|
||||
sqlite3OsFree(pTsd);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** The first time this function is called from a specific thread, nByte
|
||||
** bytes of data area are allocated and zeroed. A pointer to the new
|
||||
** allocation is returned to the caller.
|
||||
**
|
||||
** Each subsequent call to this function from the thread returns the same
|
||||
** pointer. The argument is ignored in this case.
|
||||
*/
|
||||
void *sqlite3UnixThreadSpecificData(int nByte){
|
||||
ThreadData *sqlite3UnixThreadSpecificData(int allocateFlag){
|
||||
static const ThreadData zeroData;
|
||||
#ifdef SQLITE_UNIX_THREADS
|
||||
static pthread_key_t key;
|
||||
static int keyInit = 0;
|
||||
void *pTsd;
|
||||
ThreadData *pTsd;
|
||||
|
||||
if( !keyInit ){
|
||||
sqlite3OsEnterMutex();
|
||||
if( !keyInit ){
|
||||
int rc;
|
||||
rc = pthread_key_create(&key, deleteTsd);
|
||||
rc = pthread_key_create(&key, 0);
|
||||
if( rc ){
|
||||
sqlite3OsLeaveMutex();
|
||||
return 0;
|
||||
@@ -1669,21 +1658,32 @@ void *sqlite3UnixThreadSpecificData(int nByte){
|
||||
}
|
||||
|
||||
pTsd = pthread_getspecific(key);
|
||||
if( !pTsd ){
|
||||
pTsd = sqlite3OsMalloc(nByte);
|
||||
if( pTsd ){
|
||||
memset(pTsd, 0, nByte);
|
||||
pthread_setspecific(key, pTsd);
|
||||
if( allocateFlag ){
|
||||
if( pTsd==0 ){
|
||||
pTsd = sqlite3OsMalloc(sizeof(zeroData));
|
||||
if( pTsd ){
|
||||
*pTsd = zeroData;
|
||||
pthread_setspecific(key, pTsd);
|
||||
}
|
||||
}
|
||||
}else if( pTsd!=0 && memcmp(pTsd, &zeroData, sizeof(zeroData))==0 ){
|
||||
sqlite3OsFree(pTsd);
|
||||
pthread_setspecific(key, 0);
|
||||
pTsd = 0;
|
||||
}
|
||||
return pTsd;
|
||||
#else
|
||||
static void *pTsd = 0;
|
||||
if( !pTsd ){
|
||||
pTsd = sqlite3OsMalloc(nByte);
|
||||
if( pTsd ){
|
||||
memset(pTsd, 0, nByte);
|
||||
static ThreadData *pTsd = 0;
|
||||
if( allocateFlag ){
|
||||
if( pTsd==0 ){
|
||||
pTsd = sqlite3OsMalloc( sizeof(zeroData) );
|
||||
if( pTsd ){
|
||||
*pTsd = zeroData;
|
||||
}
|
||||
}
|
||||
}else if( pTsd!=0 && memcmp(pTsd, &zeroData, sizeof(zeroData))==0 ){
|
||||
sqlite3OsFree(pTsd);
|
||||
pTsd = 0;
|
||||
}
|
||||
return pTsd;
|
||||
#endif
|
||||
|
33
src/os_win.c
33
src/os_win.c
@@ -1148,18 +1148,21 @@ int sqlite3WinCurrentTime(double *prNow){
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** The first time this function is called from a specific thread, nByte
|
||||
** bytes of data area are allocated and zeroed. A pointer to the new
|
||||
** allocation is returned to the caller.
|
||||
/*
|
||||
** If called with allocateFlag==1, then return a pointer to thread
|
||||
** specific data for the current thread. Allocate and zero the
|
||||
** thread-specific data if it does not already exist necessary.
|
||||
**
|
||||
** Each subsequent call to this function from the thread returns the same
|
||||
** pointer. The argument is ignored in this case.
|
||||
** If called with allocateFlag==0, then check the current thread
|
||||
** specific data. If it exists and is all zeros, then deallocate it.
|
||||
** Return a pointer to the thread specific data or NULL if it is
|
||||
** unallocated.
|
||||
*/
|
||||
void *sqlite3WinThreadSpecificData(int nByte){
|
||||
void *sqlite3WinThreadSpecificData(int allocateFlag){
|
||||
static void *pTsd = 0;
|
||||
static int key;
|
||||
static int keyInit = 0;
|
||||
static const ThreadData zeroData;
|
||||
|
||||
if( !keyInit ){
|
||||
sqlite3OsEnterMutex();
|
||||
@@ -1174,12 +1177,18 @@ void *sqlite3WinThreadSpecificData(int nByte){
|
||||
sqlite3OsLeaveMutex();
|
||||
}
|
||||
pTsd = TlsGetValue(key);
|
||||
if( !pTsd ){
|
||||
pTsd = sqlite3OsMalloc(nByte);
|
||||
if( pTsd ){
|
||||
memset(pTsd, 0, nByte);
|
||||
TlsSetValue(key, pTsd);
|
||||
if( allocateFlag ){
|
||||
if( !pTsd ){
|
||||
pTsd = sqlite3OsMalloc(nByte);
|
||||
if( pTsd ){
|
||||
*pTsd = zeroData;
|
||||
TlsSetValue(key, pTsd);
|
||||
}
|
||||
}
|
||||
}else if( pTsd!=0 && memcmp(pTsd, &zeroData, sizeof(zeroData))==0 ){
|
||||
sqlite3OsFree(pTsd);
|
||||
TlsSetValue(key, 0);
|
||||
pTsd = 0;
|
||||
}
|
||||
return pTsd;
|
||||
}
|
||||
|
29
src/pager.c
29
src/pager.c
@@ -18,7 +18,7 @@
|
||||
** file simultaneously, or one process from reading the database while
|
||||
** another is writing.
|
||||
**
|
||||
** @(#) $Id: pager.c,v 1.235 2006/01/10 20:32:32 drh Exp $
|
||||
** @(#) $Id: pager.c,v 1.236 2006/01/11 21:41:22 drh Exp $
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_DISKIO
|
||||
#include "sqliteInt.h"
|
||||
@@ -284,7 +284,7 @@ struct Pager {
|
||||
void (*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */
|
||||
void *pCodecArg; /* First argument to xCodec() */
|
||||
PgHdr *aHash[N_PG_HASH]; /* Hash table to map page number to PgHdr */
|
||||
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
|
||||
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
|
||||
Pager *pNext; /* Linked list of pagers in this thread */
|
||||
#endif
|
||||
};
|
||||
@@ -1618,8 +1618,8 @@ int sqlite3pager_open(
|
||||
int useJournal = (flags & PAGER_OMIT_JOURNAL)==0;
|
||||
int noReadlock = (flags & PAGER_NO_READLOCK)!=0;
|
||||
char zTemp[SQLITE_TEMPNAME_SIZE];
|
||||
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
|
||||
ThreadData *pTsd = sqlite3ThreadData();
|
||||
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
|
||||
const ThreadData *pTsdro = sqlite3ThreadDataReadOnly();
|
||||
#endif
|
||||
|
||||
/* If malloc() has already failed return SQLITE_NOMEM. Before even
|
||||
@@ -1627,7 +1627,7 @@ int sqlite3pager_open(
|
||||
** structure was never allocated.
|
||||
*/
|
||||
*ppPager = 0;
|
||||
if( sqlite3ThreadData()->mallocFailed ){
|
||||
if( sqlite3ThreadDataReadOnly()->mallocFailed ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
memset(&fd, 0, sizeof(fd));
|
||||
@@ -1720,8 +1720,9 @@ int sqlite3pager_open(
|
||||
pPager->pBusyHandler = 0;
|
||||
memset(pPager->aHash, 0, sizeof(pPager->aHash));
|
||||
*ppPager = pPager;
|
||||
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
|
||||
if( pTsd->useMemoryManagement ){
|
||||
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
|
||||
if( pTsdro->useMemoryManagement ){
|
||||
ThreadData *pTsd = sqlite3ThreadData();
|
||||
pPager->pNext = pTsd->pPager;
|
||||
pTsd->pPager = pPager;
|
||||
}
|
||||
@@ -2027,8 +2028,8 @@ int sqlite3pager_truncate(Pager *pPager, Pgno nPage){
|
||||
*/
|
||||
int sqlite3pager_close(Pager *pPager){
|
||||
PgHdr *pPg, *pNext;
|
||||
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
|
||||
ThreadData *pTsd = sqlite3ThreadData();
|
||||
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
|
||||
const ThreadData *pTsd = sqlite3ThreadDataReadOnly();
|
||||
#endif
|
||||
|
||||
switch( pPager->state ){
|
||||
@@ -2087,7 +2088,7 @@ int sqlite3pager_close(Pager *pPager){
|
||||
** }
|
||||
*/
|
||||
|
||||
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
|
||||
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
|
||||
/* Remove the pager from the linked list of pagers starting at
|
||||
** ThreadData.pPager if memory-management is enabled.
|
||||
*/
|
||||
@@ -2456,9 +2457,9 @@ static int pager_recycle(Pager *pPager, int syncOk, PgHdr **ppPg){
|
||||
** free as much memory as possible. The return value is the total number
|
||||
** of bytes of memory released.
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
|
||||
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
|
||||
int sqlite3pager_release_memory(int nReq){
|
||||
ThreadData *pTsd = sqlite3ThreadData();
|
||||
const ThreadData *pTsdro = sqlite3ThreadDataReadOnly();
|
||||
Pager *p;
|
||||
int nReleased = 0;
|
||||
int i;
|
||||
@@ -2481,7 +2482,7 @@ int sqlite3pager_release_memory(int nReq){
|
||||
for(i=0; i<=1; i++){
|
||||
|
||||
/* Loop through all the SQLite pagers opened by the current thread. */
|
||||
for(p=pTsd->pPager; p && (nReq<0 || nReleased<nReq); p=p->pNext){
|
||||
for(p=pTsdro->pPager; p && (nReq<0 || nReleased<nReq); p=p->pNext){
|
||||
PgHdr *pPg;
|
||||
int rc;
|
||||
|
||||
@@ -2527,7 +2528,7 @@ int sqlite3pager_release_memory(int nReq){
|
||||
|
||||
return nReleased;
|
||||
}
|
||||
#endif /* SQLITE_OMIT_MEMORY_MANAGEMENT */
|
||||
#endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */
|
||||
|
||||
/*
|
||||
** Acquire a page.
|
||||
|
@@ -13,7 +13,7 @@
|
||||
** interface, and routines that contribute to loading the database schema
|
||||
** from disk.
|
||||
**
|
||||
** $Id: prepare.c,v 1.19 2006/01/11 14:09:32 danielk1977 Exp $
|
||||
** $Id: prepare.c,v 1.20 2006/01/11 21:41:22 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "os.h"
|
||||
@@ -24,7 +24,7 @@
|
||||
** that the database is corrupt.
|
||||
*/
|
||||
static void corruptSchema(InitData *pData, const char *zExtra){
|
||||
if( !sqlite3ThreadData()->mallocFailed ){
|
||||
if( !sqlite3ThreadDataReadOnly()->mallocFailed ){
|
||||
sqlite3SetString(pData->pzErrMsg, "malformed database schema",
|
||||
zExtra!=0 && zExtra[0]!=0 ? " - " : (char*)0, zExtra, (char*)0);
|
||||
}
|
||||
@@ -49,7 +49,7 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **azColName){
|
||||
sqlite3 *db = pData->db;
|
||||
int iDb;
|
||||
|
||||
if( sqlite3ThreadData()->mallocFailed ){
|
||||
if( sqlite3ThreadDataReadOnly()->mallocFailed ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
|
||||
@@ -303,7 +303,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
|
||||
#endif
|
||||
sqlite3BtreeCloseCursor(curMain);
|
||||
}
|
||||
if( sqlite3ThreadData()->mallocFailed ){
|
||||
if( sqlite3ThreadDataReadOnly()->mallocFailed ){
|
||||
sqlite3SetString(pzErrMsg, "out of memory", (char*)0);
|
||||
rc = SQLITE_NOMEM;
|
||||
sqlite3ResetInternalSchema(db, 0);
|
||||
@@ -494,7 +494,7 @@ int sqlite3_prepare(
|
||||
int rc = SQLITE_OK;
|
||||
int i;
|
||||
|
||||
assert( !sqlite3ThreadData()->mallocFailed );
|
||||
assert( !sqlite3ThreadDataReadOnly()->mallocFailed );
|
||||
|
||||
assert( ppStmt );
|
||||
*ppStmt = 0;
|
||||
@@ -519,7 +519,7 @@ int sqlite3_prepare(
|
||||
sParse.db = db;
|
||||
sqlite3RunParser(&sParse, zSql, &zErrMsg);
|
||||
|
||||
if( sqlite3ThreadData()->mallocFailed ){
|
||||
if( sqlite3ThreadDataReadOnly()->mallocFailed ){
|
||||
sParse.rc = SQLITE_NOMEM;
|
||||
}
|
||||
if( sParse.rc==SQLITE_DONE ) sParse.rc = SQLITE_OK;
|
||||
@@ -569,7 +569,7 @@ int sqlite3_prepare(
|
||||
/* We must check for malloc failure last of all, in case malloc() failed
|
||||
** inside of the sqlite3Error() call above or something.
|
||||
*/
|
||||
if( sqlite3ThreadData()->mallocFailed ){
|
||||
if( sqlite3ThreadDataReadOnly()->mallocFailed ){
|
||||
rc = SQLITE_NOMEM;
|
||||
sqlite3Error(db, rc, 0);
|
||||
}
|
||||
|
17
src/select.c
17
src/select.c
@@ -12,7 +12,7 @@
|
||||
** This file contains C code routines that are called by the parser
|
||||
** to handle SELECT statements in SQLite.
|
||||
**
|
||||
** $Id: select.c,v 1.292 2006/01/10 17:58:23 danielk1977 Exp $
|
||||
** $Id: select.c,v 1.293 2006/01/11 21:41:22 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@@ -872,7 +872,8 @@ static void generateColumnNames(
|
||||
#endif
|
||||
|
||||
assert( v!=0 );
|
||||
if( pParse->colNamesSet || v==0 || sqlite3ThreadData()->mallocFailed ) return;
|
||||
if( pParse->colNamesSet || v==0
|
||||
|| sqlite3ThreadDataReadOnly()->mallocFailed ) return;
|
||||
pParse->colNamesSet = 1;
|
||||
fullNames = (db->flags & SQLITE_FullColNames)!=0;
|
||||
shortNames = (db->flags & SQLITE_ShortColNames)!=0;
|
||||
@@ -1001,7 +1002,7 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){
|
||||
zName = sqlite3MPrintf("column%d", i+1);
|
||||
}
|
||||
sqlite3Dequote(zName);
|
||||
if( sqlite3ThreadData()->mallocFailed ){
|
||||
if( sqlite3ThreadDataReadOnly()->mallocFailed ){
|
||||
sqliteFree(zName);
|
||||
sqlite3DeleteTable(0, pTab);
|
||||
return 0;
|
||||
@@ -1073,7 +1074,9 @@ static int prepSelectStmt(Parse *pParse, Select *p){
|
||||
Table *pTab;
|
||||
struct SrcList_item *pFrom;
|
||||
|
||||
if( p==0 || p->pSrc==0 || sqlite3ThreadData()->mallocFailed ) return 1;
|
||||
if( p==0 || p->pSrc==0 || sqlite3ThreadDataReadOnly()->mallocFailed ){
|
||||
return 1;
|
||||
}
|
||||
pTabList = p->pSrc;
|
||||
pEList = p->pEList;
|
||||
|
||||
@@ -2690,7 +2693,9 @@ int sqlite3Select(
|
||||
AggInfo sAggInfo; /* Information used by aggregate queries */
|
||||
int iEnd; /* Address of the end of the query */
|
||||
|
||||
if( sqlite3ThreadData()->mallocFailed || pParse->nErr || p==0 ) return 1;
|
||||
if( p==0 || sqlite3ThreadDataReadOnly()->mallocFailed || pParse->nErr ){
|
||||
return 1;
|
||||
}
|
||||
if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
|
||||
memset(&sAggInfo, 0, sizeof(sAggInfo));
|
||||
|
||||
@@ -2944,7 +2949,7 @@ int sqlite3Select(
|
||||
goto select_end;
|
||||
}
|
||||
}
|
||||
if( sqlite3ThreadData()->mallocFailed ) goto select_end;
|
||||
if( sqlite3ThreadDataReadOnly()->mallocFailed ) goto select_end;
|
||||
|
||||
/* Processing for aggregates with GROUP BY is very different and
|
||||
** much more complex tha aggregates without a GROUP BY.
|
||||
|
@@ -12,7 +12,7 @@
|
||||
** This header file defines the interface that the SQLite library
|
||||
** presents to client programs.
|
||||
**
|
||||
** @(#) $Id: sqlite.h.in,v 1.154 2006/01/10 15:18:28 drh Exp $
|
||||
** @(#) $Id: sqlite.h.in,v 1.155 2006/01/11 21:41:22 drh Exp $
|
||||
*/
|
||||
#ifndef _SQLITE3_H_
|
||||
#define _SQLITE3_H_
|
||||
@@ -1329,21 +1329,13 @@ void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
|
||||
*/
|
||||
int sqlite3_enable_shared_cache(int);
|
||||
|
||||
/*
|
||||
** This function is only available if the library is compiled without
|
||||
** the SQLITE_OMIT_MEMORY_MANAGEMENT macro defined. It is used to enable or
|
||||
** disable (if the argument is true or false, respectively) the
|
||||
** "memory management" features (accessed via the sqlite3_soft_heap_limit()
|
||||
** and sqlite3_release_memory() APIs).
|
||||
*/
|
||||
int sqlite3_enable_memory_management(int);
|
||||
|
||||
/*
|
||||
** Attempt to free N bytes of heap memory by deallocating non-essential
|
||||
** memory allocations held by the database library (example: memory
|
||||
** used to cache database pages to improve performance).
|
||||
**
|
||||
** This function is a no-op unless memory-management has been enabled.
|
||||
** This function is not a part of standard builds. It is only created
|
||||
** if SQLite is compiled with the SQLITE_ENABLE_MEMORY_MANAGEMENT macro.
|
||||
*/
|
||||
int sqlite3_release_memory(int);
|
||||
|
||||
@@ -1357,12 +1349,25 @@ int sqlite3_release_memory(int);
|
||||
** sufficient memory to prevent the limit from being exceeded, the memory is
|
||||
** allocated anyway and the current operation proceeds.
|
||||
**
|
||||
** This function is only available if the library was compiled without the
|
||||
** SQLITE_OMIT_MEMORY_MANAGEMENT option set. It is a no-op unless
|
||||
** This function is only available if the library was compiled with the
|
||||
** SQLITE_ENABLE_MEMORY_MANAGEMENT option set.
|
||||
** memory-management has been enabled.
|
||||
*/
|
||||
void sqlite3_soft_heap_limit(int);
|
||||
|
||||
/*
|
||||
** 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);
|
||||
|
||||
/*
|
||||
** Undo the hack that converts floating point types to integer for
|
||||
** builds on processors without floating point support.
|
||||
|
@@ -11,7 +11,7 @@
|
||||
*************************************************************************
|
||||
** Internal interface definitions for SQLite.
|
||||
**
|
||||
** @(#) $Id: sqliteInt.h,v 1.461 2006/01/11 14:09:32 danielk1977 Exp $
|
||||
** @(#) $Id: sqliteInt.h,v 1.462 2006/01/11 21:41:22 drh Exp $
|
||||
*/
|
||||
#ifndef _SQLITEINT_H_
|
||||
#define _SQLITEINT_H_
|
||||
@@ -286,14 +286,17 @@ extern int sqlite3_iMallocReset; /* Set iMallocFail to this when it reaches 0 */
|
||||
#define sqliteAllocSize(x) sqlite3AllocSize(x)
|
||||
|
||||
/*
|
||||
** An instance of this structure is allocated for each thread that uses SQLite.
|
||||
** An instance of this structure might be allocated to store information
|
||||
** specific to a single thread.
|
||||
**
|
||||
** To avoid a memory leak on windows, the content of this structure is
|
||||
** checked at the conclusion of each API call. If it is all zero, it
|
||||
** is deallocated.
|
||||
*/
|
||||
struct ThreadData {
|
||||
u8 isInit; /* True if structure has been initialised */
|
||||
u8 mallocFailed; /* True after a malloc() has failed */
|
||||
|
||||
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
|
||||
u8 useMemoryManagement; /* True if memory-management is enabled */
|
||||
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
|
||||
int nSoftHeapLimit; /* Suggested max mem allocation. No limit if <0 */
|
||||
int nAlloc; /* Number of bytes currently allocated */
|
||||
Pager *pPager; /* Linked list of all pagers in this thread */
|
||||
@@ -306,7 +309,7 @@ struct ThreadData {
|
||||
|
||||
#ifdef SQLITE_MEMDEBUG
|
||||
int nMaxAlloc; /* High water mark of ThreadData.nAlloc */
|
||||
int mallocAllowed; /* assert() in sqlite3Malloc() if not set */
|
||||
int mallocDisallowed; /* assert() in sqlite3Malloc() if set */
|
||||
int isFail; /* True if all malloc() calls should fail */
|
||||
const char *zFile; /* Filename to associate debugging info with */
|
||||
int iLine; /* Line number to associate debugging info with */
|
||||
@@ -1730,7 +1733,9 @@ void sqlite3AnalysisLoad(sqlite3*,int iDB);
|
||||
void sqlite3DefaultRowEst(Index*);
|
||||
void sqlite3RegisterLikeFunctions(sqlite3*, int);
|
||||
int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*);
|
||||
ThreadData *sqlite3ThreadData();
|
||||
ThreadData *sqlite3ThreadData(void);
|
||||
const ThreadData *sqlite3ThreadDataReadOnly(void);
|
||||
void sqlite3ReleaseThreadData(void);
|
||||
void sqlite3AttachFunctions(sqlite3 *);
|
||||
void sqlite3MinimumFileFormat(Parse*, int, int);
|
||||
void sqlite3SchemaFree(void *);
|
||||
|
45
src/test1.c
45
src/test1.c
@@ -13,7 +13,7 @@
|
||||
** is not included in the SQLite library. It is used for automated
|
||||
** testing of the SQLite library.
|
||||
**
|
||||
** $Id: test1.c,v 1.187 2006/01/11 14:09:32 danielk1977 Exp $
|
||||
** $Id: test1.c,v 1.188 2006/01/11 21:41:22 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "tcl.h"
|
||||
@@ -903,9 +903,9 @@ static int sqlite_malloc_outstanding(
|
||||
){
|
||||
extern int sqlite3OutstandingMallocs(Tcl_Interp *interp);
|
||||
|
||||
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
|
||||
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
|
||||
if( objc==2 ){
|
||||
ThreadData *pTd = sqlite3ThreadData();
|
||||
const ThreadData *pTd = sqlite3ThreadDataReadOnly();
|
||||
const char *zArg = Tcl_GetString(objv[1]);
|
||||
if( 0==strcmp(zArg, "-bytes") ){
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(pTd->nAlloc));
|
||||
@@ -935,11 +935,10 @@ static int sqlite_malloc_outstanding(
|
||||
|
||||
/*
|
||||
** Usage: sqlite3_enable_shared_cache BOOLEAN
|
||||
** Usage: sqlite3_enable_memory_management BOOLEAN
|
||||
**
|
||||
*/
|
||||
#if !defined(SQLITE_OMIT_SHARED_CACHE)||!defined(SQLITE_OMIT_MEMORY_MANAGEMENT)
|
||||
static int test_enable(
|
||||
#if !defined(SQLITE_OMIT_SHARED_CACHE)
|
||||
static int test_enable_shared(
|
||||
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
|
||||
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
|
||||
int objc, /* Number of arguments */
|
||||
@@ -948,20 +947,7 @@ static int test_enable(
|
||||
int rc;
|
||||
int enable;
|
||||
int ret = 0;
|
||||
int (*xFunc)(int) = (int(*)(int))clientData;
|
||||
ThreadData *pTsd = sqlite3ThreadData();
|
||||
|
||||
#ifndef SQLITE_OMIT_SHARED_CACHE
|
||||
if( xFunc==sqlite3_enable_shared_cache ){
|
||||
ret = pTsd->useSharedData;
|
||||
}else
|
||||
#endif
|
||||
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
|
||||
{
|
||||
assert( xFunc==sqlite3_enable_memory_management );
|
||||
ret = pTsd->useMemoryManagement;
|
||||
}
|
||||
#endif
|
||||
if( objc!=2 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "BOOLEAN");
|
||||
return TCL_ERROR;
|
||||
@@ -969,7 +955,8 @@ static int test_enable(
|
||||
if( Tcl_GetBooleanFromObj(interp, objv[1], &enable) ){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
rc = xFunc(enable);
|
||||
ret = sqlite3ThreadDataReadOnly()->useSharedData;
|
||||
rc = sqlite3_enable_shared_cache(enable);
|
||||
if( rc!=SQLITE_OK ){
|
||||
Tcl_SetResult(interp, (char *)sqlite3ErrStr(rc), TCL_STATIC);
|
||||
return TCL_ERROR;
|
||||
@@ -2966,7 +2953,7 @@ static int test_release_memory(
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
#if !defined(SQLITE_OMIT_MEMORY_MANAGEMENT) && !defined(SQLITE_OMIT_DISKIO)
|
||||
#if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) && !defined(SQLITE_OMIT_DISKIO)
|
||||
int N;
|
||||
int amt;
|
||||
if( objc!=1 && objc!=2 ){
|
||||
@@ -2997,13 +2984,13 @@ static int test_soft_heap_limit(
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
#if !defined(SQLITE_OMIT_MEMORY_MANAGEMENT) && !defined(SQLITE_OMIT_DISKIO)
|
||||
#if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) && !defined(SQLITE_OMIT_DISKIO)
|
||||
int amt;
|
||||
if( objc!=1 && objc!=2 ){
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "?N?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
amt = sqlite3ThreadData()->nSoftHeapLimit;
|
||||
amt = sqlite3ThreadDataReadOnly()->nSoftHeapLimit;
|
||||
if( objc==2 ){
|
||||
int N;
|
||||
if( Tcl_GetIntFromObj(interp, objv[1], &N) ) return TCL_ERROR;
|
||||
@@ -3181,10 +3168,10 @@ static void set_options(Tcl_Interp *interp){
|
||||
Tcl_SetVar2(interp, "sqlite_options", "memorydb", "1", TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_OMIT_MEMORY_MANAGEMENT
|
||||
Tcl_SetVar2(interp, "sqlite_options", "memorymanage", "0", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
|
||||
Tcl_SetVar2(interp, "sqlite_options", "memorymanage", "1", TCL_GLOBAL_ONLY);
|
||||
#else
|
||||
Tcl_SetVar2(interp, "sqlite_options", "memorymanage", "0", TCL_GLOBAL_ONLY);
|
||||
#endif
|
||||
|
||||
#ifdef SQLITE_OMIT_OR_OPTIMIZATION
|
||||
@@ -3429,11 +3416,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
|
||||
{ "sqlite3_test_errstr", test_errstr, 0 },
|
||||
{ "tcl_variable_type", tcl_variable_type, 0 },
|
||||
#ifndef SQLITE_OMIT_SHARED_CACHE
|
||||
{ "sqlite3_enable_shared_cache", test_enable, sqlite3_enable_shared_cache},
|
||||
#endif
|
||||
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
|
||||
{ "sqlite3_enable_memory_management", test_enable,
|
||||
sqlite3_enable_memory_management},
|
||||
{ "sqlite3_enable_shared_cache", test_enable_shared, 0 },
|
||||
#endif
|
||||
};
|
||||
static int bitmask_size = sizeof(Bitmask)*8;
|
||||
|
@@ -15,7 +15,7 @@
|
||||
** individual tokens and sends those tokens one-by-one over to the
|
||||
** parser for analysis.
|
||||
**
|
||||
** $Id: tokenize.c,v 1.112 2006/01/09 06:29:49 danielk1977 Exp $
|
||||
** $Id: tokenize.c,v 1.113 2006/01/11 21:41:22 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "os.h"
|
||||
@@ -358,7 +358,7 @@ int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
|
||||
assert( pParse->nVarExprAlloc==0 );
|
||||
assert( pParse->apVarExpr==0 );
|
||||
pParse->zTail = pParse->zSql = zSql;
|
||||
while( sqlite3ThreadData()->mallocFailed==0 && zSql[i]!=0 ){
|
||||
while( sqlite3ThreadDataReadOnly()->mallocFailed==0 && zSql[i]!=0 ){
|
||||
assert( i>=0 );
|
||||
pParse->sLastToken.z = (u8*)&zSql[i];
|
||||
assert( pParse->sLastToken.dyn==0 );
|
||||
@@ -406,7 +406,7 @@ abort_parse:
|
||||
sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse);
|
||||
}
|
||||
sqlite3ParserFree(pEngine, sqlite3FreeX);
|
||||
if( sqlite3ThreadData()->mallocFailed ){
|
||||
if( sqlite3ThreadDataReadOnly()->mallocFailed ){
|
||||
pParse->rc = SQLITE_NOMEM;
|
||||
}
|
||||
if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){
|
||||
|
@@ -81,14 +81,16 @@ void sqlite3BeginTrigger(
|
||||
** If sqlite3SrcListLookup() returns 0, indicating the table does not
|
||||
** exist, the error is caught by the block below.
|
||||
*/
|
||||
if( !pTableName || sqlite3ThreadData()->mallocFailed ) goto trigger_cleanup;
|
||||
if( !pTableName || sqlite3ThreadDataReadOnly()->mallocFailed ){
|
||||
goto trigger_cleanup;
|
||||
}
|
||||
pTab = sqlite3SrcListLookup(pParse, pTableName);
|
||||
if( pName2->n==0 && pTab && pTab->pSchema==db->aDb[1].pSchema ){
|
||||
iDb = 1;
|
||||
}
|
||||
|
||||
/* Ensure the table name matches database name and that the table exists */
|
||||
if( sqlite3ThreadData()->mallocFailed ) goto trigger_cleanup;
|
||||
if( sqlite3ThreadDataReadOnly()->mallocFailed ) goto trigger_cleanup;
|
||||
assert( pTableName->nSrc==1 );
|
||||
if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", pName) &&
|
||||
sqlite3FixSrcList(&sFix, pTableName) ){
|
||||
@@ -255,7 +257,7 @@ void sqlite3FinishTrigger(
|
||||
pDel = sqlite3HashInsert(&db->aDb[iDb].pSchema->trigHash,
|
||||
pTrig->name, strlen(pTrig->name)+1, pTrig);
|
||||
if( pDel ){
|
||||
assert( sqlite3ThreadData()->mallocFailed && pDel==pTrig );
|
||||
assert( sqlite3ThreadDataReadOnly()->mallocFailed && pDel==pTrig );
|
||||
goto triggerfinish_cleanup;
|
||||
}
|
||||
n = strlen(pTrig->table) + 1;
|
||||
@@ -439,7 +441,7 @@ void sqlite3DropTrigger(Parse *pParse, SrcList *pName){
|
||||
int nName;
|
||||
sqlite3 *db = pParse->db;
|
||||
|
||||
if( sqlite3ThreadData()->mallocFailed ) goto drop_trigger_cleanup;
|
||||
if( sqlite3ThreadDataReadOnly()->mallocFailed ) goto drop_trigger_cleanup;
|
||||
if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
|
||||
goto drop_trigger_cleanup;
|
||||
}
|
||||
|
@@ -12,7 +12,7 @@
|
||||
** This file contains C code routines that are called by the parser
|
||||
** to handle UPDATE statements.
|
||||
**
|
||||
** $Id: update.c,v 1.119 2006/01/10 17:58:23 danielk1977 Exp $
|
||||
** $Id: update.c,v 1.120 2006/01/11 21:41:22 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@@ -100,7 +100,9 @@ void sqlite3Update(
|
||||
int oldIdx = -1; /* index of trigger "old" temp table */
|
||||
|
||||
sContext.pParse = 0;
|
||||
if( pParse->nErr || sqlite3ThreadData()->mallocFailed ) goto update_cleanup;
|
||||
if( pParse->nErr || sqlite3ThreadDataReadOnly()->mallocFailed ){
|
||||
goto update_cleanup;
|
||||
}
|
||||
db = pParse->db;
|
||||
assert( pTabList->nSrc==1 );
|
||||
|
||||
|
98
src/util.c
98
src/util.c
@@ -14,7 +14,7 @@
|
||||
** This file contains functions for allocating memory, comparing
|
||||
** strings, and stuff like that.
|
||||
**
|
||||
** $Id: util.c,v 1.167 2006/01/11 16:10:20 danielk1977 Exp $
|
||||
** $Id: util.c,v 1.168 2006/01/11 21:41:22 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "os.h"
|
||||
@@ -66,13 +66,14 @@
|
||||
|
||||
#define MAX(x,y) ((x)>(y)?(x):(y))
|
||||
|
||||
#if !defined(SQLITE_OMIT_MEMORY_MANAGEMENT) && !defined(SQLITE_OMIT_DISKIO)
|
||||
#if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) && !defined(SQLITE_OMIT_DISKIO)
|
||||
/*
|
||||
** Set the soft heap-size limit for the current thread. Passing a negative
|
||||
** value indicates no limit.
|
||||
*/
|
||||
void sqlite3_soft_heap_limit(int n){
|
||||
sqlite3ThreadData()->nSoftHeapLimit = n;
|
||||
sqlite3ReleaseThreadData();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -82,7 +83,7 @@ int sqlite3_release_memory(int n){
|
||||
return sqlite3pager_release_memory(n);
|
||||
}
|
||||
#else
|
||||
/* If SQLITE_OMIT_MEMORY_MANAGEMENT is defined, then define a version
|
||||
/* If SQLITE_ENABLE_MEMORY_MANAGEMENT is not defined, then define a version
|
||||
** of sqlite3_release_memory() to be used by other code in this file.
|
||||
** This is done for no better reason than to reduce the number of
|
||||
** pre-processor #ifndef statements.
|
||||
@@ -121,7 +122,9 @@ int sqlite3_release_memory(int n){
|
||||
** 2 since on 64-bit machines we want the value returned by sqliteMalloc()
|
||||
** to be 8-byte aligned.
|
||||
*/
|
||||
#define TESTALLOC_NGUARD 2
|
||||
#ifndef TESTALLOC_NGUARD
|
||||
# define TESTALLOC_NGUARD 2
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Size reserved for storing file-name along with each malloc()ed blob.
|
||||
@@ -434,11 +437,11 @@ int sqlite3OutstandingMallocs(Tcl_Interp *interp){
|
||||
** This is the test layer's wrapper around sqlite3OsMalloc().
|
||||
*/
|
||||
static void * OSMALLOC(int n){
|
||||
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
|
||||
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
|
||||
ThreadData *pTsd = sqlite3ThreadData();
|
||||
pTsd->nMaxAlloc = MAX(pTsd->nMaxAlloc, pTsd->nAlloc);
|
||||
#endif
|
||||
assert( sqlite3ThreadData()->mallocAllowed );
|
||||
assert( !sqlite3ThreadData()->mallocDisallowed );
|
||||
if( !failMalloc() ){
|
||||
u32 *p;
|
||||
p = (u32 *)sqlite3OsMalloc(n + TESTALLOC_OVERHEAD);
|
||||
@@ -476,11 +479,11 @@ static void OSFREE(void *pFree){
|
||||
** This is the test layer's wrapper around sqlite3OsRealloc().
|
||||
*/
|
||||
static void * OSREALLOC(void *pRealloc, int n){
|
||||
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
|
||||
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
|
||||
ThreadData *pTsd = sqlite3ThreadData();
|
||||
pTsd->nMaxAlloc = MAX(pTsd->nMaxAlloc, pTsd->nAlloc);
|
||||
#endif
|
||||
assert( sqlite3ThreadData()->mallocAllowed );
|
||||
assert( !sqlite3ThreadData()->mallocDisallowed );
|
||||
if( !failMalloc() ){
|
||||
u32 *p = (u32 *)getOsPointer(pRealloc);
|
||||
checkGuards(p);
|
||||
@@ -521,14 +524,18 @@ static void OSMALLOC_FAILED(){
|
||||
** called to try to avoid this. No indication of whether or not this is
|
||||
** successful is returned to the caller.
|
||||
**
|
||||
** If SQLITE_OMIT_MEMORY_MANAGEMENT is defined, this function is a no-op.
|
||||
** If SQLITE_ENABLE_MEMORY_MANAGEMENT is not defined, this routine is
|
||||
** a no-op
|
||||
*/
|
||||
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
|
||||
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
|
||||
static void handleSoftLimit(int n){
|
||||
ThreadData *pTsd = sqlite3ThreadData();
|
||||
pTsd->nAlloc += n;
|
||||
assert( pTsd->nAlloc>=0 );
|
||||
if( n>0 && pTsd->nSoftHeapLimit>0 ){
|
||||
while( pTsd->nAlloc>pTsd->nSoftHeapLimit && sqlite3_release_memory(n) );
|
||||
}else if( pTsd->nAlloc==0 && pTsd->nSoftHeapLimit==0 ){
|
||||
sqlite3ReleaseThreadData();
|
||||
}
|
||||
}
|
||||
#else
|
||||
@@ -541,9 +548,8 @@ static void handleSoftLimit(int n){
|
||||
** by calling sqlite3_release_memory().
|
||||
*/
|
||||
void *sqlite3MallocRaw(int n){
|
||||
ThreadData *pTsd = sqlite3ThreadData();
|
||||
void *p = 0;
|
||||
if( n>0 && !pTsd->mallocFailed ){
|
||||
if( n>0 && !sqlite3ThreadDataReadOnly()->mallocFailed ){
|
||||
handleSoftLimit(n);
|
||||
while( !(p = OSMALLOC(n)) && sqlite3_release_memory(n) );
|
||||
if( !p ){
|
||||
@@ -566,8 +572,7 @@ void *sqlite3MallocRaw(int n){
|
||||
** attempt to free memory by calling sqlite3_release_memory().
|
||||
*/
|
||||
void *sqlite3Realloc(void *p, int n){
|
||||
ThreadData *pTsd = sqlite3ThreadData();
|
||||
if( pTsd->mallocFailed ){
|
||||
if( sqlite3ThreadDataReadOnly()->mallocFailed ){
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -584,7 +589,7 @@ void *sqlite3Realloc(void *p, int n){
|
||||
** still correct after a malloc() failure.
|
||||
*/
|
||||
handleSoftLimit(OSSIZEOF(p) - n);
|
||||
pTsd->mallocFailed = 1;
|
||||
sqlite3ThreadData()->mallocFailed = 1;
|
||||
OSMALLOC_FAILED();
|
||||
}
|
||||
return np;
|
||||
@@ -1308,17 +1313,26 @@ void *sqlite3TextToPtr(const char *z){
|
||||
** Return a pointer to the ThreadData associated with the calling thread.
|
||||
*/
|
||||
ThreadData *sqlite3ThreadData(){
|
||||
ThreadData *pTsd = sqlite3OsThreadSpecificData(sizeof(ThreadData));
|
||||
if( pTsd && !pTsd->isInit ){
|
||||
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
|
||||
pTsd->nSoftHeapLimit = -1;
|
||||
#endif
|
||||
#ifndef NDEBUG
|
||||
pTsd->mallocAllowed = 1;
|
||||
#endif
|
||||
pTsd->isInit = 1;
|
||||
}
|
||||
return pTsd;
|
||||
return (ThreadData*)sqlite3OsThreadSpecificData(1);
|
||||
}
|
||||
|
||||
/*
|
||||
** Return a pointer to the ThreadData associated with the calling thread.
|
||||
** If no ThreadData has been allocated to this thread yet, return a pointer
|
||||
** to a substitute ThreadData structure that is all zeros.
|
||||
*/
|
||||
const ThreadData *sqlite3ThreadDataReadOnly(){
|
||||
static const ThreadData zeroData;
|
||||
const ThreadData *pTd = sqlite3OsThreadSpecificData(0);
|
||||
return pTd ? pTd : &zeroData;
|
||||
}
|
||||
|
||||
/*
|
||||
** Check to see if the ThreadData for this thread is all zero. If it
|
||||
** is, then deallocate it.
|
||||
*/
|
||||
void sqlite3ReleaseThreadData(){
|
||||
sqlite3OsThreadSpecificData(0);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1326,28 +1340,12 @@ ThreadData *sqlite3ThreadData(){
|
||||
** entry points that may have called sqliteMalloc().
|
||||
*/
|
||||
void sqlite3MallocClearFailed(){
|
||||
sqlite3ThreadData()->mallocFailed = 0;
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_MEMORY_MANAGEMENT
|
||||
/*
|
||||
** Enable the shared pager and schema features.
|
||||
*/
|
||||
int sqlite3_enable_memory_management(int enable){
|
||||
ThreadData *pTsd = sqlite3ThreadData();
|
||||
|
||||
/* It is only legal to call sqlite3_enable_memory_management() when there
|
||||
** are no currently open connections that were opened by the calling
|
||||
** thread. This condition is only easy to detect if the feature were
|
||||
** previously enabled (and is being disabled).
|
||||
*/
|
||||
if( pTsd->pPager && !enable ){
|
||||
return SQLITE_MISUSE;
|
||||
ThreadData *pTd = sqlite3OsThreadSpecificData(0);
|
||||
if( pTd && pTd->mallocFailed ){
|
||||
pTd->mallocFailed = 0;
|
||||
sqlite3OsThreadSpecificData(0);
|
||||
}
|
||||
pTsd->useMemoryManagement = enable;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef NDEBUG
|
||||
/*
|
||||
@@ -1355,8 +1353,8 @@ int sqlite3_enable_memory_management(int enable){
|
||||
** cause an assert to fail if sqliteMalloc() or sqliteRealloc() is called.
|
||||
*/
|
||||
void sqlite3MallocDisallow(){
|
||||
assert(sqlite3ThreadData()->mallocAllowed);
|
||||
sqlite3ThreadData()->mallocAllowed = 0;
|
||||
assert(!sqlite3ThreadData()->mallocDisallowed);
|
||||
sqlite3ThreadData()->mallocDisallowed = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1364,7 +1362,7 @@ void sqlite3MallocDisallow(){
|
||||
** by sqlite3MallocDisallow().
|
||||
*/
|
||||
void sqlite3MallocAllow(){
|
||||
assert(!sqlite3ThreadData()->mallocAllowed);
|
||||
sqlite3ThreadData()->mallocAllowed = 1;
|
||||
assert(sqlite3ThreadData()->mallocDisallowed);
|
||||
sqlite3ThreadData()->mallocDisallowed = 0;
|
||||
}
|
||||
#endif
|
||||
|
10
src/vdbe.c
10
src/vdbe.c
@@ -43,7 +43,7 @@
|
||||
** in this file for details. If in doubt, do not deviate from existing
|
||||
** commenting and indentation practices when changing or adding code.
|
||||
**
|
||||
** $Id: vdbe.c,v 1.522 2006/01/10 19:45:49 drh Exp $
|
||||
** $Id: vdbe.c,v 1.523 2006/01/11 21:41:22 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
#include "os.h"
|
||||
@@ -412,7 +412,7 @@ int sqlite3VdbeExec(
|
||||
for(pc=p->pc; rc==SQLITE_OK; pc++){
|
||||
assert( pc>=0 && pc<p->nOp );
|
||||
assert( pTos<=&p->aStack[pc] );
|
||||
if( sqlite3ThreadData()->mallocFailed ) goto no_mem;
|
||||
if( sqlite3ThreadDataReadOnly()->mallocFailed ) goto no_mem;
|
||||
#ifdef VDBE_PROFILE
|
||||
origPc = pc;
|
||||
start = hwtime();
|
||||
@@ -1167,7 +1167,7 @@ case OP_Function: {
|
||||
if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse;
|
||||
(*ctx.pFunc->xFunc)(&ctx, n, apVal);
|
||||
if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
|
||||
if( sqlite3ThreadData()->mallocFailed ) goto no_mem;
|
||||
if( sqlite3ThreadDataReadOnly()->mallocFailed ) goto no_mem;
|
||||
popStack(&pTos, n);
|
||||
|
||||
/* If any auxilary data functions have been called by this user function,
|
||||
@@ -4020,7 +4020,7 @@ case OP_ParseSchema: { /* no-push */
|
||||
sqlite3SafetyOff(db);
|
||||
assert( db->init.busy==0 );
|
||||
db->init.busy = 1;
|
||||
assert(0==sqlite3ThreadData()->mallocFailed);
|
||||
assert(0==sqlite3ThreadDataReadOnly()->mallocFailed);
|
||||
rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
|
||||
sqliteFree(zSql);
|
||||
db->init.busy = 0;
|
||||
@@ -4616,7 +4616,7 @@ abort_due_to_misuse:
|
||||
*/
|
||||
abort_due_to_error:
|
||||
if( p->zErrMsg==0 ){
|
||||
if( sqlite3ThreadData()->mallocFailed ) rc = SQLITE_NOMEM;
|
||||
if( sqlite3ThreadDataReadOnly()->mallocFailed ) rc = SQLITE_NOMEM;
|
||||
sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(rc), (char*)0);
|
||||
}
|
||||
goto vdbe_halt;
|
||||
|
@@ -156,7 +156,7 @@ int sqlite3_step(sqlite3_stmt *pStmt){
|
||||
sqlite3 *db;
|
||||
int rc;
|
||||
|
||||
assert(!sqlite3ThreadData()->mallocFailed);
|
||||
assert(!sqlite3ThreadDataReadOnly()->mallocFailed);
|
||||
|
||||
if( p==0 || p->magic!=VDBE_MAGIC_RUN ){
|
||||
return SQLITE_MISUSE;
|
||||
@@ -404,7 +404,7 @@ static void columnMallocFailure(sqlite3_stmt *pStmt)
|
||||
** SQLITE_NOMEM. The next call to _step() (if any) will return SQLITE_ERROR
|
||||
** and _finalize() will return NOMEM.
|
||||
*/
|
||||
if( sqlite3ThreadData()->mallocFailed ){
|
||||
if( sqlite3ThreadDataReadOnly()->mallocFailed ){
|
||||
((Vdbe *)pStmt)->rc = SQLITE_NOMEM;
|
||||
sqlite3MallocClearFailed();
|
||||
}
|
||||
|
@@ -102,7 +102,7 @@ int sqlite3VdbeAddOp(Vdbe *p, int op, int p1, int p2){
|
||||
p->nOp++;
|
||||
assert( p->magic==VDBE_MAGIC_INIT );
|
||||
resizeOpArray(p, i+1);
|
||||
if( sqlite3ThreadData()->mallocFailed ){
|
||||
if( sqlite3ThreadDataReadOnly()->mallocFailed ){
|
||||
return 0;
|
||||
}
|
||||
pOp = &p->aOp[i];
|
||||
@@ -301,7 +301,7 @@ int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp){
|
||||
int addr;
|
||||
assert( p->magic==VDBE_MAGIC_INIT );
|
||||
resizeOpArray(p, p->nOp + nOp);
|
||||
if( sqlite3ThreadData()->mallocFailed ){
|
||||
if( sqlite3ThreadDataReadOnly()->mallocFailed ){
|
||||
return 0;
|
||||
}
|
||||
addr = p->nOp;
|
||||
@@ -415,7 +415,7 @@ static void freeP3(int p3type, void *p3){
|
||||
void sqlite3VdbeChangeP3(Vdbe *p, int addr, const char *zP3, int n){
|
||||
Op *pOp;
|
||||
assert( p->magic==VDBE_MAGIC_INIT );
|
||||
if( p==0 || p->aOp==0 || sqlite3ThreadData()->mallocFailed ){
|
||||
if( p==0 || p->aOp==0 || sqlite3ThreadDataReadOnly()->mallocFailed ){
|
||||
if (n != P3_KEYINFO) {
|
||||
freeP3(n, (void*)*(char**)&zP3);
|
||||
}
|
||||
@@ -472,7 +472,8 @@ void sqlite3VdbeChangeP3(Vdbe *p, int addr, const char *zP3, int n){
|
||||
void sqlite3VdbeComment(Vdbe *p, const char *zFormat, ...){
|
||||
va_list ap;
|
||||
assert( p->nOp>0 );
|
||||
assert( p->aOp==0 || p->aOp[p->nOp-1].p3==0 || sqlite3ThreadData()->mallocFailed );
|
||||
assert( p->aOp==0 || p->aOp[p->nOp-1].p3==0
|
||||
|| sqlite3ThreadDataReadOnly()->mallocFailed );
|
||||
va_start(ap, zFormat);
|
||||
sqlite3VdbeChangeP3(p, -1, sqlite3VMPrintf(zFormat, ap), P3_DYNAMIC);
|
||||
va_end(ap);
|
||||
@@ -738,7 +739,7 @@ void sqlite3VdbeMakeReady(
|
||||
+ nMem*sizeof(Mem) /* aMem */
|
||||
+ nCursor*sizeof(Cursor*) /* apCsr */
|
||||
);
|
||||
if( !sqlite3ThreadData()->mallocFailed ){
|
||||
if( !sqlite3ThreadDataReadOnly()->mallocFailed ){
|
||||
p->aMem = &p->aStack[nStack];
|
||||
p->nMem = nMem;
|
||||
p->aVar = &p->aMem[nMem];
|
||||
@@ -890,7 +891,7 @@ int sqlite3VdbeSetColName(Vdbe *p, int idx, const char *zName, int N){
|
||||
int rc;
|
||||
Mem *pColName;
|
||||
assert( idx<(2*p->nResColumn) );
|
||||
if( sqlite3ThreadData()->mallocFailed ) return SQLITE_NOMEM;
|
||||
if( sqlite3ThreadDataReadOnly()->mallocFailed ) return SQLITE_NOMEM;
|
||||
assert( p->aColName!=0 );
|
||||
pColName = &(p->aColName[idx]);
|
||||
if( N==P3_DYNAMIC || N==P3_STATIC ){
|
||||
@@ -1153,7 +1154,7 @@ int sqlite3VdbeHalt(Vdbe *p){
|
||||
int i;
|
||||
int (*xFunc)(Btree *pBt) = 0; /* Function to call on each btree backend */
|
||||
|
||||
if( sqlite3ThreadData()->mallocFailed ){
|
||||
if( sqlite3ThreadDataReadOnly()->mallocFailed ){
|
||||
p->rc = SQLITE_NOMEM;
|
||||
}
|
||||
|
||||
|
@@ -756,7 +756,7 @@ const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){
|
||||
}else if( !(pVal->flags&MEM_Blob) ){
|
||||
sqlite3VdbeMemStringify(pVal, enc);
|
||||
}
|
||||
assert(pVal->enc==enc || sqlite3ThreadData()->mallocFailed);
|
||||
assert(pVal->enc==enc || sqlite3ThreadDataReadOnly()->mallocFailed);
|
||||
return (const void *)(pVal->enc==enc ? (pVal->z) : 0);
|
||||
}
|
||||
|
||||
|
@@ -16,7 +16,7 @@
|
||||
** so is applicable. Because this module is responsible for selecting
|
||||
** indices, you might also think of this module as the "query optimizer".
|
||||
**
|
||||
** $Id: where.c,v 1.193 2006/01/10 17:58:23 danielk1977 Exp $
|
||||
** $Id: where.c,v 1.194 2006/01/11 21:41:22 drh Exp $
|
||||
*/
|
||||
#include "sqliteInt.h"
|
||||
|
||||
@@ -567,7 +567,7 @@ static void exprAnalyze(
|
||||
int nPattern;
|
||||
int isComplete;
|
||||
|
||||
if( sqlite3ThreadData()->mallocFailed ) return;
|
||||
if( sqlite3ThreadDataReadOnly()->mallocFailed ) return;
|
||||
prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft);
|
||||
if( pExpr->op==TK_IN ){
|
||||
assert( pExpr->pRight==0 );
|
||||
@@ -1438,7 +1438,7 @@ WhereInfo *sqlite3WhereBegin(
|
||||
** return value.
|
||||
*/
|
||||
pWInfo = sqliteMalloc( sizeof(WhereInfo) + pTabList->nSrc*sizeof(WhereLevel));
|
||||
if( sqlite3ThreadData()->mallocFailed ){
|
||||
if( sqlite3ThreadDataReadOnly()->mallocFailed ){
|
||||
goto whereBeginNoMem;
|
||||
}
|
||||
pWInfo->pParse = pParse;
|
||||
@@ -1462,7 +1462,7 @@ WhereInfo *sqlite3WhereBegin(
|
||||
createMask(&maskSet, pTabList->a[i].iCursor);
|
||||
}
|
||||
exprAnalyzeAll(pTabList, &maskSet, &wc);
|
||||
if( sqlite3ThreadData()->mallocFailed ){
|
||||
if( sqlite3ThreadDataReadOnly()->mallocFailed ){
|
||||
goto whereBeginNoMem;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user