summaryrefslogtreecommitdiffstats
path: root/third_party
diff options
context:
space:
mode:
authorshess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-14 06:37:46 +0000
committershess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-14 06:37:46 +0000
commite48e05150a1180ea87a52fbb32e8f042ecf89610 (patch)
treeac03e954a1114cda97cd91548c6c466798bec5cb /third_party
parent6a016d854a8acc092c0789958c60649fe56d7946 (diff)
downloadchromium_src-e48e05150a1180ea87a52fbb32e8f042ecf89610.zip
chromium_src-e48e05150a1180ea87a52fbb32e8f042ecf89610.tar.gz
chromium_src-e48e05150a1180ea87a52fbb32e8f042ecf89610.tar.bz2
[SQLite] Hack to touch page cache to debug slow connection close.
The shutdown-monitor has noted cases where sqlite3_close() is taking a very long time to finish. In reviewing the code, writes are committed before the close is called, so there should be almost no I/O involved (excepting perhaps unlocking the file?). One hypothesis is that the SQLite page cache, which is LRU, may have very old pages which have been paged out. This change touches them all, so if they are paged out the crash should move to this code. BUG=95527 TEST=Monitor crash in bug, see if it changes. Review URL: http://codereview.chromium.org/7891025 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@101034 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'third_party')
-rw-r--r--third_party/sqlite/amalgamation/sqlite3.c91
-rw-r--r--third_party/sqlite/amalgamation/sqlite3.h15
2 files changed, 106 insertions, 0 deletions
diff --git a/third_party/sqlite/amalgamation/sqlite3.c b/third_party/sqlite/amalgamation/sqlite3.c
index 9c66c16..f82ed1c 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;
+}
diff --git a/third_party/sqlite/amalgamation/sqlite3.h b/third_party/sqlite/amalgamation/sqlite3.h
index 0d42790..4ee2ee4 100644
--- a/third_party/sqlite/amalgamation/sqlite3.h
+++ b/third_party/sqlite/amalgamation/sqlite3.h
@@ -6477,3 +6477,18 @@ struct sqlite3_rtree_geometry {
#endif /* ifndef _SQLITE3RTREE_H_ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Fault in page cache for db. See http://crbug.com/95527 .
+** *pnTouched will accumulate the number of bytes represented by the
+** touched pages. */
+int sqlite3_95527(sqlite3 *db, unsigned int *pnTouched);
+
+/* Let our code know that it's safe to call the function. */
+#define HAS_SQLITE3_95527
+
+#ifdef __cplusplus
+} /* end of the 'extern "C"' block */
+#endif