mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
In shared-cache mode, make sure the busy hander invoked is the
busy handler associated with the database connection that caused the lock contention in the first place. (CVS 4598) FossilOrigin-Name: c9eb65912f61ce0a6b66fe253652a1827e46b12a
This commit is contained in:
26
manifest
26
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Get\sthe\sLIKE\sand\sGLOB\soperators\sworking\sagain\son\ssystems\susing\sthe\nEBCDIC\scharacter\sset.\s(CVS\s4597)
|
C In\sshared-cache\smode,\smake\ssure\sthe\sbusy\shander\sinvoked\sis\sthe\nbusy\shandler\sassociated\swith\sthe\sdatabase\sconnection\sthat\scaused\nthe\slock\scontention\sin\sthe\sfirst\splace.\s(CVS\s4598)
|
||||||
D 2007-12-07T18:39:05
|
D 2007-12-07T18:55:28
|
||||||
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
|
F Makefile.arm-wince-mingw32ce-gcc ac5f7b2cef0cd850d6f755ba6ee4ab961b1fadf7
|
||||||
F Makefile.in 30789bf70614bad659351660d76b8e533f3340e9
|
F Makefile.in 30789bf70614bad659351660d76b8e533f3340e9
|
||||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||||
@@ -82,10 +82,10 @@ F src/alter.c 8512ed319aa5f7b9bbbd4e17953809e3ff398fdd
|
|||||||
F src/analyze.c fd1a3d756c1a20fca3c505bed0398f4cdca83cb8
|
F src/analyze.c fd1a3d756c1a20fca3c505bed0398f4cdca83cb8
|
||||||
F src/attach.c a01d55157d46a1234909f3a7f21fb09549c947bd
|
F src/attach.c a01d55157d46a1234909f3a7f21fb09549c947bd
|
||||||
F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627
|
F src/auth.c c8b2ab5c8bad4bd90ed7c294694f48269162c627
|
||||||
F src/btmutex.c 442be6f068d77ca9ffd69899cf0a3943c244548c
|
F src/btmutex.c 5d39da37c9d1282f3c6f9967afae6a34ee36b7ff
|
||||||
F src/btree.c c5844bb4bbe997a7c8400a714fcf304d91855383
|
F src/btree.c 45c65b60efb1eb20edcda08cecbd15279c9e220c
|
||||||
F src/btree.h d0736ebca4b6eafbdd823c46a8de574cea078211
|
F src/btree.h 19dcf5ad23c17b98855da548e9a8e3eb4429d5eb
|
||||||
F src/btreeInt.h 4330c19b8314545fdb209cc77e2a57f6a5290e9c
|
F src/btreeInt.h 68ec997e34e426093f706da965c147ece75185b9
|
||||||
F src/build.c 580561a0d9e070ff2741f3b115cae51c1ef08260
|
F src/build.c 580561a0d9e070ff2741f3b115cae51c1ef08260
|
||||||
F src/callback.c 77b302b0d41468dcda78c70e706e5b84577f0fa0
|
F src/callback.c 77b302b0d41468dcda78c70e706e5b84577f0fa0
|
||||||
F src/complete.c 4cf68fd75d60257524cbe74f87351b9848399131
|
F src/complete.c 4cf68fd75d60257524cbe74f87351b9848399131
|
||||||
@@ -101,7 +101,7 @@ F src/journal.c 807bed7a158979ac8d63953e1774e8d85bff65e2
|
|||||||
F src/legacy.c 4ac53191fad2e3c4d59bde1228879b2dc5a96d66
|
F src/legacy.c 4ac53191fad2e3c4d59bde1228879b2dc5a96d66
|
||||||
F src/limits.h 71ab25f17e35e0a9f3f6f234b8ed49cc56731d35
|
F src/limits.h 71ab25f17e35e0a9f3f6f234b8ed49cc56731d35
|
||||||
F src/loadext.c 124e566563d1c03e68e1396cb44df9870612c6e9
|
F src/loadext.c 124e566563d1c03e68e1396cb44df9870612c6e9
|
||||||
F src/main.c 53e71b4d4a0dbc1eb3a73520970973689cabea18
|
F src/main.c bdeb906fb112ff60f3612d4fd91abba05ae6d397
|
||||||
F src/malloc.c 60e392a4c12c839517f9b0db7b995f825444fb35
|
F src/malloc.c 60e392a4c12c839517f9b0db7b995f825444fb35
|
||||||
F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217
|
F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217
|
||||||
F src/mem1.c 6d1a11864963d249c67e72ad5f6533b040333880
|
F src/mem1.c 6d1a11864963d249c67e72ad5f6533b040333880
|
||||||
@@ -124,7 +124,7 @@ F src/os_unix.c 10641ed959b960915deaf2d053105e1ee9849d88
|
|||||||
F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e
|
F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e
|
||||||
F src/os_win.c a92769a7ec45ff908ca5e83553c8582215bb58c5
|
F src/os_win.c a92769a7ec45ff908ca5e83553c8582215bb58c5
|
||||||
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
|
F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b
|
||||||
F src/pager.c 65298fee4e815c269fb374d3fe3cd1cf4f05ad94
|
F src/pager.c 2f420d4605159f3a3cd06c70c927cb00a731affa
|
||||||
F src/pager.h f504f7ae84060fee0416a853e368d3d113c3d6fa
|
F src/pager.h f504f7ae84060fee0416a853e368d3d113c3d6fa
|
||||||
F src/parse.y a780b33ef45dd7b3272319cf91e609d6f109a31c
|
F src/parse.y a780b33ef45dd7b3272319cf91e609d6f109a31c
|
||||||
F src/pragma.c 0246032dbe681dded8710ac43eaf654eead1434e
|
F src/pragma.c 0246032dbe681dded8710ac43eaf654eead1434e
|
||||||
@@ -136,13 +136,13 @@ F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96
|
|||||||
F src/shell.c c97be281cfc3dcb14902f45e4b16f20038eb83ff
|
F src/shell.c c97be281cfc3dcb14902f45e4b16f20038eb83ff
|
||||||
F src/sqlite.h.in 544587c10005dde0ad8f132dd9b7816b132b2bea
|
F src/sqlite.h.in 544587c10005dde0ad8f132dd9b7816b132b2bea
|
||||||
F src/sqlite3ext.h a93f59cdee3638dc0c9c086f80df743a4e68c3cb
|
F src/sqlite3ext.h a93f59cdee3638dc0c9c086f80df743a4e68c3cb
|
||||||
F src/sqliteInt.h a941ccf797b45c27bc0face4e75935b5cc019202
|
F src/sqliteInt.h 5c86734aaecc6c498c1ed0497935f3f1d3c2f842
|
||||||
F src/sqliteLimit.h 15ffe2116746c27ace2b428a26a4fcd6dba6fa65
|
F src/sqliteLimit.h 15ffe2116746c27ace2b428a26a4fcd6dba6fa65
|
||||||
F src/table.c 1aeb9eab57b4235db86fe15a35dec76fb445a9c4
|
F src/table.c 1aeb9eab57b4235db86fe15a35dec76fb445a9c4
|
||||||
F src/tclsqlite.c 9923abeffc9b3d7dad58e92b319661521f60debf
|
F src/tclsqlite.c 9923abeffc9b3d7dad58e92b319661521f60debf
|
||||||
F src/test1.c ba01f4b8bb742ec5869167bbc87491eaafb7da3f
|
F src/test1.c ba01f4b8bb742ec5869167bbc87491eaafb7da3f
|
||||||
F src/test2.c 77b34303883b9d722c65a6879bb0163a400e3789
|
F src/test2.c 77b34303883b9d722c65a6879bb0163a400e3789
|
||||||
F src/test3.c 73c1fd55d1ece61f295a6b9204fd97a139de86ae
|
F src/test3.c df62cd5c971dc1ae0be0a1842f9df3390934e7a6
|
||||||
F src/test4.c c2c0f5dc907f1346f5d4b65eb5799f11eb9e4071
|
F src/test4.c c2c0f5dc907f1346f5d4b65eb5799f11eb9e4071
|
||||||
F src/test5.c 3a6a5717a149d7ca2e6d14f5be72cf7555d54dc4
|
F src/test5.c 3a6a5717a149d7ca2e6d14f5be72cf7555d54dc4
|
||||||
F src/test6.c a9fc983d32d6f262eab300d742e49ff239b0bdbd
|
F src/test6.c a9fc983d32d6f262eab300d742e49ff239b0bdbd
|
||||||
@@ -597,7 +597,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130
|
|||||||
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
|
||||||
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b
|
||||||
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
|
F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5
|
||||||
P f29deb5f0bfcd6d00795aeb66dece717a6c1768a
|
P 754298a74e3d889f3767daba058262613d20a601
|
||||||
R 914411460f2d77a89cfca0420655917f
|
R 0ae36f66eb071af9c23c05039a009307
|
||||||
U drh
|
U drh
|
||||||
Z dab0e24c447ca0aa1c74119b9b014915
|
Z 974b15de4ea104f24852fc03b178d3ac
|
||||||
|
@@ -1 +1 @@
|
|||||||
754298a74e3d889f3767daba058262613d20a601
|
c9eb65912f61ce0a6b66fe253652a1827e46b12a
|
@@ -10,7 +10,7 @@
|
|||||||
**
|
**
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
**
|
**
|
||||||
** $Id: btmutex.c,v 1.7 2007/08/30 01:19:59 drh Exp $
|
** $Id: btmutex.c,v 1.8 2007/12/07 18:55:28 drh Exp $
|
||||||
**
|
**
|
||||||
** This file contains code used to implement mutexes on Btree objects.
|
** This file contains code used to implement mutexes on Btree objects.
|
||||||
** This code really belongs in btree.c. But btree.c is getting too
|
** This code really belongs in btree.c. But btree.c is getting too
|
||||||
@@ -46,8 +46,8 @@ void sqlite3BtreeEnter(Btree *p){
|
|||||||
** the same connection. Only shared Btrees are on the list. */
|
** the same connection. Only shared Btrees are on the list. */
|
||||||
assert( p->pNext==0 || p->pNext->pBt>p->pBt );
|
assert( p->pNext==0 || p->pNext->pBt>p->pBt );
|
||||||
assert( p->pPrev==0 || p->pPrev->pBt<p->pBt );
|
assert( p->pPrev==0 || p->pPrev->pBt<p->pBt );
|
||||||
assert( p->pNext==0 || p->pNext->pSqlite==p->pSqlite );
|
assert( p->pNext==0 || p->pNext->db==p->db );
|
||||||
assert( p->pPrev==0 || p->pPrev->pSqlite==p->pSqlite );
|
assert( p->pPrev==0 || p->pPrev->db==p->db );
|
||||||
assert( p->sharable || (p->pNext==0 && p->pPrev==0) );
|
assert( p->sharable || (p->pNext==0 && p->pPrev==0) );
|
||||||
|
|
||||||
/* Check for locking consistency */
|
/* Check for locking consistency */
|
||||||
@@ -55,7 +55,7 @@ void sqlite3BtreeEnter(Btree *p){
|
|||||||
assert( p->sharable || p->wantToLock==0 );
|
assert( p->sharable || p->wantToLock==0 );
|
||||||
|
|
||||||
/* We should already hold a lock on the database connection */
|
/* We should already hold a lock on the database connection */
|
||||||
assert( sqlite3_mutex_held(p->pSqlite->mutex) );
|
assert( sqlite3_mutex_held(p->db->mutex) );
|
||||||
|
|
||||||
if( !p->sharable ) return;
|
if( !p->sharable ) return;
|
||||||
p->wantToLock++;
|
p->wantToLock++;
|
||||||
@@ -278,7 +278,7 @@ void sqlite3BtreeMutexArrayEnter(BtreeMutexArray *pArray){
|
|||||||
assert( !p->locked || p->wantToLock>0 );
|
assert( !p->locked || p->wantToLock>0 );
|
||||||
|
|
||||||
/* We should already hold a lock on the database connection */
|
/* We should already hold a lock on the database connection */
|
||||||
assert( sqlite3_mutex_held(p->pSqlite->mutex) );
|
assert( sqlite3_mutex_held(p->db->mutex) );
|
||||||
|
|
||||||
p->wantToLock++;
|
p->wantToLock++;
|
||||||
if( !p->locked && p->sharable ){
|
if( !p->locked && p->sharable ){
|
||||||
@@ -301,7 +301,7 @@ void sqlite3BtreeMutexArrayLeave(BtreeMutexArray *pArray){
|
|||||||
assert( p->wantToLock>0 );
|
assert( p->wantToLock>0 );
|
||||||
|
|
||||||
/* We should already hold a lock on the database connection */
|
/* We should already hold a lock on the database connection */
|
||||||
assert( sqlite3_mutex_held(p->pSqlite->mutex) );
|
assert( sqlite3_mutex_held(p->db->mutex) );
|
||||||
|
|
||||||
p->wantToLock--;
|
p->wantToLock--;
|
||||||
if( p->wantToLock==0 && p->locked ){
|
if( p->wantToLock==0 && p->locked ){
|
||||||
|
114
src/btree.c
114
src/btree.c
@@ -9,7 +9,7 @@
|
|||||||
** May you share freely, never taking more than you give.
|
** May you share freely, never taking more than you give.
|
||||||
**
|
**
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
** $Id: btree.c,v 1.431 2007/11/28 16:19:56 drh Exp $
|
** $Id: btree.c,v 1.432 2007/12/07 18:55:28 drh Exp $
|
||||||
**
|
**
|
||||||
** This file implements a external (disk-based) database using BTrees.
|
** This file implements a external (disk-based) database using BTrees.
|
||||||
** See the header comment on "btreeInt.h" for additional information.
|
** See the header comment on "btreeInt.h" for additional information.
|
||||||
@@ -118,8 +118,8 @@ static int queryTableLock(Btree *p, Pgno iTab, u8 eLock){
|
|||||||
** write-cursor does not change.
|
** write-cursor does not change.
|
||||||
*/
|
*/
|
||||||
if(
|
if(
|
||||||
!p->pSqlite ||
|
!p->db ||
|
||||||
0==(p->pSqlite->flags&SQLITE_ReadUncommitted) ||
|
0==(p->db->flags&SQLITE_ReadUncommitted) ||
|
||||||
eLock==WRITE_LOCK ||
|
eLock==WRITE_LOCK ||
|
||||||
iTab==MASTER_ROOT
|
iTab==MASTER_ROOT
|
||||||
){
|
){
|
||||||
@@ -163,8 +163,8 @@ static int lockTable(Btree *p, Pgno iTable, u8 eLock){
|
|||||||
** the ReadUncommitted flag.
|
** the ReadUncommitted flag.
|
||||||
*/
|
*/
|
||||||
if(
|
if(
|
||||||
(p->pSqlite) &&
|
(p->db) &&
|
||||||
(p->pSqlite->flags&SQLITE_ReadUncommitted) &&
|
(p->db->flags&SQLITE_ReadUncommitted) &&
|
||||||
(eLock==READ_LOCK) &&
|
(eLock==READ_LOCK) &&
|
||||||
iTable!=MASTER_ROOT
|
iTable!=MASTER_ROOT
|
||||||
){
|
){
|
||||||
@@ -1098,6 +1098,16 @@ static void pageReinit(DbPage *pData, int pageSize){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Invoke the busy handler for a btree.
|
||||||
|
*/
|
||||||
|
static int sqlite3BtreeInvokeBusyHandler(void *pArg, int n){
|
||||||
|
BtShared *pBt = (BtShared*)pArg;
|
||||||
|
assert( pBt->db );
|
||||||
|
assert( sqlite3_mutex_held(pBt->db->mutex) );
|
||||||
|
return sqlite3InvokeBusyHandler(&pBt->db->busyHandler);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Open a database file.
|
** Open a database file.
|
||||||
**
|
**
|
||||||
@@ -1109,7 +1119,7 @@ static void pageReinit(DbPage *pData, int pageSize){
|
|||||||
*/
|
*/
|
||||||
int sqlite3BtreeOpen(
|
int sqlite3BtreeOpen(
|
||||||
const char *zFilename, /* Name of the file containing the BTree database */
|
const char *zFilename, /* Name of the file containing the BTree database */
|
||||||
sqlite3 *pSqlite, /* Associated database handle */
|
sqlite3 *db, /* Associated database handle */
|
||||||
Btree **ppBtree, /* Pointer to new Btree object written here */
|
Btree **ppBtree, /* Pointer to new Btree object written here */
|
||||||
int flags, /* Options */
|
int flags, /* Options */
|
||||||
int vfsFlags /* Flags passed through to sqlite3_vfs.xOpen() */
|
int vfsFlags /* Flags passed through to sqlite3_vfs.xOpen() */
|
||||||
@@ -1134,16 +1144,16 @@ int sqlite3BtreeOpen(
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
assert( pSqlite!=0 );
|
assert( db!=0 );
|
||||||
assert( sqlite3_mutex_held(pSqlite->mutex) );
|
assert( sqlite3_mutex_held(db->mutex) );
|
||||||
|
|
||||||
pVfs = pSqlite->pVfs;
|
pVfs = db->pVfs;
|
||||||
p = sqlite3MallocZero(sizeof(Btree));
|
p = sqlite3MallocZero(sizeof(Btree));
|
||||||
if( !p ){
|
if( !p ){
|
||||||
return SQLITE_NOMEM;
|
return SQLITE_NOMEM;
|
||||||
}
|
}
|
||||||
p->inTrans = TRANS_NONE;
|
p->inTrans = TRANS_NONE;
|
||||||
p->pSqlite = pSqlite;
|
p->db = db;
|
||||||
|
|
||||||
#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
|
#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
|
||||||
/*
|
/*
|
||||||
@@ -1152,7 +1162,7 @@ int sqlite3BtreeOpen(
|
|||||||
*/
|
*/
|
||||||
if( (flags & BTREE_PRIVATE)==0
|
if( (flags & BTREE_PRIVATE)==0
|
||||||
&& isMemdb==0
|
&& isMemdb==0
|
||||||
&& (pSqlite->flags & SQLITE_Vtab)==0
|
&& (db->flags & SQLITE_Vtab)==0
|
||||||
&& zFilename && zFilename[0]
|
&& zFilename && zFilename[0]
|
||||||
){
|
){
|
||||||
if( sqlite3SharedCacheEnabled ){
|
if( sqlite3SharedCacheEnabled ){
|
||||||
@@ -1160,8 +1170,8 @@ int sqlite3BtreeOpen(
|
|||||||
char *zFullPathname = (char *)sqlite3_malloc(nFullPathname);
|
char *zFullPathname = (char *)sqlite3_malloc(nFullPathname);
|
||||||
sqlite3_mutex *mutexShared;
|
sqlite3_mutex *mutexShared;
|
||||||
p->sharable = 1;
|
p->sharable = 1;
|
||||||
if( pSqlite ){
|
if( db ){
|
||||||
pSqlite->flags |= SQLITE_SharedCache;
|
db->flags |= SQLITE_SharedCache;
|
||||||
}
|
}
|
||||||
if( !zFullPathname ){
|
if( !zFullPathname ){
|
||||||
sqlite3_free(p);
|
sqlite3_free(p);
|
||||||
@@ -1211,6 +1221,8 @@ int sqlite3BtreeOpen(
|
|||||||
rc = SQLITE_NOMEM;
|
rc = SQLITE_NOMEM;
|
||||||
goto btree_open_out;
|
goto btree_open_out;
|
||||||
}
|
}
|
||||||
|
pBt->busyHdr.xFunc = sqlite3BtreeInvokeBusyHandler;
|
||||||
|
pBt->busyHdr.pArg = pBt;
|
||||||
rc = sqlite3PagerOpen(pVfs, &pBt->pPager, zFilename,
|
rc = sqlite3PagerOpen(pVfs, &pBt->pPager, zFilename,
|
||||||
EXTRA_SIZE, flags, vfsFlags);
|
EXTRA_SIZE, flags, vfsFlags);
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
@@ -1219,6 +1231,7 @@ int sqlite3BtreeOpen(
|
|||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
goto btree_open_out;
|
goto btree_open_out;
|
||||||
}
|
}
|
||||||
|
sqlite3PagerSetBusyhandler(pBt->pPager, &pBt->busyHdr);
|
||||||
p->pBt = pBt;
|
p->pBt = pBt;
|
||||||
|
|
||||||
sqlite3PagerSetDestructor(pBt->pPager, pageDestructor);
|
sqlite3PagerSetDestructor(pBt->pPager, pageDestructor);
|
||||||
@@ -1273,7 +1286,7 @@ int sqlite3BtreeOpen(
|
|||||||
pBt->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
|
pBt->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
|
||||||
if( pBt->mutex==0 ){
|
if( pBt->mutex==0 ){
|
||||||
rc = SQLITE_NOMEM;
|
rc = SQLITE_NOMEM;
|
||||||
pSqlite->mallocFailed = 0;
|
db->mallocFailed = 0;
|
||||||
goto btree_open_out;
|
goto btree_open_out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1293,8 +1306,8 @@ int sqlite3BtreeOpen(
|
|||||||
if( p->sharable ){
|
if( p->sharable ){
|
||||||
int i;
|
int i;
|
||||||
Btree *pSib;
|
Btree *pSib;
|
||||||
for(i=0; i<pSqlite->nDb; i++){
|
for(i=0; i<db->nDb; i++){
|
||||||
if( (pSib = pSqlite->aDb[i].pBt)!=0 && pSib->sharable ){
|
if( (pSib = db->aDb[i].pBt)!=0 && pSib->sharable ){
|
||||||
while( pSib->pPrev ){ pSib = pSib->pPrev; }
|
while( pSib->pPrev ){ pSib = pSib->pPrev; }
|
||||||
if( p->pBt<pSib->pBt ){
|
if( p->pBt<pSib->pBt ){
|
||||||
p->pNext = pSib;
|
p->pNext = pSib;
|
||||||
@@ -1378,8 +1391,9 @@ int sqlite3BtreeClose(Btree *p){
|
|||||||
BtCursor *pCur;
|
BtCursor *pCur;
|
||||||
|
|
||||||
/* Close all cursors opened via this handle. */
|
/* Close all cursors opened via this handle. */
|
||||||
assert( sqlite3_mutex_held(p->pSqlite->mutex) );
|
assert( sqlite3_mutex_held(p->db->mutex) );
|
||||||
sqlite3BtreeEnter(p);
|
sqlite3BtreeEnter(p);
|
||||||
|
pBt->db = p->db;
|
||||||
pCur = pBt->pCursor;
|
pCur = pBt->pCursor;
|
||||||
while( pCur ){
|
while( pCur ){
|
||||||
BtCursor *pTmp = pCur;
|
BtCursor *pTmp = pCur;
|
||||||
@@ -1427,19 +1441,6 @@ int sqlite3BtreeClose(Btree *p){
|
|||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
** Change the busy handler callback function.
|
|
||||||
*/
|
|
||||||
int sqlite3BtreeSetBusyHandler(Btree *p, BusyHandler *pHandler){
|
|
||||||
BtShared *pBt = p->pBt;
|
|
||||||
assert( sqlite3_mutex_held(p->pSqlite->mutex) );
|
|
||||||
sqlite3BtreeEnter(p);
|
|
||||||
pBt->pBusyHandler = pHandler;
|
|
||||||
sqlite3PagerSetBusyhandler(pBt->pPager, pHandler);
|
|
||||||
sqlite3BtreeLeave(p);
|
|
||||||
return SQLITE_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Change the limit on the number of pages allowed in the cache.
|
** Change the limit on the number of pages allowed in the cache.
|
||||||
**
|
**
|
||||||
@@ -1457,7 +1458,7 @@ int sqlite3BtreeSetBusyHandler(Btree *p, BusyHandler *pHandler){
|
|||||||
*/
|
*/
|
||||||
int sqlite3BtreeSetCacheSize(Btree *p, int mxPage){
|
int sqlite3BtreeSetCacheSize(Btree *p, int mxPage){
|
||||||
BtShared *pBt = p->pBt;
|
BtShared *pBt = p->pBt;
|
||||||
assert( sqlite3_mutex_held(p->pSqlite->mutex) );
|
assert( sqlite3_mutex_held(p->db->mutex) );
|
||||||
sqlite3BtreeEnter(p);
|
sqlite3BtreeEnter(p);
|
||||||
sqlite3PagerSetCachesize(pBt->pPager, mxPage);
|
sqlite3PagerSetCachesize(pBt->pPager, mxPage);
|
||||||
sqlite3BtreeLeave(p);
|
sqlite3BtreeLeave(p);
|
||||||
@@ -1475,7 +1476,7 @@ int sqlite3BtreeSetCacheSize(Btree *p, int mxPage){
|
|||||||
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
|
#ifndef SQLITE_OMIT_PAGER_PRAGMAS
|
||||||
int sqlite3BtreeSetSafetyLevel(Btree *p, int level, int fullSync){
|
int sqlite3BtreeSetSafetyLevel(Btree *p, int level, int fullSync){
|
||||||
BtShared *pBt = p->pBt;
|
BtShared *pBt = p->pBt;
|
||||||
assert( sqlite3_mutex_held(p->pSqlite->mutex) );
|
assert( sqlite3_mutex_held(p->db->mutex) );
|
||||||
sqlite3BtreeEnter(p);
|
sqlite3BtreeEnter(p);
|
||||||
sqlite3PagerSetSafetyLevel(pBt->pPager, level, fullSync);
|
sqlite3PagerSetSafetyLevel(pBt->pPager, level, fullSync);
|
||||||
sqlite3BtreeLeave(p);
|
sqlite3BtreeLeave(p);
|
||||||
@@ -1490,7 +1491,7 @@ int sqlite3BtreeSetSafetyLevel(Btree *p, int level, int fullSync){
|
|||||||
int sqlite3BtreeSyncDisabled(Btree *p){
|
int sqlite3BtreeSyncDisabled(Btree *p){
|
||||||
BtShared *pBt = p->pBt;
|
BtShared *pBt = p->pBt;
|
||||||
int rc;
|
int rc;
|
||||||
assert( sqlite3_mutex_held(p->pSqlite->mutex) );
|
assert( sqlite3_mutex_held(p->db->mutex) );
|
||||||
sqlite3BtreeEnter(p);
|
sqlite3BtreeEnter(p);
|
||||||
assert( pBt && pBt->pPager );
|
assert( pBt && pBt->pPager );
|
||||||
rc = sqlite3PagerNosync(pBt->pPager);
|
rc = sqlite3PagerNosync(pBt->pPager);
|
||||||
@@ -1823,6 +1824,7 @@ int sqlite3BtreeBeginTrans(Btree *p, int wrflag){
|
|||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
|
|
||||||
sqlite3BtreeEnter(p);
|
sqlite3BtreeEnter(p);
|
||||||
|
pBt->db = p->db;
|
||||||
btreeIntegrity(p);
|
btreeIntegrity(p);
|
||||||
|
|
||||||
/* If the btree is already in a write-transaction, or it
|
/* If the btree is already in a write-transaction, or it
|
||||||
@@ -1870,7 +1872,7 @@ int sqlite3BtreeBeginTrans(Btree *p, int wrflag){
|
|||||||
unlockBtreeIfUnused(pBt);
|
unlockBtreeIfUnused(pBt);
|
||||||
}
|
}
|
||||||
}while( rc==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE &&
|
}while( rc==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE &&
|
||||||
sqlite3InvokeBusyHandler(pBt->pBusyHandler) );
|
sqlite3BtreeInvokeBusyHandler(pBt, 0) );
|
||||||
|
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
if( p->inTrans==TRANS_NONE ){
|
if( p->inTrans==TRANS_NONE ){
|
||||||
@@ -2196,6 +2198,7 @@ int sqlite3BtreeIncrVacuum(Btree *p){
|
|||||||
BtShared *pBt = p->pBt;
|
BtShared *pBt = p->pBt;
|
||||||
|
|
||||||
sqlite3BtreeEnter(p);
|
sqlite3BtreeEnter(p);
|
||||||
|
pBt->db = p->db;
|
||||||
assert( pBt->inTransaction==TRANS_WRITE && p->inTrans==TRANS_WRITE );
|
assert( pBt->inTransaction==TRANS_WRITE && p->inTrans==TRANS_WRITE );
|
||||||
if( !pBt->autoVacuum ){
|
if( !pBt->autoVacuum ){
|
||||||
rc = SQLITE_DONE;
|
rc = SQLITE_DONE;
|
||||||
@@ -2312,6 +2315,7 @@ int sqlite3BtreeCommitPhaseOne(Btree *p, const char *zMaster){
|
|||||||
BtShared *pBt = p->pBt;
|
BtShared *pBt = p->pBt;
|
||||||
Pgno nTrunc = 0;
|
Pgno nTrunc = 0;
|
||||||
sqlite3BtreeEnter(p);
|
sqlite3BtreeEnter(p);
|
||||||
|
pBt->db = p->db;
|
||||||
#ifndef SQLITE_OMIT_AUTOVACUUM
|
#ifndef SQLITE_OMIT_AUTOVACUUM
|
||||||
if( pBt->autoVacuum ){
|
if( pBt->autoVacuum ){
|
||||||
rc = autoVacuumCommit(pBt, &nTrunc);
|
rc = autoVacuumCommit(pBt, &nTrunc);
|
||||||
@@ -2345,6 +2349,7 @@ int sqlite3BtreeCommitPhaseTwo(Btree *p){
|
|||||||
BtShared *pBt = p->pBt;
|
BtShared *pBt = p->pBt;
|
||||||
|
|
||||||
sqlite3BtreeEnter(p);
|
sqlite3BtreeEnter(p);
|
||||||
|
pBt->db = p->db;
|
||||||
btreeIntegrity(p);
|
btreeIntegrity(p);
|
||||||
|
|
||||||
/* If the handle has a write-transaction open, commit the shared-btrees
|
/* If the handle has a write-transaction open, commit the shared-btrees
|
||||||
@@ -2465,6 +2470,7 @@ int sqlite3BtreeRollback(Btree *p){
|
|||||||
MemPage *pPage1;
|
MemPage *pPage1;
|
||||||
|
|
||||||
sqlite3BtreeEnter(p);
|
sqlite3BtreeEnter(p);
|
||||||
|
pBt->db = p->db;
|
||||||
rc = saveAllCursors(pBt, 0, 0);
|
rc = saveAllCursors(pBt, 0, 0);
|
||||||
#ifndef SQLITE_OMIT_SHARED_CACHE
|
#ifndef SQLITE_OMIT_SHARED_CACHE
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
@@ -2540,6 +2546,7 @@ int sqlite3BtreeBeginStmt(Btree *p){
|
|||||||
int rc;
|
int rc;
|
||||||
BtShared *pBt = p->pBt;
|
BtShared *pBt = p->pBt;
|
||||||
sqlite3BtreeEnter(p);
|
sqlite3BtreeEnter(p);
|
||||||
|
pBt->db = p->db;
|
||||||
if( (p->inTrans!=TRANS_WRITE) || pBt->inStmt ){
|
if( (p->inTrans!=TRANS_WRITE) || pBt->inStmt ){
|
||||||
rc = pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
|
rc = pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
|
||||||
}else{
|
}else{
|
||||||
@@ -2560,6 +2567,7 @@ int sqlite3BtreeCommitStmt(Btree *p){
|
|||||||
int rc;
|
int rc;
|
||||||
BtShared *pBt = p->pBt;
|
BtShared *pBt = p->pBt;
|
||||||
sqlite3BtreeEnter(p);
|
sqlite3BtreeEnter(p);
|
||||||
|
pBt->db = p->db;
|
||||||
if( pBt->inStmt && !pBt->readOnly ){
|
if( pBt->inStmt && !pBt->readOnly ){
|
||||||
rc = sqlite3PagerStmtCommit(pBt->pPager);
|
rc = sqlite3PagerStmtCommit(pBt->pPager);
|
||||||
}else{
|
}else{
|
||||||
@@ -2582,6 +2590,7 @@ int sqlite3BtreeRollbackStmt(Btree *p){
|
|||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
BtShared *pBt = p->pBt;
|
BtShared *pBt = p->pBt;
|
||||||
sqlite3BtreeEnter(p);
|
sqlite3BtreeEnter(p);
|
||||||
|
pBt->db = p->db;
|
||||||
if( pBt->inStmt && !pBt->readOnly ){
|
if( pBt->inStmt && !pBt->readOnly ){
|
||||||
rc = sqlite3PagerStmtRollback(pBt->pPager);
|
rc = sqlite3PagerStmtRollback(pBt->pPager);
|
||||||
assert( countWriteCursors(pBt)==0 );
|
assert( countWriteCursors(pBt)==0 );
|
||||||
@@ -2725,6 +2734,7 @@ int sqlite3BtreeCursor(
|
|||||||
){
|
){
|
||||||
int rc;
|
int rc;
|
||||||
sqlite3BtreeEnter(p);
|
sqlite3BtreeEnter(p);
|
||||||
|
p->pBt->db = p->db;
|
||||||
rc = btreeCursor(p, iTable, wrFlag, xCmp, pArg, ppCur);
|
rc = btreeCursor(p, iTable, wrFlag, xCmp, pArg, ppCur);
|
||||||
sqlite3BtreeLeave(p);
|
sqlite3BtreeLeave(p);
|
||||||
return rc;
|
return rc;
|
||||||
@@ -2740,6 +2750,7 @@ int sqlite3BtreeCloseCursor(BtCursor *pCur){
|
|||||||
Btree *pBtree = pCur->pBtree;
|
Btree *pBtree = pCur->pBtree;
|
||||||
|
|
||||||
sqlite3BtreeEnter(pBtree);
|
sqlite3BtreeEnter(pBtree);
|
||||||
|
pBt->db = pBtree->db;
|
||||||
clearCursorPosition(pCur);
|
clearCursorPosition(pCur);
|
||||||
if( pCur->pPrev ){
|
if( pCur->pPrev ){
|
||||||
pCur->pPrev->pNext = pCur->pNext;
|
pCur->pPrev->pNext = pCur->pNext;
|
||||||
@@ -3474,7 +3485,7 @@ int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){
|
|||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
assert( cursorHoldsMutex(pCur) );
|
assert( cursorHoldsMutex(pCur) );
|
||||||
assert( sqlite3_mutex_held(pCur->pBtree->pSqlite->mutex) );
|
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
|
||||||
rc = moveToRoot(pCur);
|
rc = moveToRoot(pCur);
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
if( pCur->eState==CURSOR_INVALID ){
|
if( pCur->eState==CURSOR_INVALID ){
|
||||||
@@ -3498,7 +3509,7 @@ int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
|
|||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
assert( cursorHoldsMutex(pCur) );
|
assert( cursorHoldsMutex(pCur) );
|
||||||
assert( sqlite3_mutex_held(pCur->pBtree->pSqlite->mutex) );
|
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
|
||||||
rc = moveToRoot(pCur);
|
rc = moveToRoot(pCur);
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
if( CURSOR_INVALID==pCur->eState ){
|
if( CURSOR_INVALID==pCur->eState ){
|
||||||
@@ -3551,7 +3562,7 @@ int sqlite3BtreeMoveto(
|
|||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
assert( cursorHoldsMutex(pCur) );
|
assert( cursorHoldsMutex(pCur) );
|
||||||
assert( sqlite3_mutex_held(pCur->pBtree->pSqlite->mutex) );
|
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
|
||||||
rc = moveToRoot(pCur);
|
rc = moveToRoot(pCur);
|
||||||
if( rc ){
|
if( rc ){
|
||||||
return rc;
|
return rc;
|
||||||
@@ -3678,8 +3689,8 @@ int sqlite3BtreeEof(BtCursor *pCur){
|
|||||||
** Return the database connection handle for a cursor.
|
** Return the database connection handle for a cursor.
|
||||||
*/
|
*/
|
||||||
sqlite3 *sqlite3BtreeCursorDb(const BtCursor *pCur){
|
sqlite3 *sqlite3BtreeCursorDb(const BtCursor *pCur){
|
||||||
assert( sqlite3_mutex_held(pCur->pBtree->pSqlite->mutex) );
|
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
|
||||||
return pCur->pBtree->pSqlite;
|
return pCur->pBtree->db;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -5500,14 +5511,14 @@ static int balance(MemPage *pPage, int insert){
|
|||||||
static int checkReadLocks(Btree *pBtree, Pgno pgnoRoot, BtCursor *pExclude){
|
static int checkReadLocks(Btree *pBtree, Pgno pgnoRoot, BtCursor *pExclude){
|
||||||
BtCursor *p;
|
BtCursor *p;
|
||||||
BtShared *pBt = pBtree->pBt;
|
BtShared *pBt = pBtree->pBt;
|
||||||
sqlite3 *db = pBtree->pSqlite;
|
sqlite3 *db = pBtree->db;
|
||||||
assert( sqlite3BtreeHoldsMutex(pBtree) );
|
assert( sqlite3BtreeHoldsMutex(pBtree) );
|
||||||
for(p=pBt->pCursor; p; p=p->pNext){
|
for(p=pBt->pCursor; p; p=p->pNext){
|
||||||
if( p==pExclude ) continue;
|
if( p==pExclude ) continue;
|
||||||
if( p->eState!=CURSOR_VALID ) continue;
|
if( p->eState!=CURSOR_VALID ) continue;
|
||||||
if( p->pgnoRoot!=pgnoRoot ) continue;
|
if( p->pgnoRoot!=pgnoRoot ) continue;
|
||||||
if( p->wrFlag==0 ){
|
if( p->wrFlag==0 ){
|
||||||
sqlite3 *dbOther = p->pBtree->pSqlite;
|
sqlite3 *dbOther = p->pBtree->db;
|
||||||
if( dbOther==0 ||
|
if( dbOther==0 ||
|
||||||
(dbOther!=db && (dbOther->flags & SQLITE_ReadUncommitted)==0) ){
|
(dbOther!=db && (dbOther->flags & SQLITE_ReadUncommitted)==0) ){
|
||||||
return SQLITE_LOCKED;
|
return SQLITE_LOCKED;
|
||||||
@@ -5880,6 +5891,7 @@ static int btreeCreateTable(Btree *p, int *piTable, int flags){
|
|||||||
int sqlite3BtreeCreateTable(Btree *p, int *piTable, int flags){
|
int sqlite3BtreeCreateTable(Btree *p, int *piTable, int flags){
|
||||||
int rc;
|
int rc;
|
||||||
sqlite3BtreeEnter(p);
|
sqlite3BtreeEnter(p);
|
||||||
|
p->pBt->db = p->db;
|
||||||
rc = btreeCreateTable(p, piTable, flags);
|
rc = btreeCreateTable(p, piTable, flags);
|
||||||
sqlite3BtreeLeave(p);
|
sqlite3BtreeLeave(p);
|
||||||
return rc;
|
return rc;
|
||||||
@@ -5944,6 +5956,7 @@ int sqlite3BtreeClearTable(Btree *p, int iTable){
|
|||||||
int rc;
|
int rc;
|
||||||
BtShared *pBt = p->pBt;
|
BtShared *pBt = p->pBt;
|
||||||
sqlite3BtreeEnter(p);
|
sqlite3BtreeEnter(p);
|
||||||
|
pBt->db = p->db;
|
||||||
if( p->inTrans!=TRANS_WRITE ){
|
if( p->inTrans!=TRANS_WRITE ){
|
||||||
rc = pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
|
rc = pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
|
||||||
}else if( (rc = checkReadLocks(p, iTable, 0))!=SQLITE_OK ){
|
}else if( (rc = checkReadLocks(p, iTable, 0))!=SQLITE_OK ){
|
||||||
@@ -6087,6 +6100,7 @@ static int btreeDropTable(Btree *p, int iTable, int *piMoved){
|
|||||||
int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){
|
int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){
|
||||||
int rc;
|
int rc;
|
||||||
sqlite3BtreeEnter(p);
|
sqlite3BtreeEnter(p);
|
||||||
|
p->pBt->db = p->db;
|
||||||
rc = btreeDropTable(p, iTable, piMoved);
|
rc = btreeDropTable(p, iTable, piMoved);
|
||||||
sqlite3BtreeLeave(p);
|
sqlite3BtreeLeave(p);
|
||||||
return rc;
|
return rc;
|
||||||
@@ -6110,6 +6124,7 @@ int sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){
|
|||||||
BtShared *pBt = p->pBt;
|
BtShared *pBt = p->pBt;
|
||||||
|
|
||||||
sqlite3BtreeEnter(p);
|
sqlite3BtreeEnter(p);
|
||||||
|
pBt->db = p->db;
|
||||||
|
|
||||||
/* Reading a meta-data value requires a read-lock on page 1 (and hence
|
/* Reading a meta-data value requires a read-lock on page 1 (and hence
|
||||||
** the sqlite_master table. We grab this lock regardless of whether or
|
** the sqlite_master table. We grab this lock regardless of whether or
|
||||||
@@ -6155,6 +6170,7 @@ int sqlite3BtreeUpdateMeta(Btree *p, int idx, u32 iMeta){
|
|||||||
int rc;
|
int rc;
|
||||||
assert( idx>=1 && idx<=15 );
|
assert( idx>=1 && idx<=15 );
|
||||||
sqlite3BtreeEnter(p);
|
sqlite3BtreeEnter(p);
|
||||||
|
pBt->db = p->db;
|
||||||
if( p->inTrans!=TRANS_WRITE ){
|
if( p->inTrans!=TRANS_WRITE ){
|
||||||
rc = pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
|
rc = pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
|
||||||
}else{
|
}else{
|
||||||
@@ -6543,6 +6559,7 @@ char *sqlite3BtreeIntegrityCheck(
|
|||||||
BtShared *pBt = p->pBt;
|
BtShared *pBt = p->pBt;
|
||||||
|
|
||||||
sqlite3BtreeEnter(p);
|
sqlite3BtreeEnter(p);
|
||||||
|
pBt->db = p->db;
|
||||||
nRef = sqlite3PagerRefcount(pBt->pPager);
|
nRef = sqlite3PagerRefcount(pBt->pPager);
|
||||||
if( lockBtreeWithRetry(p)!=SQLITE_OK ){
|
if( lockBtreeWithRetry(p)!=SQLITE_OK ){
|
||||||
sqlite3BtreeLeave(p);
|
sqlite3BtreeLeave(p);
|
||||||
@@ -6569,7 +6586,7 @@ char *sqlite3BtreeIntegrityCheck(
|
|||||||
unlockBtreeIfUnused(pBt);
|
unlockBtreeIfUnused(pBt);
|
||||||
*pnErr = 1;
|
*pnErr = 1;
|
||||||
sqlite3BtreeLeave(p);
|
sqlite3BtreeLeave(p);
|
||||||
return sqlite3MPrintf(p->pSqlite, "Unable to malloc %d bytes",
|
return sqlite3MPrintf(p->db, "Unable to malloc %d bytes",
|
||||||
(sCheck.nPage+1)*sizeof(sCheck.anRef[0]));
|
(sCheck.nPage+1)*sizeof(sCheck.anRef[0]));
|
||||||
}
|
}
|
||||||
for(i=0; i<=sCheck.nPage; i++){ sCheck.anRef[i] = 0; }
|
for(i=0; i<=sCheck.nPage; i++){ sCheck.anRef[i] = 0; }
|
||||||
@@ -6686,6 +6703,9 @@ static int btreeCopyFile(Btree *pTo, Btree *pFrom){
|
|||||||
|
|
||||||
BtShared *pBtTo = pTo->pBt;
|
BtShared *pBtTo = pTo->pBt;
|
||||||
BtShared *pBtFrom = pFrom->pBt;
|
BtShared *pBtFrom = pFrom->pBt;
|
||||||
|
pBtTo->db = pTo->db;
|
||||||
|
pBtFrom->db = pFrom->db;
|
||||||
|
|
||||||
|
|
||||||
if( pTo->inTrans!=TRANS_WRITE || pFrom->inTrans!=TRANS_WRITE ){
|
if( pTo->inTrans!=TRANS_WRITE || pFrom->inTrans!=TRANS_WRITE ){
|
||||||
return SQLITE_ERROR;
|
return SQLITE_ERROR;
|
||||||
@@ -6748,7 +6768,7 @@ int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){
|
|||||||
** Return non-zero if a transaction is active.
|
** Return non-zero if a transaction is active.
|
||||||
*/
|
*/
|
||||||
int sqlite3BtreeIsInTrans(Btree *p){
|
int sqlite3BtreeIsInTrans(Btree *p){
|
||||||
assert( p==0 || sqlite3_mutex_held(p->pSqlite->mutex) );
|
assert( p==0 || sqlite3_mutex_held(p->db->mutex) );
|
||||||
return (p && (p->inTrans==TRANS_WRITE));
|
return (p && (p->inTrans==TRANS_WRITE));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6764,7 +6784,7 @@ int sqlite3BtreeIsInStmt(Btree *p){
|
|||||||
** Return non-zero if a read (or write) transaction is active.
|
** Return non-zero if a read (or write) transaction is active.
|
||||||
*/
|
*/
|
||||||
int sqlite3BtreeIsInReadTrans(Btree *p){
|
int sqlite3BtreeIsInReadTrans(Btree *p){
|
||||||
assert( sqlite3_mutex_held(p->pSqlite->mutex) );
|
assert( sqlite3_mutex_held(p->db->mutex) );
|
||||||
return (p && (p->inTrans!=TRANS_NONE));
|
return (p && (p->inTrans!=TRANS_NONE));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6801,7 +6821,7 @@ void *sqlite3BtreeSchema(Btree *p, int nBytes, void(*xFree)(void *)){
|
|||||||
*/
|
*/
|
||||||
int sqlite3BtreeSchemaLocked(Btree *p){
|
int sqlite3BtreeSchemaLocked(Btree *p){
|
||||||
int rc;
|
int rc;
|
||||||
assert( sqlite3_mutex_held(p->pSqlite->mutex) );
|
assert( sqlite3_mutex_held(p->db->mutex) );
|
||||||
sqlite3BtreeEnter(p);
|
sqlite3BtreeEnter(p);
|
||||||
rc = (queryTableLock(p, MASTER_ROOT, READ_LOCK)!=SQLITE_OK);
|
rc = (queryTableLock(p, MASTER_ROOT, READ_LOCK)!=SQLITE_OK);
|
||||||
sqlite3BtreeLeave(p);
|
sqlite3BtreeLeave(p);
|
||||||
@@ -6838,7 +6858,7 @@ int sqlite3BtreeLockTable(Btree *p, int iTab, u8 isWriteLock){
|
|||||||
*/
|
*/
|
||||||
int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){
|
int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){
|
||||||
assert( cursorHoldsMutex(pCsr) );
|
assert( cursorHoldsMutex(pCsr) );
|
||||||
assert( sqlite3_mutex_held(pCsr->pBtree->pSqlite->mutex) );
|
assert( sqlite3_mutex_held(pCsr->pBtree->db->mutex) );
|
||||||
assert(pCsr->isIncrblobHandle);
|
assert(pCsr->isIncrblobHandle);
|
||||||
if( pCsr->eState>=CURSOR_REQUIRESEEK ){
|
if( pCsr->eState>=CURSOR_REQUIRESEEK ){
|
||||||
if( pCsr->eState==CURSOR_FAULT ){
|
if( pCsr->eState==CURSOR_FAULT ){
|
||||||
@@ -6880,7 +6900,7 @@ int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){
|
|||||||
*/
|
*/
|
||||||
void sqlite3BtreeCacheOverflow(BtCursor *pCur){
|
void sqlite3BtreeCacheOverflow(BtCursor *pCur){
|
||||||
assert( cursorHoldsMutex(pCur) );
|
assert( cursorHoldsMutex(pCur) );
|
||||||
assert( sqlite3_mutex_held(pCur->pBtree->pSqlite->mutex) );
|
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
|
||||||
assert(!pCur->isIncrblobHandle);
|
assert(!pCur->isIncrblobHandle);
|
||||||
assert(!pCur->aOverflow);
|
assert(!pCur->aOverflow);
|
||||||
pCur->isIncrblobHandle = 1;
|
pCur->isIncrblobHandle = 1;
|
||||||
|
@@ -13,7 +13,7 @@
|
|||||||
** subsystem. See comments in the source code for a detailed description
|
** subsystem. See comments in the source code for a detailed description
|
||||||
** of what each interface routine does.
|
** of what each interface routine does.
|
||||||
**
|
**
|
||||||
** @(#) $Id: btree.h,v 1.93 2007/09/03 15:19:35 drh Exp $
|
** @(#) $Id: btree.h,v 1.94 2007/12/07 18:55:28 drh Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef _BTREE_H_
|
#ifndef _BTREE_H_
|
||||||
#define _BTREE_H_
|
#define _BTREE_H_
|
||||||
@@ -82,7 +82,6 @@ int sqlite3BtreeOpen(
|
|||||||
#define BTREE_PRIVATE 64 /* Never share with other connections */
|
#define BTREE_PRIVATE 64 /* Never share with other connections */
|
||||||
|
|
||||||
int sqlite3BtreeClose(Btree*);
|
int sqlite3BtreeClose(Btree*);
|
||||||
int sqlite3BtreeSetBusyHandler(Btree*,BusyHandler*);
|
|
||||||
int sqlite3BtreeSetCacheSize(Btree*,int);
|
int sqlite3BtreeSetCacheSize(Btree*,int);
|
||||||
int sqlite3BtreeSetSafetyLevel(Btree*,int,int);
|
int sqlite3BtreeSetSafetyLevel(Btree*,int,int);
|
||||||
int sqlite3BtreeSyncDisabled(Btree*);
|
int sqlite3BtreeSyncDisabled(Btree*);
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
** May you share freely, never taking more than you give.
|
** May you share freely, never taking more than you give.
|
||||||
**
|
**
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
** $Id: btreeInt.h,v 1.13 2007/08/30 01:19:59 drh Exp $
|
** $Id: btreeInt.h,v 1.14 2007/12/07 18:55:28 drh Exp $
|
||||||
**
|
**
|
||||||
** This file implements a external (disk-based) database using BTrees.
|
** This file implements a external (disk-based) database using BTrees.
|
||||||
** For a detailed discussion of BTrees, refer to
|
** For a detailed discussion of BTrees, refer to
|
||||||
@@ -325,13 +325,13 @@ struct MemPage {
|
|||||||
** they often do so without holding sqlite3.mutex.
|
** they often do so without holding sqlite3.mutex.
|
||||||
*/
|
*/
|
||||||
struct Btree {
|
struct Btree {
|
||||||
sqlite3 *pSqlite; /* The database connection holding this btree */
|
sqlite3 *db; /* The database connection holding this btree */
|
||||||
BtShared *pBt; /* Sharable content of this btree */
|
BtShared *pBt; /* Sharable content of this btree */
|
||||||
u8 inTrans; /* TRANS_NONE, TRANS_READ or TRANS_WRITE */
|
u8 inTrans; /* TRANS_NONE, TRANS_READ or TRANS_WRITE */
|
||||||
u8 sharable; /* True if we can share pBt with other pSqlite */
|
u8 sharable; /* True if we can share pBt with another db */
|
||||||
u8 locked; /* True if pSqlite currently has pBt locked */
|
u8 locked; /* True if db currently has pBt locked */
|
||||||
int wantToLock; /* Number of nested calls to sqlite3BtreeEnter() */
|
int wantToLock; /* Number of nested calls to sqlite3BtreeEnter() */
|
||||||
Btree *pNext; /* List of other sharable Btrees from the same pSqlite */
|
Btree *pNext; /* List of other sharable Btrees from the same db */
|
||||||
Btree *pPrev; /* Back pointer of the same list */
|
Btree *pPrev; /* Back pointer of the same list */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -365,6 +365,7 @@ struct Btree {
|
|||||||
*/
|
*/
|
||||||
struct BtShared {
|
struct BtShared {
|
||||||
Pager *pPager; /* The page cache */
|
Pager *pPager; /* The page cache */
|
||||||
|
sqlite3 *db; /* Database connection currently using this Btree */
|
||||||
BtCursor *pCursor; /* A list of all open cursors */
|
BtCursor *pCursor; /* A list of all open cursors */
|
||||||
MemPage *pPage1; /* First page of the database */
|
MemPage *pPage1; /* First page of the database */
|
||||||
u8 inStmt; /* True if we are in a statement subtransaction */
|
u8 inStmt; /* True if we are in a statement subtransaction */
|
||||||
@@ -384,12 +385,12 @@ struct BtShared {
|
|||||||
int minLocal; /* Minimum local payload in non-LEAFDATA tables */
|
int minLocal; /* Minimum local payload in non-LEAFDATA tables */
|
||||||
int maxLeaf; /* Maximum local payload in a LEAFDATA table */
|
int maxLeaf; /* Maximum local payload in a LEAFDATA table */
|
||||||
int minLeaf; /* Minimum local payload in a LEAFDATA table */
|
int minLeaf; /* Minimum local payload in a LEAFDATA table */
|
||||||
BusyHandler *pBusyHandler; /* Callback for when there is lock contention */
|
|
||||||
u8 inTransaction; /* Transaction state */
|
u8 inTransaction; /* Transaction state */
|
||||||
int nTransaction; /* Number of open transactions (read + write) */
|
int nTransaction; /* Number of open transactions (read + write) */
|
||||||
void *pSchema; /* Pointer to space allocated by sqlite3BtreeSchema() */
|
void *pSchema; /* Pointer to space allocated by sqlite3BtreeSchema() */
|
||||||
void (*xFreeSchema)(void*); /* Destructor for BtShared.pSchema */
|
void (*xFreeSchema)(void*); /* Destructor for BtShared.pSchema */
|
||||||
sqlite3_mutex *mutex; /* Non-recursive mutex required to access this struct */
|
sqlite3_mutex *mutex; /* Non-recursive mutex required to access this struct */
|
||||||
|
BusyHandler busyHdr; /* The busy handler for this btree */
|
||||||
#ifndef SQLITE_OMIT_SHARED_CACHE
|
#ifndef SQLITE_OMIT_SHARED_CACHE
|
||||||
int nRef; /* Number of references to this structure */
|
int nRef; /* Number of references to this structure */
|
||||||
BtShared *pNext; /* Next on a list of sharable BtShared structs */
|
BtShared *pNext; /* Next on a list of sharable BtShared structs */
|
||||||
@@ -423,7 +424,7 @@ struct CellInfo {
|
|||||||
**
|
**
|
||||||
** When a single database file can shared by two more database connections,
|
** When a single database file can shared by two more database connections,
|
||||||
** but cursors cannot be shared. Each cursor is associated with a
|
** but cursors cannot be shared. Each cursor is associated with a
|
||||||
** particular database connection identified BtCursor.pBtree.pSqlite.
|
** particular database connection identified BtCursor.pBtree.db.
|
||||||
**
|
**
|
||||||
** Fields in this structure are accessed under the BtShared.mutex
|
** Fields in this structure are accessed under the BtShared.mutex
|
||||||
** found at self->pBt->mutex.
|
** found at self->pBt->mutex.
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
** other files are for internal use by SQLite and should not be
|
** other files are for internal use by SQLite and should not be
|
||||||
** accessed by users of the library.
|
** accessed by users of the library.
|
||||||
**
|
**
|
||||||
** $Id: main.c,v 1.408 2007/12/05 01:38:23 drh Exp $
|
** $Id: main.c,v 1.409 2007/12/07 18:55:28 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@@ -766,7 +766,6 @@ int sqlite3BtreeFactory(
|
|||||||
}
|
}
|
||||||
rc = sqlite3BtreeOpen(zFilename, (sqlite3 *)db, ppBtree, btFlags, vfsFlags);
|
rc = sqlite3BtreeOpen(zFilename, (sqlite3 *)db, ppBtree, btFlags, vfsFlags);
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
sqlite3BtreeSetBusyHandler(*ppBtree, (void*)&db->busyHandler);
|
|
||||||
sqlite3BtreeSetCacheSize(*ppBtree, nCache);
|
sqlite3BtreeSetCacheSize(*ppBtree, nCache);
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
|
@@ -18,7 +18,7 @@
|
|||||||
** file simultaneously, or one process from reading the database while
|
** file simultaneously, or one process from reading the database while
|
||||||
** another is writing.
|
** another is writing.
|
||||||
**
|
**
|
||||||
** @(#) $Id: pager.c,v 1.397 2007/11/29 18:44:27 drh Exp $
|
** @(#) $Id: pager.c,v 1.398 2007/12/07 18:55:28 drh Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef SQLITE_OMIT_DISKIO
|
#ifndef SQLITE_OMIT_DISKIO
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
@@ -3151,6 +3151,7 @@ int sqlite3PagerReleaseMemory(int nReq){
|
|||||||
int nReleased = 0; /* Bytes of memory released so far */
|
int nReleased = 0; /* Bytes of memory released so far */
|
||||||
sqlite3_mutex *mutex; /* The MEM2 mutex */
|
sqlite3_mutex *mutex; /* The MEM2 mutex */
|
||||||
Pager *pPager; /* For looping over pagers */
|
Pager *pPager; /* For looping over pagers */
|
||||||
|
BusyHandler *savedBusy; /* Saved copy of the busy handler */
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
|
|
||||||
/* Acquire the memory-management mutex
|
/* Acquire the memory-management mutex
|
||||||
@@ -3195,7 +3196,10 @@ int sqlite3PagerReleaseMemory(int nReq){
|
|||||||
assert(!pPg->needSync || pPg==pPager->lru.pFirst);
|
assert(!pPg->needSync || pPg==pPager->lru.pFirst);
|
||||||
assert(pPg->needSync || pPg==pPager->lru.pFirstSynced);
|
assert(pPg->needSync || pPg==pPager->lru.pFirstSynced);
|
||||||
|
|
||||||
|
savedBusy = pPager->pBusyHandler;
|
||||||
|
pPager->pBusyHandler = 0;
|
||||||
rc = pager_recycle(pPager, &pRecycled);
|
rc = pager_recycle(pPager, &pRecycled);
|
||||||
|
pPager->pBusyHandler = savedBusy;
|
||||||
assert(pRecycled==pPg || rc!=SQLITE_OK);
|
assert(pRecycled==pPg || rc!=SQLITE_OK);
|
||||||
if( rc==SQLITE_OK ){
|
if( rc==SQLITE_OK ){
|
||||||
/* We've found a page to free. At this point the page has been
|
/* We've found a page to free. At this point the page has been
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** Internal interface definitions for SQLite.
|
** Internal interface definitions for SQLite.
|
||||||
**
|
**
|
||||||
** @(#) $Id: sqliteInt.h,v 1.623 2007/12/05 01:38:24 drh Exp $
|
** @(#) $Id: sqliteInt.h,v 1.624 2007/12/07 18:55:29 drh Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef _SQLITEINT_H_
|
#ifndef _SQLITEINT_H_
|
||||||
#define _SQLITEINT_H_
|
#define _SQLITEINT_H_
|
||||||
@@ -1620,8 +1620,10 @@ typedef struct {
|
|||||||
#ifdef SQLITE_DEBUG
|
#ifdef SQLITE_DEBUG
|
||||||
int sqlite3Corrupt(void);
|
int sqlite3Corrupt(void);
|
||||||
# define SQLITE_CORRUPT_BKPT sqlite3Corrupt()
|
# define SQLITE_CORRUPT_BKPT sqlite3Corrupt()
|
||||||
|
# define DEBUGONLY(X) X
|
||||||
#else
|
#else
|
||||||
# define SQLITE_CORRUPT_BKPT SQLITE_CORRUPT
|
# define SQLITE_CORRUPT_BKPT SQLITE_CORRUPT
|
||||||
|
# define DEBUGONLY(X)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
10
src/test3.c
10
src/test3.c
@@ -13,7 +13,7 @@
|
|||||||
** is not included in the SQLite library. It is used for automated
|
** is not included in the SQLite library. It is used for automated
|
||||||
** testing of the SQLite library.
|
** testing of the SQLite library.
|
||||||
**
|
**
|
||||||
** $Id: test3.c,v 1.87 2007/09/12 17:01:45 danielk1977 Exp $
|
** $Id: test3.c,v 1.88 2007/12/07 18:55:29 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "btreeInt.h"
|
#include "btreeInt.h"
|
||||||
@@ -566,7 +566,7 @@ static int btree_pager_stats(
|
|||||||
** we need to obtain the mutex for the controlling SQLite handle before
|
** we need to obtain the mutex for the controlling SQLite handle before
|
||||||
** it is safe to call sqlite3BtreeEnter().
|
** it is safe to call sqlite3BtreeEnter().
|
||||||
*/
|
*/
|
||||||
sqlite3_mutex_enter(pBt->pSqlite->mutex);
|
sqlite3_mutex_enter(pBt->db->mutex);
|
||||||
|
|
||||||
sqlite3BtreeEnter(pBt);
|
sqlite3BtreeEnter(pBt);
|
||||||
a = sqlite3PagerStats(sqlite3BtreePager(pBt));
|
a = sqlite3PagerStats(sqlite3BtreePager(pBt));
|
||||||
@@ -583,7 +583,7 @@ static int btree_pager_stats(
|
|||||||
sqlite3BtreeLeave(pBt);
|
sqlite3BtreeLeave(pBt);
|
||||||
|
|
||||||
/* Release the mutex on the SQLite handle that controls this b-tree */
|
/* Release the mutex on the SQLite handle that controls this b-tree */
|
||||||
sqlite3_mutex_leave(pBt->pSqlite->mutex);
|
sqlite3_mutex_leave(pBt->db->mutex);
|
||||||
return TCL_OK;
|
return TCL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1591,11 +1591,11 @@ static int btree_set_cache_size(
|
|||||||
pBt = sqlite3TextToPtr(argv[1]);
|
pBt = sqlite3TextToPtr(argv[1]);
|
||||||
if( Tcl_GetInt(interp, argv[2], &nCache) ) return TCL_ERROR;
|
if( Tcl_GetInt(interp, argv[2], &nCache) ) return TCL_ERROR;
|
||||||
|
|
||||||
sqlite3_mutex_enter(pBt->pSqlite->mutex);
|
sqlite3_mutex_enter(pBt->db->mutex);
|
||||||
sqlite3BtreeEnter(pBt);
|
sqlite3BtreeEnter(pBt);
|
||||||
sqlite3BtreeSetCacheSize(pBt, nCache);
|
sqlite3BtreeSetCacheSize(pBt, nCache);
|
||||||
sqlite3BtreeLeave(pBt);
|
sqlite3BtreeLeave(pBt);
|
||||||
sqlite3_mutex_leave(pBt->pSqlite->mutex);
|
sqlite3_mutex_leave(pBt->db->mutex);
|
||||||
|
|
||||||
return TCL_OK;
|
return TCL_OK;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user