Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(610)

Side by Side Diff: sql/connection.cc

Issue 19000007: [sql] Serialize calls to sqlite3_initialize(). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | sql/sql.gyp » ('j') | sql/sql.gyp » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "sql/connection.h" 5 #include "sql/connection.h"
6 6
7 #include <string.h> 7 #include <string.h>
8 8
9 #include "base/files/file_path.h" 9 #include "base/files/file_path.h"
10 #include "base/file_util.h" 10 #include "base/file_util.h"
11 #include "base/lazy_instance.h"
11 #include "base/logging.h" 12 #include "base/logging.h"
12 #include "base/metrics/histogram.h" 13 #include "base/metrics/histogram.h"
13 #include "base/metrics/sparse_histogram.h" 14 #include "base/metrics/sparse_histogram.h"
14 #include "base/strings/string_split.h" 15 #include "base/strings/string_split.h"
15 #include "base/strings/string_util.h" 16 #include "base/strings/string_util.h"
16 #include "base/strings/stringprintf.h" 17 #include "base/strings/stringprintf.h"
17 #include "base/strings/utf_string_conversions.h" 18 #include "base/strings/utf_string_conversions.h"
19 #include "base/synchronization/lock.h"
18 #include "sql/statement.h" 20 #include "sql/statement.h"
19 #include "third_party/sqlite/sqlite3.h" 21 #include "third_party/sqlite/sqlite3.h"
20 22
21 #if defined(OS_IOS) && defined(USE_SYSTEM_SQLITE) 23 #if defined(OS_IOS) && defined(USE_SYSTEM_SQLITE)
22 #include "third_party/sqlite/src/ext/icu/sqliteicu.h" 24 #include "third_party/sqlite/src/ext/icu/sqliteicu.h"
23 #endif 25 #endif
24 26
25 namespace { 27 namespace {
26 28
27 // Spin for up to a second waiting for the lock to clear when setting 29 // Spin for up to a second waiting for the lock to clear when setting
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 89
88 // If successful, exactly one page should have been backed up. If 90 // If successful, exactly one page should have been backed up. If
89 // this breaks, check this function to make sure assumptions aren't 91 // this breaks, check this function to make sure assumptions aren't
90 // being broken. 92 // being broken.
91 if (rc == SQLITE_DONE) 93 if (rc == SQLITE_DONE)
92 DCHECK_EQ(pages, 1); 94 DCHECK_EQ(pages, 1);
93 95
94 return rc; 96 return rc;
95 } 97 }
96 98
99 // SQLite automatically calls sqlite3_initialize() lazily, but
100 // sqlite3_initialize() uses double-checked locking and thus can have
101 // data races.
102 //
103 // TODO(shess): Another alternative would be to have
104 // sqlite3_initialize() called as part of process bring-up. If this
105 // is changed, remove the dynamic_annotations dependency in sql.gyp.
106 base::LazyInstance<base::Lock>::Leaky
107 g_sqlite_init_lock = LAZY_INSTANCE_INITIALIZER;
108 void InitializeSqlite() {
109 base::AutoLock lock(g_sqlite_init_lock.Get());
110 sqlite3_initialize();
111 }
112
97 } // namespace 113 } // namespace
98 114
99 namespace sql { 115 namespace sql {
100 116
101 // static 117 // static
102 Connection::ErrorIgnorerCallback* Connection::current_ignorer_cb_ = NULL; 118 Connection::ErrorIgnorerCallback* Connection::current_ignorer_cb_ = NULL;
103 119
104 // static 120 // static
105 bool Connection::ShouldIgnore(int error) { 121 bool Connection::ShouldIgnore(int error) {
106 if (!current_ignorer_cb_) 122 if (!current_ignorer_cb_)
(...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after
700 } 716 }
701 717
702 bool Connection::OpenInternal(const std::string& file_name) { 718 bool Connection::OpenInternal(const std::string& file_name) {
703 AssertIOAllowed(); 719 AssertIOAllowed();
704 720
705 if (db_) { 721 if (db_) {
706 DLOG(FATAL) << "sql::Connection is already open."; 722 DLOG(FATAL) << "sql::Connection is already open.";
707 return false; 723 return false;
708 } 724 }
709 725
726 // Make sure sqlite3_initialize() is called before anything else.
727 InitializeSqlite();
728
710 // If |poisoned_| is set, it means an error handler called 729 // If |poisoned_| is set, it means an error handler called
711 // RazeAndClose(). Until regular Close() is called, the caller 730 // RazeAndClose(). Until regular Close() is called, the caller
712 // should be treating the database as open, but is_open() currently 731 // should be treating the database as open, but is_open() currently
713 // only considers the sqlite3 handle's state. 732 // only considers the sqlite3 handle's state.
714 // TODO(shess): Revise is_open() to consider poisoned_, and review 733 // TODO(shess): Revise is_open() to consider poisoned_, and review
715 // to see if any non-testing code even depends on it. 734 // to see if any non-testing code even depends on it.
716 DLOG_IF(FATAL, poisoned_) << "sql::Connection is already open."; 735 DLOG_IF(FATAL, poisoned_) << "sql::Connection is already open.";
717 poisoned_ = false; 736 poisoned_ = false;
718 737
719 int err = sqlite3_open(file_name.c_str(), &db_); 738 int err = sqlite3_open(file_name.c_str(), &db_);
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
899 } 918 }
900 919
901 // Best effort to put things back as they were before. 920 // Best effort to put things back as they were before.
902 const char kNoWritableSchema[] = "PRAGMA writable_schema = OFF"; 921 const char kNoWritableSchema[] = "PRAGMA writable_schema = OFF";
903 ignore_result(Execute(kNoWritableSchema)); 922 ignore_result(Execute(kNoWritableSchema));
904 923
905 return ret; 924 return ret;
906 } 925 }
907 926
908 } // namespace sql 927 } // namespace sql
OLDNEW
« no previous file with comments | « no previous file | sql/sql.gyp » ('j') | sql/sql.gyp » ('J')

Powered by Google App Engine
This is Rietveld 408576698