Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Avoid calling sqlite3BtreeEnter() in a corner case where the corresponding database handle mutex (sqlite3.mutex) may not be held. This prevents a potential deadlock or crash that can occur if the backup API, shared-cache mode and SQLITE_HAVE_CODEC are all in use. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
89b8c377a6f03d9fa885f3f94c1f0b1e |
User & Date: | dan 2012-09-28 20:23:42.567 |
Context
2012-09-29
| ||
14:45 | Fix compiler warnings found on Lion. (check-in: fd74d3d917 user: drh tags: trunk) | |
2012-09-28
| ||
20:23 | Avoid calling sqlite3BtreeEnter() in a corner case where the corresponding database handle mutex (sqlite3.mutex) may not be held. This prevents a potential deadlock or crash that can occur if the backup API, shared-cache mode and SQLITE_HAVE_CODEC are all in use. (check-in: 89b8c377a6 user: dan tags: trunk) | |
18:13 | Modify the clearCell function to use SQLITE_CORRUPT_BKPT in the one place it was not. (check-in: 472beb306a user: mistachkin tags: trunk) | |
Changes
Changes to src/backup.c.
︙ | ︙ | |||
215 216 217 218 219 220 221 | static int backupOnePage(sqlite3_backup *p, Pgno iSrcPg, const u8 *zSrcData){ Pager * const pDestPager = sqlite3BtreePager(p->pDest); const int nSrcPgsz = sqlite3BtreeGetPageSize(p->pSrc); int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest); const int nCopy = MIN(nSrcPgsz, nDestPgsz); const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz; #ifdef SQLITE_HAS_CODEC | > > > | < > | 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 | static int backupOnePage(sqlite3_backup *p, Pgno iSrcPg, const u8 *zSrcData){ Pager * const pDestPager = sqlite3BtreePager(p->pDest); const int nSrcPgsz = sqlite3BtreeGetPageSize(p->pSrc); int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest); const int nCopy = MIN(nSrcPgsz, nDestPgsz); const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz; #ifdef SQLITE_HAS_CODEC /* Use BtreeGetReserveNoMutex() for the source b-tree, as although it is ** guaranteed that the shared-mutex is held by this thread, handle ** p->pSrc may not actually be the owner. */ int nSrcReserve = sqlite3BtreeGetReserveNoMutex(p->pSrc); int nDestReserve = sqlite3BtreeGetReserve(p->pDest); #endif int rc = SQLITE_OK; i64 iOff; assert( sqlite3BtreeGetReserveNoMutex(p->pSrc)>=0 ); assert( p->bDestLocked ); assert( !isFatalError(p->rc) ); assert( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ); assert( zSrcData ); /* Catch the case where the destination is an in-memory database and the ** page sizes of the source and destination differ. |
︙ | ︙ |
Changes to src/btree.c.
︙ | ︙ | |||
2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 | /* ** Return the currently defined page size */ int sqlite3BtreeGetPageSize(Btree *p){ return p->pBt->pageSize; } #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM) /* ** Return the number of bytes of space at the end of every page that ** are intentually left unused. This is the "reserved" space that is ** sometimes used by extensions. */ | > > > > > > > > > > > > > > > > | 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 | /* ** Return the currently defined page size */ int sqlite3BtreeGetPageSize(Btree *p){ return p->pBt->pageSize; } /* ** This function is similar to sqlite3BtreeGetReserve(), except that it ** may only be called if it is guaranteed that the b-tree mutex is already ** held. ** ** This is useful in one special case in the backup API code where it is ** known that the shared b-tree mutex is held, but the mutex on the ** database handle that owns *p is not. In this case if sqlite3BtreeEnter() ** were to be called, it might collide with some other operation on the ** database handle that owns *p, causing undefined behaviour. */ int sqlite3BtreeGetReserveNoMutex(Btree *p){ assert( sqlite3_mutex_held(p->pBt->mutex) ); return p->pBt->pageSize - p->pBt->usableSize; } #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM) /* ** Return the number of bytes of space at the end of every page that ** are intentually left unused. This is the "reserved" space that is ** sometimes used by extensions. */ |
︙ | ︙ |
Changes to src/btree.h.
︙ | ︙ | |||
67 68 69 70 71 72 73 74 75 76 77 78 79 80 | int sqlite3BtreeSyncDisabled(Btree*); int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix); int sqlite3BtreeGetPageSize(Btree*); int sqlite3BtreeMaxPageCount(Btree*,int); u32 sqlite3BtreeLastPage(Btree*); int sqlite3BtreeSecureDelete(Btree*,int); int sqlite3BtreeGetReserve(Btree*); int sqlite3BtreeSetAutoVacuum(Btree *, int); int sqlite3BtreeGetAutoVacuum(Btree *); int sqlite3BtreeBeginTrans(Btree*,int); int sqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster); int sqlite3BtreeCommitPhaseTwo(Btree*, int); int sqlite3BtreeCommit(Btree*); int sqlite3BtreeRollback(Btree*,int); | > | 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | int sqlite3BtreeSyncDisabled(Btree*); int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix); int sqlite3BtreeGetPageSize(Btree*); int sqlite3BtreeMaxPageCount(Btree*,int); u32 sqlite3BtreeLastPage(Btree*); int sqlite3BtreeSecureDelete(Btree*,int); int sqlite3BtreeGetReserve(Btree*); int sqlite3BtreeGetReserveNoMutex(Btree *p); int sqlite3BtreeSetAutoVacuum(Btree *, int); int sqlite3BtreeGetAutoVacuum(Btree *); int sqlite3BtreeBeginTrans(Btree*,int); int sqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster); int sqlite3BtreeCommitPhaseTwo(Btree*, int); int sqlite3BtreeCommit(Btree*); int sqlite3BtreeRollback(Btree*,int); |
︙ | ︙ |