[sql] Retry Open() if error handler fixed things.
Since the caller cannot have existing database-derived state before
the database is opened, Open() can be safely retried after the error
handler has razed the database.
BUG=109482
Review URL: https://chromiumcodereview.appspot.com/18641004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@211936 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/sql/connection.cc b/sql/connection.cc
index 5f76a7f3..95d09c2 100644
--- a/sql/connection.cc
+++ b/sql/connection.cc
@@ -194,15 +194,15 @@
}
#if defined(OS_WIN)
- return OpenInternal(WideToUTF8(path.value()));
+ return OpenInternal(WideToUTF8(path.value()), RETRY_ON_POISON);
#elif defined(OS_POSIX)
- return OpenInternal(path.value());
+ return OpenInternal(path.value(), RETRY_ON_POISON);
#endif
}
bool Connection::OpenInMemory() {
in_memory_ = true;
- return OpenInternal(":memory:");
+ return OpenInternal(":memory:", NO_RETRY);
}
void Connection::CloseInternal(bool forced) {
@@ -238,8 +238,8 @@
AssertIOAllowed();
// TODO(shess): Histogram for failure.
sqlite3_close(db_);
- db_ = NULL;
}
+ db_ = NULL;
}
void Connection::Close() {
@@ -699,7 +699,8 @@
return sqlite3_errmsg(db_);
}
-bool Connection::OpenInternal(const std::string& file_name) {
+bool Connection::OpenInternal(const std::string& file_name,
+ Connection::Retry retry_flag) {
AssertIOAllowed();
if (db_) {
@@ -723,8 +724,11 @@
UMA_HISTOGRAM_ENUMERATION("Sqlite.OpenFailure", err & 0xff, 50);
OnSqliteError(err, NULL);
+ bool was_poisoned = poisoned_;
Close();
- db_ = NULL;
+
+ if (was_poisoned && retry_flag == RETRY_ON_POISON)
+ return OpenInternal(file_name, NO_RETRY);
return false;
}
@@ -806,7 +810,10 @@
}
if (!ExecuteWithTimeout("PRAGMA secure_delete=ON", kBusyTimeout)) {
+ bool was_poisoned = poisoned_;
Close();
+ if (was_poisoned && retry_flag == RETRY_ON_POISON)
+ return OpenInternal(file_name, NO_RETRY);
return false;
}