| Index: third_party/sqlite/amalgamation/sqlite3.c
|
| diff --git a/third_party/sqlite/amalgamation/sqlite3.c b/third_party/sqlite/amalgamation/sqlite3.c
|
| index 9c66c16c9e47cab0198735fcac01648a2c6be556..f82ed1cb45dc0527bb0595a1b448ae7c1aec780e 100644
|
| --- a/third_party/sqlite/amalgamation/sqlite3.c
|
| +++ b/third_party/sqlite/amalgamation/sqlite3.c
|
| @@ -126259,3 +126259,94 @@ SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule(
|
| #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
|
|
|
| /************** End of fts3_icu.c ********************************************/
|
| +
|
| +/* Touch the bigs of pCache which will be processed by
|
| +** pcache1TruncateUnsafe(), pcache1FreePage(), and pcache1Free()
|
| +** during sqlite3_close(). *pnTouched will have the number of bytes
|
| +** represented by the pages touched added to it. */
|
| +SQLITE_PRIVATE void pcache1VisitUnsafe(PCache1 *pCache,
|
| + unsigned int *pnTouched){
|
| + unsigned int iHash;
|
| +
|
| + assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
|
| +
|
| + for(iHash=0; iHash<pCache->nHash; iHash++){
|
| + PgHdr1 *pp = pCache->apHash[iHash];
|
| + PgHdr1 *lp = pp;
|
| + unsigned int s = 0;
|
| + while (pp) {
|
| + /* Crash if a loop is detected. */
|
| + /* NOTE(shess): Touches the PgHdr1 structure as a side effect.
|
| + ** If this check is removed, revise the code to match ordering
|
| + ** in pcache1TruncateUnsafe(). Yes, I realize this is
|
| + ** probably reordered to heck and back.
|
| + */
|
| + if (lp == pp->pNext) {
|
| + int *zero = NULL;
|
| + *zero = 42;
|
| + }
|
| +
|
| + /* Touch the data area, in case it's on a prior VM page. */
|
| + *pnTouched += sqlite3MallocSize(PGHDR1_TO_PAGE(pp));
|
| +
|
| + pp = pp->pNext;
|
| +
|
| + /* Bump the loop-detection pointer forward every time s is an
|
| + ** even power of 2. */
|
| + s++;
|
| + if (!(s & (s-1))) {
|
| + lp = pp;
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| +/* TODO(shess): Debugging code for http://crbug.com/95527 .
|
| +** Touch the entire page cache for the given db. The idea is that if
|
| +** paging activity is causing the slowdown, the shutdown monitor will
|
| +** see things happening here, rather than in sqlite3_close().
|
| +*/
|
| +int sqlite3_95527(sqlite3 *db, unsigned int *pnTouched){
|
| + unsigned int iDb;
|
| +
|
| + /* This code assumes that pcache1 is the pager cache implementation. */
|
| + if (sqlite3GlobalConfig.pcache.xTruncate != pcache1Truncate) {
|
| + return SQLITE_OK;
|
| + }
|
| +
|
| + /* This setup is like sqlite3_close(). */
|
| + if( !db ){
|
| + return SQLITE_OK;
|
| + }
|
| + if( !sqlite3SafetyCheckSickOrOk(db) ){
|
| + return SQLITE_MISUSE_BKPT;
|
| + }
|
| + sqlite3_mutex_enter(db->mutex);
|
| +
|
| + /* A sqlite3* connection may refer to multiple underlying database
|
| + files. Usually these will be 'main' and 'temp', with 'temp' having
|
| + no btree or pager. */
|
| + for(iDb=0; iDb<db->nDb; iDb++){
|
| + Btree *b;
|
| + Pager *p;
|
| + PCache1 *pCache;
|
| + struct Db *pDb = &db->aDb[iDb];
|
| + if (!pDb) continue;
|
| +
|
| + b = pDb->pBt;
|
| + if (!b) continue;
|
| +
|
| + p = sqlite3BtreePager(b);
|
| + if (!p) continue;
|
| +
|
| + pCache = (PCache1*)p->pPCache->pCache;
|
| + if (!pCache) continue;
|
| +
|
| + pcache1EnterMutex(pCache->pGroup);
|
| + pcache1VisitUnsafe(pCache, pnTouched);
|
| + pcache1LeaveMutex(pCache->pGroup);
|
| + }
|
| +
|
| + sqlite3_mutex_leave(db->mutex);
|
| + return SQLITE_OK;
|
| +}
|
|
|