/ Check-in [c9eb6591]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment: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)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: c9eb65912f61ce0a6b66fe253652a1827e46b12a
User & Date: drh 2007-12-07 18:55:28
Context
2007-12-07
23:47
Change prefix search from O(N*M) to O(NlogM). The previous code linearly merged the doclists, so as the accumulated list got large, things got slow (the M term, a fucntion of the number of documents in the index). This change does pairwise merges until a single doclist remains. A test search of 't*' against a database of RFC text improves from 1m16s to 4.75s. (CVS 4599) check-in: feef1b15 user: shess tags: trunk
18:55
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) check-in: c9eb6591 user: drh tags: trunk
18:39
Get the LIKE and GLOB operators working again on systems using the EBCDIC character set. (CVS 4597) check-in: 754298a7 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/btmutex.c.

     6      6   **
     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   **
    13         -** $Id: btmutex.c,v 1.7 2007/08/30 01:19:59 drh Exp $
           13  +** $Id: btmutex.c,v 1.8 2007/12/07 18:55:28 drh Exp $
    14     14   **
    15     15   ** This file contains code used to implement mutexes on Btree objects.
    16     16   ** This code really belongs in btree.c.  But btree.c is getting too
    17     17   ** big and we want to break it down some.  This packaged seemed like
    18     18   ** a good breakout.
    19     19   */
    20     20   #include "btreeInt.h"
................................................................................
    42     42   
    43     43     /* Some basic sanity checking on the Btree.  The list of Btrees
    44     44     ** connected by pNext and pPrev should be in sorted order by
    45     45     ** Btree.pBt value. All elements of the list should belong to
    46     46     ** the same connection. Only shared Btrees are on the list. */
    47     47     assert( p->pNext==0 || p->pNext->pBt>p->pBt );
    48     48     assert( p->pPrev==0 || p->pPrev->pBt<p->pBt );
    49         -  assert( p->pNext==0 || p->pNext->pSqlite==p->pSqlite );
    50         -  assert( p->pPrev==0 || p->pPrev->pSqlite==p->pSqlite );
           49  +  assert( p->pNext==0 || p->pNext->db==p->db );
           50  +  assert( p->pPrev==0 || p->pPrev->db==p->db );
    51     51     assert( p->sharable || (p->pNext==0 && p->pPrev==0) );
    52     52   
    53     53     /* Check for locking consistency */
    54     54     assert( !p->locked || p->wantToLock>0 );
    55     55     assert( p->sharable || p->wantToLock==0 );
    56     56   
    57     57     /* We should already hold a lock on the database connection */
    58         -  assert( sqlite3_mutex_held(p->pSqlite->mutex) );
           58  +  assert( sqlite3_mutex_held(p->db->mutex) );
    59     59   
    60     60     if( !p->sharable ) return;
    61     61     p->wantToLock++;
    62     62     if( p->locked ) return;
    63     63   
    64     64     /* In most cases, we should be able to acquire the lock we
    65     65     ** want without having to go throught the ascending lock
................................................................................
   274    274     for(i=0; i<pArray->nMutex; i++){
   275    275       Btree *p = pArray->aBtree[i];
   276    276       /* Some basic sanity checking */
   277    277       assert( i==0 || pArray->aBtree[i-1]->pBt<p->pBt );
   278    278       assert( !p->locked || p->wantToLock>0 );
   279    279   
   280    280       /* We should already hold a lock on the database connection */
   281         -    assert( sqlite3_mutex_held(p->pSqlite->mutex) );
          281  +    assert( sqlite3_mutex_held(p->db->mutex) );
   282    282   
   283    283       p->wantToLock++;
   284    284       if( !p->locked && p->sharable ){
   285    285         sqlite3_mutex_enter(p->pBt->mutex);
   286    286         p->locked = 1;
   287    287       }
   288    288     }
................................................................................
   297    297       Btree *p = pArray->aBtree[i];
   298    298       /* Some basic sanity checking */
   299    299       assert( i==0 || pArray->aBtree[i-1]->pBt<p->pBt );
   300    300       assert( p->locked || !p->sharable );
   301    301       assert( p->wantToLock>0 );
   302    302   
   303    303       /* We should already hold a lock on the database connection */
   304         -    assert( sqlite3_mutex_held(p->pSqlite->mutex) );
          304  +    assert( sqlite3_mutex_held(p->db->mutex) );
   305    305   
   306    306       p->wantToLock--;
   307    307       if( p->wantToLock==0 && p->locked ){
   308    308         sqlite3_mutex_leave(p->pBt->mutex);
   309    309         p->locked = 0;
   310    310       }
   311    311     }
   312    312   }
   313    313   
   314    314   
   315    315   #endif  /* SQLITE_THREADSAFE && !SQLITE_OMIT_SHARED_CACHE */

Changes to src/btree.c.

     5      5   ** a legal notice, here is a blessing:
     6      6   **
     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12         -** $Id: btree.c,v 1.431 2007/11/28 16:19:56 drh Exp $
           12  +** $Id: btree.c,v 1.432 2007/12/07 18:55:28 drh Exp $
    13     13   **
    14     14   ** This file implements a external (disk-based) database using BTrees.
    15     15   ** See the header comment on "btreeInt.h" for additional information.
    16     16   ** Including a description of file format and an overview of operation.
    17     17   */
    18     18   #include "btreeInt.h"
    19     19   
................................................................................
   114    114     ** (BtShared.pLock).
   115    115     **
   116    116     ** To summarize: If the ReadUncommitted flag is set, then read cursors do
   117    117     ** not create or respect table locks. The locking procedure for a 
   118    118     ** write-cursor does not change.
   119    119     */
   120    120     if( 
   121         -    !p->pSqlite || 
   122         -    0==(p->pSqlite->flags&SQLITE_ReadUncommitted) || 
          121  +    !p->db || 
          122  +    0==(p->db->flags&SQLITE_ReadUncommitted) || 
   123    123       eLock==WRITE_LOCK ||
   124    124       iTab==MASTER_ROOT
   125    125     ){
   126    126       for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){
   127    127         if( pIter->pBtree!=p && pIter->iTable==iTab && 
   128    128             (pIter->eLock!=eLock || eLock!=READ_LOCK) ){
   129    129           return SQLITE_LOCKED;
................................................................................
   159    159   
   160    160     /* If the read-uncommitted flag is set and a read-lock is requested,
   161    161     ** return early without adding an entry to the BtShared.pLock list. See
   162    162     ** comment in function queryTableLock() for more info on handling 
   163    163     ** the ReadUncommitted flag.
   164    164     */
   165    165     if( 
   166         -    (p->pSqlite) && 
   167         -    (p->pSqlite->flags&SQLITE_ReadUncommitted) && 
          166  +    (p->db) && 
          167  +    (p->db->flags&SQLITE_ReadUncommitted) && 
   168    168       (eLock==READ_LOCK) &&
   169    169       iTable!=MASTER_ROOT
   170    170     ){
   171    171       return SQLITE_OK;
   172    172     }
   173    173   
   174    174     /* First search the list for an existing lock on this table. */
................................................................................
  1093   1093     pPage = (MemPage *)sqlite3PagerGetExtra(pData);
  1094   1094     if( pPage->isInit ){
  1095   1095       assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  1096   1096       pPage->isInit = 0;
  1097   1097       sqlite3BtreeInitPage(pPage, pPage->pParent);
  1098   1098     }
  1099   1099   }
         1100  +
         1101  +/*
         1102  +** Invoke the busy handler for a btree.
         1103  +*/
         1104  +static int sqlite3BtreeInvokeBusyHandler(void *pArg, int n){
         1105  +  BtShared *pBt = (BtShared*)pArg;
         1106  +  assert( pBt->db );
         1107  +  assert( sqlite3_mutex_held(pBt->db->mutex) );
         1108  +  return sqlite3InvokeBusyHandler(&pBt->db->busyHandler);
         1109  +}
  1100   1110   
  1101   1111   /*
  1102   1112   ** Open a database file.
  1103   1113   ** 
  1104   1114   ** zFilename is the name of the database file.  If zFilename is NULL
  1105   1115   ** a new database with a random name is created.  This randomly named
  1106   1116   ** database file will be deleted when sqlite3BtreeClose() is called.
  1107   1117   ** If zFilename is ":memory:" then an in-memory database is created
  1108   1118   ** that is automatically destroyed when it is closed.
  1109   1119   */
  1110   1120   int sqlite3BtreeOpen(
  1111   1121     const char *zFilename,  /* Name of the file containing the BTree database */
  1112         -  sqlite3 *pSqlite,       /* Associated database handle */
         1122  +  sqlite3 *db,            /* Associated database handle */
  1113   1123     Btree **ppBtree,        /* Pointer to new Btree object written here */
  1114   1124     int flags,              /* Options */
  1115   1125     int vfsFlags            /* Flags passed through to sqlite3_vfs.xOpen() */
  1116   1126   ){
  1117   1127     sqlite3_vfs *pVfs;      /* The VFS to use for this btree */
  1118   1128     BtShared *pBt = 0;      /* Shared part of btree structure */
  1119   1129     Btree *p;               /* Handle to return */
................................................................................
  1130   1140     #ifdef SQLITE_OMIT_MEMORYDB
  1131   1141       const int isMemdb = 0;
  1132   1142     #else
  1133   1143       const int isMemdb = zFilename && !strcmp(zFilename, ":memory:");
  1134   1144     #endif
  1135   1145   #endif
  1136   1146   
  1137         -  assert( pSqlite!=0 );
  1138         -  assert( sqlite3_mutex_held(pSqlite->mutex) );
         1147  +  assert( db!=0 );
         1148  +  assert( sqlite3_mutex_held(db->mutex) );
  1139   1149   
  1140         -  pVfs = pSqlite->pVfs;
         1150  +  pVfs = db->pVfs;
  1141   1151     p = sqlite3MallocZero(sizeof(Btree));
  1142   1152     if( !p ){
  1143   1153       return SQLITE_NOMEM;
  1144   1154     }
  1145   1155     p->inTrans = TRANS_NONE;
  1146         -  p->pSqlite = pSqlite;
         1156  +  p->db = db;
  1147   1157   
  1148   1158   #if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
  1149   1159     /*
  1150   1160     ** If this Btree is a candidate for shared cache, try to find an
  1151   1161     ** existing BtShared object that we can share with
  1152   1162     */
  1153   1163     if( (flags & BTREE_PRIVATE)==0
  1154   1164      && isMemdb==0
  1155         -   && (pSqlite->flags & SQLITE_Vtab)==0
         1165  +   && (db->flags & SQLITE_Vtab)==0
  1156   1166      && zFilename && zFilename[0]
  1157   1167     ){
  1158   1168       if( sqlite3SharedCacheEnabled ){
  1159   1169         int nFullPathname = pVfs->mxPathname+1;
  1160   1170         char *zFullPathname = (char *)sqlite3_malloc(nFullPathname);
  1161   1171         sqlite3_mutex *mutexShared;
  1162   1172         p->sharable = 1;
  1163         -      if( pSqlite ){
  1164         -        pSqlite->flags |= SQLITE_SharedCache;
         1173  +      if( db ){
         1174  +        db->flags |= SQLITE_SharedCache;
  1165   1175         }
  1166   1176         if( !zFullPathname ){
  1167   1177           sqlite3_free(p);
  1168   1178           return SQLITE_NOMEM;
  1169   1179         }
  1170   1180         sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname);
  1171   1181         mutexShared = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
................................................................................
  1207   1217       assert( sizeof(Pgno)==4 );
  1208   1218     
  1209   1219       pBt = sqlite3MallocZero( sizeof(*pBt) );
  1210   1220       if( pBt==0 ){
  1211   1221         rc = SQLITE_NOMEM;
  1212   1222         goto btree_open_out;
  1213   1223       }
         1224  +    pBt->busyHdr.xFunc = sqlite3BtreeInvokeBusyHandler;
         1225  +    pBt->busyHdr.pArg = pBt;
  1214   1226       rc = sqlite3PagerOpen(pVfs, &pBt->pPager, zFilename,
  1215   1227                             EXTRA_SIZE, flags, vfsFlags);
  1216   1228       if( rc==SQLITE_OK ){
  1217   1229         rc = sqlite3PagerReadFileheader(pBt->pPager,sizeof(zDbHeader),zDbHeader);
  1218   1230       }
  1219   1231       if( rc!=SQLITE_OK ){
  1220   1232         goto btree_open_out;
  1221   1233       }
         1234  +    sqlite3PagerSetBusyhandler(pBt->pPager, &pBt->busyHdr);
  1222   1235       p->pBt = pBt;
  1223   1236     
  1224   1237       sqlite3PagerSetDestructor(pBt->pPager, pageDestructor);
  1225   1238       sqlite3PagerSetReiniter(pBt->pPager, pageReinit);
  1226   1239       pBt->pCursor = 0;
  1227   1240       pBt->pPage1 = 0;
  1228   1241       pBt->readOnly = sqlite3PagerIsreadonly(pBt->pPager);
................................................................................
  1269   1282         sqlite3_mutex *mutexShared;
  1270   1283         pBt->nRef = 1;
  1271   1284         mutexShared = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
  1272   1285         if( SQLITE_THREADSAFE ){
  1273   1286           pBt->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
  1274   1287           if( pBt->mutex==0 ){
  1275   1288             rc = SQLITE_NOMEM;
  1276         -          pSqlite->mallocFailed = 0;
         1289  +          db->mallocFailed = 0;
  1277   1290             goto btree_open_out;
  1278   1291           }
  1279   1292         }
  1280   1293         sqlite3_mutex_enter(mutexShared);
  1281   1294         pBt->pNext = sqlite3SharedCacheList;
  1282   1295         sqlite3SharedCacheList = pBt;
  1283   1296         sqlite3_mutex_leave(mutexShared);
................................................................................
  1289   1302     /* If the new Btree uses a sharable pBtShared, then link the new
  1290   1303     ** Btree into the list of all sharable Btrees for the same connection.
  1291   1304     ** The list is kept in ascending order by pBt address.
  1292   1305     */
  1293   1306     if( p->sharable ){
  1294   1307       int i;
  1295   1308       Btree *pSib;
  1296         -    for(i=0; i<pSqlite->nDb; i++){
  1297         -      if( (pSib = pSqlite->aDb[i].pBt)!=0 && pSib->sharable ){
         1309  +    for(i=0; i<db->nDb; i++){
         1310  +      if( (pSib = db->aDb[i].pBt)!=0 && pSib->sharable ){
  1298   1311           while( pSib->pPrev ){ pSib = pSib->pPrev; }
  1299   1312           if( p->pBt<pSib->pBt ){
  1300   1313             p->pNext = pSib;
  1301   1314             p->pPrev = 0;
  1302   1315             pSib->pPrev = p;
  1303   1316           }else{
  1304   1317             while( pSib->pNext && pSib->pNext->pBt<p->pBt ){
................................................................................
  1374   1387   ** Close an open database and invalidate all cursors.
  1375   1388   */
  1376   1389   int sqlite3BtreeClose(Btree *p){
  1377   1390     BtShared *pBt = p->pBt;
  1378   1391     BtCursor *pCur;
  1379   1392   
  1380   1393     /* Close all cursors opened via this handle.  */
  1381         -  assert( sqlite3_mutex_held(p->pSqlite->mutex) );
         1394  +  assert( sqlite3_mutex_held(p->db->mutex) );
  1382   1395     sqlite3BtreeEnter(p);
         1396  +  pBt->db = p->db;
  1383   1397     pCur = pBt->pCursor;
  1384   1398     while( pCur ){
  1385   1399       BtCursor *pTmp = pCur;
  1386   1400       pCur = pCur->pNext;
  1387   1401       if( pTmp->pBtree==p ){
  1388   1402         sqlite3BtreeCloseCursor(pTmp);
  1389   1403       }
................................................................................
  1423   1437     if( p->pNext ) p->pNext->pPrev = p->pPrev;
  1424   1438   #endif
  1425   1439   
  1426   1440     sqlite3_free(p);
  1427   1441     return SQLITE_OK;
  1428   1442   }
  1429   1443   
  1430         -/*
  1431         -** Change the busy handler callback function.
  1432         -*/
  1433         -int sqlite3BtreeSetBusyHandler(Btree *p, BusyHandler *pHandler){
  1434         -  BtShared *pBt = p->pBt;
  1435         -  assert( sqlite3_mutex_held(p->pSqlite->mutex) );
  1436         -  sqlite3BtreeEnter(p);
  1437         -  pBt->pBusyHandler = pHandler;
  1438         -  sqlite3PagerSetBusyhandler(pBt->pPager, pHandler);
  1439         -  sqlite3BtreeLeave(p);
  1440         -  return SQLITE_OK;
  1441         -}
  1442         -
  1443   1444   /*
  1444   1445   ** Change the limit on the number of pages allowed in the cache.
  1445   1446   **
  1446   1447   ** The maximum number of cache pages is set to the absolute
  1447   1448   ** value of mxPage.  If mxPage is negative, the pager will
  1448   1449   ** operate asynchronously - it will not stop to do fsync()s
  1449   1450   ** to insure data is written to the disk surface before
................................................................................
  1453   1454   ** an abrupt power failure when synchronous is off, the database
  1454   1455   ** could be left in an inconsistent and unrecoverable state.
  1455   1456   ** Synchronous is on by default so database corruption is not
  1456   1457   ** normally a worry.
  1457   1458   */
  1458   1459   int sqlite3BtreeSetCacheSize(Btree *p, int mxPage){
  1459   1460     BtShared *pBt = p->pBt;
  1460         -  assert( sqlite3_mutex_held(p->pSqlite->mutex) );
         1461  +  assert( sqlite3_mutex_held(p->db->mutex) );
  1461   1462     sqlite3BtreeEnter(p);
  1462   1463     sqlite3PagerSetCachesize(pBt->pPager, mxPage);
  1463   1464     sqlite3BtreeLeave(p);
  1464   1465     return SQLITE_OK;
  1465   1466   }
  1466   1467   
  1467   1468   /*
................................................................................
  1471   1472   ** there is a high probability of damage)  Level 2 is the default.  There
  1472   1473   ** is a very low but non-zero probability of damage.  Level 3 reduces the
  1473   1474   ** probability of damage to near zero but with a write performance reduction.
  1474   1475   */
  1475   1476   #ifndef SQLITE_OMIT_PAGER_PRAGMAS
  1476   1477   int sqlite3BtreeSetSafetyLevel(Btree *p, int level, int fullSync){
  1477   1478     BtShared *pBt = p->pBt;
  1478         -  assert( sqlite3_mutex_held(p->pSqlite->mutex) );
         1479  +  assert( sqlite3_mutex_held(p->db->mutex) );
  1479   1480     sqlite3BtreeEnter(p);
  1480   1481     sqlite3PagerSetSafetyLevel(pBt->pPager, level, fullSync);
  1481   1482     sqlite3BtreeLeave(p);
  1482   1483     return SQLITE_OK;
  1483   1484   }
  1484   1485   #endif
  1485   1486   
................................................................................
  1486   1487   /*
  1487   1488   ** Return TRUE if the given btree is set to safety level 1.  In other
  1488   1489   ** words, return TRUE if no sync() occurs on the disk files.
  1489   1490   */
  1490   1491   int sqlite3BtreeSyncDisabled(Btree *p){
  1491   1492     BtShared *pBt = p->pBt;
  1492   1493     int rc;
  1493         -  assert( sqlite3_mutex_held(p->pSqlite->mutex) );  
         1494  +  assert( sqlite3_mutex_held(p->db->mutex) );  
  1494   1495     sqlite3BtreeEnter(p);
  1495   1496     assert( pBt && pBt->pPager );
  1496   1497     rc = sqlite3PagerNosync(pBt->pPager);
  1497   1498     sqlite3BtreeLeave(p);
  1498   1499     return rc;
  1499   1500   }
  1500   1501   
................................................................................
  1819   1820   ** proceed.
  1820   1821   */
  1821   1822   int sqlite3BtreeBeginTrans(Btree *p, int wrflag){
  1822   1823     BtShared *pBt = p->pBt;
  1823   1824     int rc = SQLITE_OK;
  1824   1825   
  1825   1826     sqlite3BtreeEnter(p);
         1827  +  pBt->db = p->db;
  1826   1828     btreeIntegrity(p);
  1827   1829   
  1828   1830     /* If the btree is already in a write-transaction, or it
  1829   1831     ** is already in a read-transaction and a read-transaction
  1830   1832     ** is requested, this is a no-op.
  1831   1833     */
  1832   1834     if( p->inTrans==TRANS_WRITE || (p->inTrans==TRANS_READ && !wrflag) ){
................................................................................
  1866   1868     
  1867   1869       if( rc==SQLITE_OK ){
  1868   1870         if( wrflag ) pBt->inStmt = 0;
  1869   1871       }else{
  1870   1872         unlockBtreeIfUnused(pBt);
  1871   1873       }
  1872   1874     }while( rc==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE &&
  1873         -          sqlite3InvokeBusyHandler(pBt->pBusyHandler) );
         1875  +          sqlite3BtreeInvokeBusyHandler(pBt, 0) );
  1874   1876   
  1875   1877     if( rc==SQLITE_OK ){
  1876   1878       if( p->inTrans==TRANS_NONE ){
  1877   1879         pBt->nTransaction++;
  1878   1880       }
  1879   1881       p->inTrans = (wrflag?TRANS_WRITE:TRANS_READ);
  1880   1882       if( p->inTrans>pBt->inTransaction ){
................................................................................
  2192   2194   ** SQLITE_OK is returned. Otherwise an SQLite error code. 
  2193   2195   */
  2194   2196   int sqlite3BtreeIncrVacuum(Btree *p){
  2195   2197     int rc;
  2196   2198     BtShared *pBt = p->pBt;
  2197   2199   
  2198   2200     sqlite3BtreeEnter(p);
         2201  +  pBt->db = p->db;
  2199   2202     assert( pBt->inTransaction==TRANS_WRITE && p->inTrans==TRANS_WRITE );
  2200   2203     if( !pBt->autoVacuum ){
  2201   2204       rc = SQLITE_DONE;
  2202   2205     }else{
  2203   2206       invalidateAllOverflowCache(pBt);
  2204   2207       rc = incrVacuumStep(pBt, 0);
  2205   2208     }
................................................................................
  2308   2311   */
  2309   2312   int sqlite3BtreeCommitPhaseOne(Btree *p, const char *zMaster){
  2310   2313     int rc = SQLITE_OK;
  2311   2314     if( p->inTrans==TRANS_WRITE ){
  2312   2315       BtShared *pBt = p->pBt;
  2313   2316       Pgno nTrunc = 0;
  2314   2317       sqlite3BtreeEnter(p);
         2318  +    pBt->db = p->db;
  2315   2319   #ifndef SQLITE_OMIT_AUTOVACUUM
  2316   2320       if( pBt->autoVacuum ){
  2317   2321         rc = autoVacuumCommit(pBt, &nTrunc); 
  2318   2322         if( rc!=SQLITE_OK ){
  2319   2323           sqlite3BtreeLeave(p);
  2320   2324           return rc;
  2321   2325         }
................................................................................
  2341   2345   ** This will release the write lock on the database file.  If there
  2342   2346   ** are no active cursors, it also releases the read lock.
  2343   2347   */
  2344   2348   int sqlite3BtreeCommitPhaseTwo(Btree *p){
  2345   2349     BtShared *pBt = p->pBt;
  2346   2350   
  2347   2351     sqlite3BtreeEnter(p);
         2352  +  pBt->db = p->db;
  2348   2353     btreeIntegrity(p);
  2349   2354   
  2350   2355     /* If the handle has a write-transaction open, commit the shared-btrees 
  2351   2356     ** transaction and set the shared state to TRANS_READ.
  2352   2357     */
  2353   2358     if( p->inTrans==TRANS_WRITE ){
  2354   2359       int rc;
................................................................................
  2461   2466   */
  2462   2467   int sqlite3BtreeRollback(Btree *p){
  2463   2468     int rc;
  2464   2469     BtShared *pBt = p->pBt;
  2465   2470     MemPage *pPage1;
  2466   2471   
  2467   2472     sqlite3BtreeEnter(p);
         2473  +  pBt->db = p->db;
  2468   2474     rc = saveAllCursors(pBt, 0, 0);
  2469   2475   #ifndef SQLITE_OMIT_SHARED_CACHE
  2470   2476     if( rc!=SQLITE_OK ){
  2471   2477       /* This is a horrible situation. An IO or malloc() error occured whilst
  2472   2478       ** trying to save cursor positions. If this is an automatic rollback (as
  2473   2479       ** the result of a constraint, malloc() failure or IO error) then 
  2474   2480       ** the cache may be internally inconsistent (not contain valid trees) so
................................................................................
  2536   2542   ** error occurs within the statement, the effect of that one statement
  2537   2543   ** can be rolled back without having to rollback the entire transaction.
  2538   2544   */
  2539   2545   int sqlite3BtreeBeginStmt(Btree *p){
  2540   2546     int rc;
  2541   2547     BtShared *pBt = p->pBt;
  2542   2548     sqlite3BtreeEnter(p);
         2549  +  pBt->db = p->db;
  2543   2550     if( (p->inTrans!=TRANS_WRITE) || pBt->inStmt ){
  2544   2551       rc = pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
  2545   2552     }else{
  2546   2553       assert( pBt->inTransaction==TRANS_WRITE );
  2547   2554       rc = pBt->readOnly ? SQLITE_OK : sqlite3PagerStmtBegin(pBt->pPager);
  2548   2555       pBt->inStmt = 1;
  2549   2556     }
................................................................................
  2556   2563   ** Commit the statment subtransaction currently in progress.  If no
  2557   2564   ** subtransaction is active, this is a no-op.
  2558   2565   */
  2559   2566   int sqlite3BtreeCommitStmt(Btree *p){
  2560   2567     int rc;
  2561   2568     BtShared *pBt = p->pBt;
  2562   2569     sqlite3BtreeEnter(p);
         2570  +  pBt->db = p->db;
  2563   2571     if( pBt->inStmt && !pBt->readOnly ){
  2564   2572       rc = sqlite3PagerStmtCommit(pBt->pPager);
  2565   2573     }else{
  2566   2574       rc = SQLITE_OK;
  2567   2575     }
  2568   2576     pBt->inStmt = 0;
  2569   2577     sqlite3BtreeLeave(p);
................................................................................
  2578   2586   ** to use a cursor that was open at the beginning of this operation
  2579   2587   ** will result in an error.
  2580   2588   */
  2581   2589   int sqlite3BtreeRollbackStmt(Btree *p){
  2582   2590     int rc = SQLITE_OK;
  2583   2591     BtShared *pBt = p->pBt;
  2584   2592     sqlite3BtreeEnter(p);
         2593  +  pBt->db = p->db;
  2585   2594     if( pBt->inStmt && !pBt->readOnly ){
  2586   2595       rc = sqlite3PagerStmtRollback(pBt->pPager);
  2587   2596       assert( countWriteCursors(pBt)==0 );
  2588   2597       pBt->inStmt = 0;
  2589   2598     }
  2590   2599     sqlite3BtreeLeave(p);
  2591   2600     return rc;
................................................................................
  2721   2730     int wrFlag,                                 /* 1 to write. 0 read-only */
  2722   2731     int (*xCmp)(void*,int,const void*,int,const void*), /* Key Comparison func */
  2723   2732     void *pArg,                                 /* First arg to xCompare() */
  2724   2733     BtCursor **ppCur                            /* Write new cursor here */
  2725   2734   ){
  2726   2735     int rc;
  2727   2736     sqlite3BtreeEnter(p);
         2737  +  p->pBt->db = p->db;
  2728   2738     rc = btreeCursor(p, iTable, wrFlag, xCmp, pArg, ppCur);
  2729   2739     sqlite3BtreeLeave(p);
  2730   2740     return rc;
  2731   2741   }
  2732   2742   
  2733   2743   
  2734   2744   /*
................................................................................
  2736   2746   ** when the last cursor is closed.
  2737   2747   */
  2738   2748   int sqlite3BtreeCloseCursor(BtCursor *pCur){
  2739   2749     BtShared *pBt = pCur->pBt;
  2740   2750     Btree *pBtree = pCur->pBtree;
  2741   2751   
  2742   2752     sqlite3BtreeEnter(pBtree);
         2753  +  pBt->db = pBtree->db;
  2743   2754     clearCursorPosition(pCur);
  2744   2755     if( pCur->pPrev ){
  2745   2756       pCur->pPrev->pNext = pCur->pNext;
  2746   2757     }else{
  2747   2758       pBt->pCursor = pCur->pNext;
  2748   2759     }
  2749   2760     if( pCur->pNext ){
................................................................................
  3470   3481   ** on success.  Set *pRes to 0 if the cursor actually points to something
  3471   3482   ** or set *pRes to 1 if the table is empty.
  3472   3483   */
  3473   3484   int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){
  3474   3485     int rc;
  3475   3486   
  3476   3487     assert( cursorHoldsMutex(pCur) );
  3477         -  assert( sqlite3_mutex_held(pCur->pBtree->pSqlite->mutex) );
         3488  +  assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
  3478   3489     rc = moveToRoot(pCur);
  3479   3490     if( rc==SQLITE_OK ){
  3480   3491       if( pCur->eState==CURSOR_INVALID ){
  3481   3492         assert( pCur->pPage->nCell==0 );
  3482   3493         *pRes = 1;
  3483   3494         rc = SQLITE_OK;
  3484   3495       }else{
................................................................................
  3494   3505   ** on success.  Set *pRes to 0 if the cursor actually points to something
  3495   3506   ** or set *pRes to 1 if the table is empty.
  3496   3507   */
  3497   3508   int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
  3498   3509     int rc;
  3499   3510    
  3500   3511     assert( cursorHoldsMutex(pCur) );
  3501         -  assert( sqlite3_mutex_held(pCur->pBtree->pSqlite->mutex) );
         3512  +  assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
  3502   3513     rc = moveToRoot(pCur);
  3503   3514     if( rc==SQLITE_OK ){
  3504   3515       if( CURSOR_INVALID==pCur->eState ){
  3505   3516         assert( pCur->pPage->nCell==0 );
  3506   3517         *pRes = 1;
  3507   3518       }else{
  3508   3519         assert( pCur->eState==CURSOR_VALID );
................................................................................
  3547   3558     i64 nKey,              /* Size of pKey.  Or the key for tables */
  3548   3559     int biasRight,         /* If true, bias the search to the high end */
  3549   3560     int *pRes              /* Search result flag */
  3550   3561   ){
  3551   3562     int rc;
  3552   3563   
  3553   3564     assert( cursorHoldsMutex(pCur) );
  3554         -  assert( sqlite3_mutex_held(pCur->pBtree->pSqlite->mutex) );
         3565  +  assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
  3555   3566     rc = moveToRoot(pCur);
  3556   3567     if( rc ){
  3557   3568       return rc;
  3558   3569     }
  3559   3570     assert( pCur->pPage );
  3560   3571     assert( pCur->pPage->isInit );
  3561   3572     if( pCur->eState==CURSOR_INVALID ){
................................................................................
  3674   3685     return (CURSOR_VALID!=pCur->eState);
  3675   3686   }
  3676   3687   
  3677   3688   /*
  3678   3689   ** Return the database connection handle for a cursor.
  3679   3690   */
  3680   3691   sqlite3 *sqlite3BtreeCursorDb(const BtCursor *pCur){
  3681         -  assert( sqlite3_mutex_held(pCur->pBtree->pSqlite->mutex) );
  3682         -  return pCur->pBtree->pSqlite;
         3692  +  assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
         3693  +  return pCur->pBtree->db;
  3683   3694   }
  3684   3695   
  3685   3696   /*
  3686   3697   ** Advance the cursor to the next entry in the database.  If
  3687   3698   ** successful then set *pRes=0.  If the cursor
  3688   3699   ** was already pointing to the last entry in the database before
  3689   3700   ** this routine was called, then set *pRes=1.
................................................................................
  5496   5507   ** or delete might change the number of cells on a page or delete
  5497   5508   ** a page entirely and we do not want to leave any cursors 
  5498   5509   ** pointing to non-existant pages or cells.
  5499   5510   */
  5500   5511   static int checkReadLocks(Btree *pBtree, Pgno pgnoRoot, BtCursor *pExclude){
  5501   5512     BtCursor *p;
  5502   5513     BtShared *pBt = pBtree->pBt;
  5503         -  sqlite3 *db = pBtree->pSqlite;
         5514  +  sqlite3 *db = pBtree->db;
  5504   5515     assert( sqlite3BtreeHoldsMutex(pBtree) );
  5505   5516     for(p=pBt->pCursor; p; p=p->pNext){
  5506   5517       if( p==pExclude ) continue;
  5507   5518       if( p->eState!=CURSOR_VALID ) continue;
  5508   5519       if( p->pgnoRoot!=pgnoRoot ) continue;
  5509   5520       if( p->wrFlag==0 ){
  5510         -      sqlite3 *dbOther = p->pBtree->pSqlite;
         5521  +      sqlite3 *dbOther = p->pBtree->db;
  5511   5522         if( dbOther==0 ||
  5512   5523            (dbOther!=db && (dbOther->flags & SQLITE_ReadUncommitted)==0) ){
  5513   5524           return SQLITE_LOCKED;
  5514   5525         }
  5515   5526       }else if( p->pPage->pgno!=p->pgnoRoot ){
  5516   5527         moveToRoot(p);
  5517   5528       }
................................................................................
  5876   5887     sqlite3PagerUnref(pRoot->pDbPage);
  5877   5888     *piTable = (int)pgnoRoot;
  5878   5889     return SQLITE_OK;
  5879   5890   }
  5880   5891   int sqlite3BtreeCreateTable(Btree *p, int *piTable, int flags){
  5881   5892     int rc;
  5882   5893     sqlite3BtreeEnter(p);
         5894  +  p->pBt->db = p->db;
  5883   5895     rc = btreeCreateTable(p, piTable, flags);
  5884   5896     sqlite3BtreeLeave(p);
  5885   5897     return rc;
  5886   5898   }
  5887   5899   
  5888   5900   /*
  5889   5901   ** Erase the given database page and all its children.  Return
................................................................................
  5940   5952   ** read cursors on the table.  Open write cursors are moved to the
  5941   5953   ** root of the table.
  5942   5954   */
  5943   5955   int sqlite3BtreeClearTable(Btree *p, int iTable){
  5944   5956     int rc;
  5945   5957     BtShared *pBt = p->pBt;
  5946   5958     sqlite3BtreeEnter(p);
         5959  +  pBt->db = p->db;
  5947   5960     if( p->inTrans!=TRANS_WRITE ){
  5948   5961       rc = pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
  5949   5962     }else if( (rc = checkReadLocks(p, iTable, 0))!=SQLITE_OK ){
  5950   5963       /* nothing to do */
  5951   5964     }else if( SQLITE_OK!=(rc = saveAllCursors(pBt, iTable, 0)) ){
  5952   5965       /* nothing to do */
  5953   5966     }else{
................................................................................
  6083   6096       releasePage(pPage);
  6084   6097     }
  6085   6098     return rc;  
  6086   6099   }
  6087   6100   int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){
  6088   6101     int rc;
  6089   6102     sqlite3BtreeEnter(p);
         6103  +  p->pBt->db = p->db;
  6090   6104     rc = btreeDropTable(p, iTable, piMoved);
  6091   6105     sqlite3BtreeLeave(p);
  6092   6106     return rc;
  6093   6107   }
  6094   6108   
  6095   6109   
  6096   6110   /*
................................................................................
  6106   6120   int sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){
  6107   6121     DbPage *pDbPage;
  6108   6122     int rc;
  6109   6123     unsigned char *pP1;
  6110   6124     BtShared *pBt = p->pBt;
  6111   6125   
  6112   6126     sqlite3BtreeEnter(p);
         6127  +  pBt->db = p->db;
  6113   6128   
  6114   6129     /* Reading a meta-data value requires a read-lock on page 1 (and hence
  6115   6130     ** the sqlite_master table. We grab this lock regardless of whether or
  6116   6131     ** not the SQLITE_ReadUncommitted flag is set (the table rooted at page
  6117   6132     ** 1 is treated as a special case by queryTableLock() and lockTable()).
  6118   6133     */
  6119   6134     rc = queryTableLock(p, 1, READ_LOCK);
................................................................................
  6151   6166   */
  6152   6167   int sqlite3BtreeUpdateMeta(Btree *p, int idx, u32 iMeta){
  6153   6168     BtShared *pBt = p->pBt;
  6154   6169     unsigned char *pP1;
  6155   6170     int rc;
  6156   6171     assert( idx>=1 && idx<=15 );
  6157   6172     sqlite3BtreeEnter(p);
         6173  +  pBt->db = p->db;
  6158   6174     if( p->inTrans!=TRANS_WRITE ){
  6159   6175       rc = pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
  6160   6176     }else{
  6161   6177       assert( pBt->pPage1!=0 );
  6162   6178       pP1 = pBt->pPage1->aData;
  6163   6179       rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
  6164   6180       if( rc==SQLITE_OK ){
................................................................................
  6539   6555   ){
  6540   6556     int i;
  6541   6557     int nRef;
  6542   6558     IntegrityCk sCheck;
  6543   6559     BtShared *pBt = p->pBt;
  6544   6560   
  6545   6561     sqlite3BtreeEnter(p);
         6562  +  pBt->db = p->db;
  6546   6563     nRef = sqlite3PagerRefcount(pBt->pPager);
  6547   6564     if( lockBtreeWithRetry(p)!=SQLITE_OK ){
  6548   6565       sqlite3BtreeLeave(p);
  6549   6566       return sqlite3StrDup("Unable to acquire a read lock on the database");
  6550   6567     }
  6551   6568     sCheck.pBt = pBt;
  6552   6569     sCheck.pPager = pBt->pPager;
................................................................................
  6565   6582       return 0;
  6566   6583     }
  6567   6584     sCheck.anRef = sqlite3_malloc( (sCheck.nPage+1)*sizeof(sCheck.anRef[0]) );
  6568   6585     if( !sCheck.anRef ){
  6569   6586       unlockBtreeIfUnused(pBt);
  6570   6587       *pnErr = 1;
  6571   6588       sqlite3BtreeLeave(p);
  6572         -    return sqlite3MPrintf(p->pSqlite, "Unable to malloc %d bytes", 
         6589  +    return sqlite3MPrintf(p->db, "Unable to malloc %d bytes", 
  6573   6590           (sCheck.nPage+1)*sizeof(sCheck.anRef[0]));
  6574   6591     }
  6575   6592     for(i=0; i<=sCheck.nPage; i++){ sCheck.anRef[i] = 0; }
  6576   6593     i = PENDING_BYTE_PAGE(pBt);
  6577   6594     if( i<=sCheck.nPage ){
  6578   6595       sCheck.anRef[i] = 1;
  6579   6596     }
................................................................................
  6682   6699   */
  6683   6700   static int btreeCopyFile(Btree *pTo, Btree *pFrom){
  6684   6701     int rc = SQLITE_OK;
  6685   6702     Pgno i, nPage, nToPage, iSkip;
  6686   6703   
  6687   6704     BtShared *pBtTo = pTo->pBt;
  6688   6705     BtShared *pBtFrom = pFrom->pBt;
         6706  +  pBtTo->db = pTo->db;
         6707  +  pBtFrom->db = pFrom->db;
         6708  +  
  6689   6709   
  6690   6710     if( pTo->inTrans!=TRANS_WRITE || pFrom->inTrans!=TRANS_WRITE ){
  6691   6711       return SQLITE_ERROR;
  6692   6712     }
  6693   6713     if( pBtTo->pCursor ) return SQLITE_BUSY;
  6694   6714     nToPage = sqlite3PagerPagecount(pBtTo->pPager);
  6695   6715     nPage = sqlite3PagerPagecount(pBtFrom->pPager);
................................................................................
  6744   6764   
  6745   6765   #endif /* SQLITE_OMIT_VACUUM */
  6746   6766   
  6747   6767   /*
  6748   6768   ** Return non-zero if a transaction is active.
  6749   6769   */
  6750   6770   int sqlite3BtreeIsInTrans(Btree *p){
  6751         -  assert( p==0 || sqlite3_mutex_held(p->pSqlite->mutex) );
         6771  +  assert( p==0 || sqlite3_mutex_held(p->db->mutex) );
  6752   6772     return (p && (p->inTrans==TRANS_WRITE));
  6753   6773   }
  6754   6774   
  6755   6775   /*
  6756   6776   ** Return non-zero if a statement transaction is active.
  6757   6777   */
  6758   6778   int sqlite3BtreeIsInStmt(Btree *p){
................................................................................
  6760   6780     return (p->pBt && p->pBt->inStmt);
  6761   6781   }
  6762   6782   
  6763   6783   /*
  6764   6784   ** Return non-zero if a read (or write) transaction is active.
  6765   6785   */
  6766   6786   int sqlite3BtreeIsInReadTrans(Btree *p){
  6767         -  assert( sqlite3_mutex_held(p->pSqlite->mutex) );
         6787  +  assert( sqlite3_mutex_held(p->db->mutex) );
  6768   6788     return (p && (p->inTrans!=TRANS_NONE));
  6769   6789   }
  6770   6790   
  6771   6791   /*
  6772   6792   ** This function returns a pointer to a blob of memory associated with
  6773   6793   ** a single shared-btree. The memory is used by client code for it's own
  6774   6794   ** purposes (for example, to store a high-level schema associated with 
................................................................................
  6797   6817   
  6798   6818   /*
  6799   6819   ** Return true if another user of the same shared btree as the argument
  6800   6820   ** handle holds an exclusive lock on the sqlite_master table.
  6801   6821   */
  6802   6822   int sqlite3BtreeSchemaLocked(Btree *p){
  6803   6823     int rc;
  6804         -  assert( sqlite3_mutex_held(p->pSqlite->mutex) );
         6824  +  assert( sqlite3_mutex_held(p->db->mutex) );
  6805   6825     sqlite3BtreeEnter(p);
  6806   6826     rc = (queryTableLock(p, MASTER_ROOT, READ_LOCK)!=SQLITE_OK);
  6807   6827     sqlite3BtreeLeave(p);
  6808   6828     return rc;
  6809   6829   }
  6810   6830   
  6811   6831   
................................................................................
  6834   6854   ** INTKEY table currently pointing at a valid table entry. 
  6835   6855   ** This function modifies the data stored as part of that entry.
  6836   6856   ** Only the data content may only be modified, it is not possible
  6837   6857   ** to change the length of the data stored.
  6838   6858   */
  6839   6859   int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){
  6840   6860     assert( cursorHoldsMutex(pCsr) );
  6841         -  assert( sqlite3_mutex_held(pCsr->pBtree->pSqlite->mutex) );
         6861  +  assert( sqlite3_mutex_held(pCsr->pBtree->db->mutex) );
  6842   6862     assert(pCsr->isIncrblobHandle);
  6843   6863     if( pCsr->eState>=CURSOR_REQUIRESEEK ){
  6844   6864       if( pCsr->eState==CURSOR_FAULT ){
  6845   6865         return pCsr->skip;
  6846   6866       }else{
  6847   6867         return SQLITE_ABORT;
  6848   6868       }
................................................................................
  6876   6896   ** This function sets a flag only. The actual page location cache
  6877   6897   ** (stored in BtCursor.aOverflow[]) is allocated and used by function
  6878   6898   ** accessPayload() (the worker function for sqlite3BtreeData() and
  6879   6899   ** sqlite3BtreePutData()).
  6880   6900   */
  6881   6901   void sqlite3BtreeCacheOverflow(BtCursor *pCur){
  6882   6902     assert( cursorHoldsMutex(pCur) );
  6883         -  assert( sqlite3_mutex_held(pCur->pBtree->pSqlite->mutex) );
         6903  +  assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
  6884   6904     assert(!pCur->isIncrblobHandle);
  6885   6905     assert(!pCur->aOverflow);
  6886   6906     pCur->isIncrblobHandle = 1;
  6887   6907   }
  6888   6908   #endif

Changes to src/btree.h.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This header file defines the interface that the sqlite B-Tree file
    13     13   ** subsystem.  See comments in the source code for a detailed description
    14     14   ** of what each interface routine does.
    15     15   **
    16         -** @(#) $Id: btree.h,v 1.93 2007/09/03 15:19:35 drh Exp $
           16  +** @(#) $Id: btree.h,v 1.94 2007/12/07 18:55:28 drh Exp $
    17     17   */
    18     18   #ifndef _BTREE_H_
    19     19   #define _BTREE_H_
    20     20   
    21     21   /* TODO: This definition is just included so other modules compile. It
    22     22   ** needs to be revisited.
    23     23   */
................................................................................
    78     78   
    79     79   /* Additional values for the 4th argument of sqlite3BtreeOpen that
    80     80   ** are not associated with PAGER_ values.
    81     81   */
    82     82   #define BTREE_PRIVATE      64  /* Never share with other connections */
    83     83   
    84     84   int sqlite3BtreeClose(Btree*);
    85         -int sqlite3BtreeSetBusyHandler(Btree*,BusyHandler*);
    86     85   int sqlite3BtreeSetCacheSize(Btree*,int);
    87     86   int sqlite3BtreeSetSafetyLevel(Btree*,int,int);
    88     87   int sqlite3BtreeSyncDisabled(Btree*);
    89     88   int sqlite3BtreeSetPageSize(Btree*,int,int);
    90     89   int sqlite3BtreeGetPageSize(Btree*);
    91     90   int sqlite3BtreeMaxPageCount(Btree*,int);
    92     91   int sqlite3BtreeGetReserve(Btree*);

Changes to src/btreeInt.h.

     5      5   ** a legal notice, here is a blessing:
     6      6   **
     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12         -** $Id: btreeInt.h,v 1.13 2007/08/30 01:19:59 drh Exp $
           12  +** $Id: btreeInt.h,v 1.14 2007/12/07 18:55:28 drh Exp $
    13     13   **
    14     14   ** This file implements a external (disk-based) database using BTrees.
    15     15   ** For a detailed discussion of BTrees, refer to
    16     16   **
    17     17   **     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
    18     18   **     "Sorting And Searching", pages 473-480. Addison-Wesley
    19     19   **     Publishing Company, Reading, Massachusetts.
................................................................................
   321    321   ** All fields in this structure are accessed under sqlite3.mutex.
   322    322   ** The pBt pointer itself may not be changed while there exists cursors 
   323    323   ** in the referenced BtShared that point back to this Btree since those
   324    324   ** cursors have to do go through this Btree to find their BtShared and
   325    325   ** they often do so without holding sqlite3.mutex.
   326    326   */
   327    327   struct Btree {
   328         -  sqlite3 *pSqlite;  /* The database connection holding this btree */
          328  +  sqlite3 *db;       /* The database connection holding this btree */
   329    329     BtShared *pBt;     /* Sharable content of this btree */
   330    330     u8 inTrans;        /* TRANS_NONE, TRANS_READ or TRANS_WRITE */
   331         -  u8 sharable;       /* True if we can share pBt with other pSqlite */
   332         -  u8 locked;         /* True if pSqlite currently has pBt locked */
          331  +  u8 sharable;       /* True if we can share pBt with another db */
          332  +  u8 locked;         /* True if db currently has pBt locked */
   333    333     int wantToLock;    /* Number of nested calls to sqlite3BtreeEnter() */
   334         -  Btree *pNext;      /* List of other sharable Btrees from the same pSqlite */
          334  +  Btree *pNext;      /* List of other sharable Btrees from the same db */
   335    335     Btree *pPrev;      /* Back pointer of the same list */
   336    336   };
   337    337   
   338    338   /*
   339    339   ** Btree.inTrans may take one of the following values.
   340    340   **
   341    341   ** If the shared-data extension is enabled, there may be multiple users
................................................................................
   361    361   ** global SQLITE_MUTEX_STATIC_MASTER mutex.  The pPager field
   362    362   ** may not be modified once it is initially set as long as nRef>0.
   363    363   ** The pSchema field may be set once under BtShared.mutex and
   364    364   ** thereafter is unchanged as long as nRef>0.
   365    365   */
   366    366   struct BtShared {
   367    367     Pager *pPager;        /* The page cache */
          368  +  sqlite3 *db;          /* Database connection currently using this Btree */
   368    369     BtCursor *pCursor;    /* A list of all open cursors */
   369    370     MemPage *pPage1;      /* First page of the database */
   370    371     u8 inStmt;            /* True if we are in a statement subtransaction */
   371    372     u8 readOnly;          /* True if the underlying file is readonly */
   372    373     u8 maxEmbedFrac;      /* Maximum payload as % of total page size */
   373    374     u8 minEmbedFrac;      /* Minimum payload as % of total page size */
   374    375     u8 minLeafFrac;       /* Minimum leaf payload as % of total page size */
................................................................................
   380    381   #endif
   381    382     u16 pageSize;         /* Total number of bytes on a page */
   382    383     u16 usableSize;       /* Number of usable bytes on each page */
   383    384     int maxLocal;         /* Maximum local payload in non-LEAFDATA tables */
   384    385     int minLocal;         /* Minimum local payload in non-LEAFDATA tables */
   385    386     int maxLeaf;          /* Maximum local payload in a LEAFDATA table */
   386    387     int minLeaf;          /* Minimum local payload in a LEAFDATA table */
   387         -  BusyHandler *pBusyHandler;   /* Callback for when there is lock contention */
   388    388     u8 inTransaction;     /* Transaction state */
   389    389     int nTransaction;     /* Number of open transactions (read + write) */
   390    390     void *pSchema;        /* Pointer to space allocated by sqlite3BtreeSchema() */
   391    391     void (*xFreeSchema)(void*);  /* Destructor for BtShared.pSchema */
   392    392     sqlite3_mutex *mutex; /* Non-recursive mutex required to access this struct */
          393  +  BusyHandler busyHdr;  /* The busy handler for this btree */
   393    394   #ifndef SQLITE_OMIT_SHARED_CACHE
   394    395     int nRef;             /* Number of references to this structure */
   395    396     BtShared *pNext;      /* Next on a list of sharable BtShared structs */
   396    397     BtLock *pLock;        /* List of locks held on this shared-btree struct */
   397    398   #endif
   398    399   };
   399    400   
................................................................................
   419    420   ** b-tree within a database file.
   420    421   **
   421    422   ** The entry is identified by its MemPage and the index in
   422    423   ** MemPage.aCell[] of the entry.
   423    424   **
   424    425   ** When a single database file can shared by two more database connections,
   425    426   ** but cursors cannot be shared.  Each cursor is associated with a
   426         -** particular database connection identified BtCursor.pBtree.pSqlite.
          427  +** particular database connection identified BtCursor.pBtree.db.
   427    428   **
   428    429   ** Fields in this structure are accessed under the BtShared.mutex
   429    430   ** found at self->pBt->mutex. 
   430    431   */
   431    432   struct BtCursor {
   432    433     Btree *pBtree;            /* The Btree to which this cursor belongs */
   433    434     BtShared *pBt;            /* The BtShared this cursor points to */

Changes to src/main.c.

    10     10   **
    11     11   *************************************************************************
    12     12   ** Main file for the SQLite library.  The routines in this file
    13     13   ** implement the programmer interface to the library.  Routines in
    14     14   ** other files are for internal use by SQLite and should not be
    15     15   ** accessed by users of the library.
    16     16   **
    17         -** $Id: main.c,v 1.408 2007/12/05 01:38:23 drh Exp $
           17  +** $Id: main.c,v 1.409 2007/12/07 18:55:28 drh Exp $
    18     18   */
    19     19   #include "sqliteInt.h"
    20     20   #include <ctype.h>
    21     21   
    22     22   /*
    23     23   ** The version of the library
    24     24   */
................................................................................
   762    762     }
   763    763   
   764    764     if( (vfsFlags & SQLITE_OPEN_MAIN_DB)!=0 && (zFilename==0 || *zFilename==0) ){
   765    765       vfsFlags = (vfsFlags & ~SQLITE_OPEN_MAIN_DB) | SQLITE_OPEN_TEMP_DB;
   766    766     }
   767    767     rc = sqlite3BtreeOpen(zFilename, (sqlite3 *)db, ppBtree, btFlags, vfsFlags);
   768    768     if( rc==SQLITE_OK ){
   769         -    sqlite3BtreeSetBusyHandler(*ppBtree, (void*)&db->busyHandler);
   770    769       sqlite3BtreeSetCacheSize(*ppBtree, nCache);
   771    770     }
   772    771     return rc;
   773    772   }
   774    773   
   775    774   /*
   776    775   ** Return UTF-8 encoded English language explanation of the most recent

Changes to src/pager.c.

    14     14   ** The pager is used to access a database disk file.  It implements
    15     15   ** atomic commit and rollback through the use of a journal file that
    16     16   ** is separate from the database file.  The pager also implements file
    17     17   ** locking to prevent two processes from writing the same database
    18     18   ** file simultaneously, or one process from reading the database while
    19     19   ** another is writing.
    20     20   **
    21         -** @(#) $Id: pager.c,v 1.397 2007/11/29 18:44:27 drh Exp $
           21  +** @(#) $Id: pager.c,v 1.398 2007/12/07 18:55:28 drh Exp $
    22     22   */
    23     23   #ifndef SQLITE_OMIT_DISKIO
    24     24   #include "sqliteInt.h"
    25     25   #include <assert.h>
    26     26   #include <string.h>
    27     27   
    28     28   /*
................................................................................
  3147   3147   ** been released, the function returns. The return value is the total number 
  3148   3148   ** of bytes of memory released.
  3149   3149   */
  3150   3150   int sqlite3PagerReleaseMemory(int nReq){
  3151   3151     int nReleased = 0;          /* Bytes of memory released so far */
  3152   3152     sqlite3_mutex *mutex;       /* The MEM2 mutex */
  3153   3153     Pager *pPager;              /* For looping over pagers */
         3154  +  BusyHandler *savedBusy;     /* Saved copy of the busy handler */
  3154   3155     int rc = SQLITE_OK;
  3155   3156   
  3156   3157     /* Acquire the memory-management mutex
  3157   3158     */
  3158   3159     mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM2);
  3159   3160     sqlite3_mutex_enter(mutex);
  3160   3161   
................................................................................
  3191   3192       */
  3192   3193       if( !pPg ) break;
  3193   3194   
  3194   3195       pPager = pPg->pPager;
  3195   3196       assert(!pPg->needSync || pPg==pPager->lru.pFirst);
  3196   3197       assert(pPg->needSync || pPg==pPager->lru.pFirstSynced);
  3197   3198     
         3199  +    savedBusy = pPager->pBusyHandler;
         3200  +    pPager->pBusyHandler = 0;
  3198   3201       rc = pager_recycle(pPager, &pRecycled);
         3202  +    pPager->pBusyHandler = savedBusy;
  3199   3203       assert(pRecycled==pPg || rc!=SQLITE_OK);
  3200   3204       if( rc==SQLITE_OK ){
  3201   3205         /* We've found a page to free. At this point the page has been 
  3202   3206         ** removed from the page hash-table, free-list and synced-list 
  3203   3207         ** (pFirstSynced). It is still in the all pages (pAll) list. 
  3204   3208         ** Remove it from this list before freeing.
  3205   3209         **

Changes to src/sqliteInt.h.

     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** Internal interface definitions for SQLite.
    13     13   **
    14         -** @(#) $Id: sqliteInt.h,v 1.623 2007/12/05 01:38:24 drh Exp $
           14  +** @(#) $Id: sqliteInt.h,v 1.624 2007/12/07 18:55:29 drh Exp $
    15     15   */
    16     16   #ifndef _SQLITEINT_H_
    17     17   #define _SQLITEINT_H_
    18     18   
    19     19   /*
    20     20   ** The macro unlikely() is a hint that surrounds a boolean
    21     21   ** expression that is usually false.  Macro likely() surrounds
................................................................................
  1616   1616   ** builds) or a function call (for debugging).  If it is a function call,
  1617   1617   ** it allows the operator to set a breakpoint at the spot where database
  1618   1618   ** corruption is first detected.
  1619   1619   */
  1620   1620   #ifdef SQLITE_DEBUG
  1621   1621     int sqlite3Corrupt(void);
  1622   1622   # define SQLITE_CORRUPT_BKPT sqlite3Corrupt()
         1623  +# define DEBUGONLY(X)        X
  1623   1624   #else
  1624   1625   # define SQLITE_CORRUPT_BKPT SQLITE_CORRUPT
         1626  +# define DEBUGONLY(X)
  1625   1627   #endif
  1626   1628   
  1627   1629   /*
  1628   1630   ** Internal function prototypes
  1629   1631   */
  1630   1632   int sqlite3StrICmp(const char *, const char *);
  1631   1633   int sqlite3StrNICmp(const char *, const char *, int);

Changes to src/test3.c.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** Code for testing the btree.c module in SQLite.  This code
    13     13   ** is not included in the SQLite library.  It is used for automated
    14     14   ** testing of the SQLite library.
    15     15   **
    16         -** $Id: test3.c,v 1.87 2007/09/12 17:01:45 danielk1977 Exp $
           16  +** $Id: test3.c,v 1.88 2007/12/07 18:55:29 drh Exp $
    17     17   */
    18     18   #include "sqliteInt.h"
    19     19   #include "btreeInt.h"
    20     20   #include "tcl.h"
    21     21   #include <stdlib.h>
    22     22   #include <string.h>
    23     23   
................................................................................
   562    562     /* Normally in this file, with a b-tree handle opened using the 
   563    563     ** [btree_open] command it is safe to call sqlite3BtreeEnter() directly.
   564    564     ** But this function is sometimes called with a btree handle obtained
   565    565     ** from an open SQLite connection (using [btree_from_db]). In this case
   566    566     ** we need to obtain the mutex for the controlling SQLite handle before
   567    567     ** it is safe to call sqlite3BtreeEnter().
   568    568     */
   569         -  sqlite3_mutex_enter(pBt->pSqlite->mutex);
          569  +  sqlite3_mutex_enter(pBt->db->mutex);
   570    570   
   571    571     sqlite3BtreeEnter(pBt);
   572    572     a = sqlite3PagerStats(sqlite3BtreePager(pBt));
   573    573     for(i=0; i<11; i++){
   574    574       static char *zName[] = {
   575    575         "ref", "page", "max", "size", "state", "err",
   576    576         "hit", "miss", "ovfl", "read", "write"
................................................................................
   579    579       Tcl_AppendElement(interp, zName[i]);
   580    580       sqlite3_snprintf(sizeof(zBuf), zBuf,"%d",a[i]);
   581    581       Tcl_AppendElement(interp, zBuf);
   582    582     }
   583    583     sqlite3BtreeLeave(pBt);
   584    584   
   585    585     /* Release the mutex on the SQLite handle that controls this b-tree */
   586         -  sqlite3_mutex_leave(pBt->pSqlite->mutex);
          586  +  sqlite3_mutex_leave(pBt->db->mutex);
   587    587     return TCL_OK;
   588    588   }
   589    589   
   590    590   /*
   591    591   ** Usage:   btree_pager_ref_dump ID
   592    592   **
   593    593   ** Print out all outstanding pages.
................................................................................
  1587   1587       Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  1588   1588          " BT NCACHE\"", 0);
  1589   1589       return TCL_ERROR;
  1590   1590     }
  1591   1591     pBt = sqlite3TextToPtr(argv[1]);
  1592   1592     if( Tcl_GetInt(interp, argv[2], &nCache) ) return TCL_ERROR;
  1593   1593   
  1594         -  sqlite3_mutex_enter(pBt->pSqlite->mutex);
         1594  +  sqlite3_mutex_enter(pBt->db->mutex);
  1595   1595     sqlite3BtreeEnter(pBt);
  1596   1596     sqlite3BtreeSetCacheSize(pBt, nCache);
  1597   1597     sqlite3BtreeLeave(pBt);
  1598         -  sqlite3_mutex_leave(pBt->pSqlite->mutex);
         1598  +  sqlite3_mutex_leave(pBt->db->mutex);
  1599   1599   
  1600   1600     return TCL_OK;
  1601   1601   }
  1602   1602   
  1603   1603   
  1604   1604   /*
  1605   1605   ** Register commands with the TCL interpreter.