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

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: rebase before comment queue. 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') | no next file with comments »
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 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 if (!((attachment_point[i] >= '0' && attachment_point[i] <= '9') || 104 if (!((attachment_point[i] >= '0' && attachment_point[i] <= '9') ||
103 (attachment_point[i] >= 'a' && attachment_point[i] <= 'z') || 105 (attachment_point[i] >= 'a' && attachment_point[i] <= 'z') ||
104 (attachment_point[i] >= 'A' && attachment_point[i] <= 'Z') || 106 (attachment_point[i] >= 'A' && attachment_point[i] <= 'Z') ||
105 attachment_point[i] == '_')) { 107 attachment_point[i] == '_')) {
106 return false; 108 return false;
107 } 109 }
108 } 110 }
109 return true; 111 return true;
110 } 112 }
111 113
114 // SQLite automatically calls sqlite3_initialize() lazily, but
115 // sqlite3_initialize() uses double-checked locking and thus can have
116 // data races.
117 //
118 // TODO(shess): Another alternative would be to have
119 // sqlite3_initialize() called as part of process bring-up. If this
120 // is changed, remove the dynamic_annotations dependency in sql.gyp.
121 base::LazyInstance<base::Lock>::Leaky
122 g_sqlite_init_lock = LAZY_INSTANCE_INITIALIZER;
123 void InitializeSqlite() {
124 base::AutoLock lock(g_sqlite_init_lock.Get());
125 sqlite3_initialize();
126 }
127
112 } // namespace 128 } // namespace
113 129
114 namespace sql { 130 namespace sql {
115 131
116 // static 132 // static
117 Connection::ErrorIgnorerCallback* Connection::current_ignorer_cb_ = NULL; 133 Connection::ErrorIgnorerCallback* Connection::current_ignorer_cb_ = NULL;
118 134
119 // static 135 // static
120 bool Connection::ShouldIgnore(int error) { 136 bool Connection::ShouldIgnore(int error) {
121 if (!current_ignorer_cb_) 137 if (!current_ignorer_cb_)
(...skipping 670 matching lines...) Expand 10 before | Expand all | Expand 10 after
792 808
793 bool Connection::OpenInternal(const std::string& file_name, 809 bool Connection::OpenInternal(const std::string& file_name,
794 Connection::Retry retry_flag) { 810 Connection::Retry retry_flag) {
795 AssertIOAllowed(); 811 AssertIOAllowed();
796 812
797 if (db_) { 813 if (db_) {
798 DLOG(FATAL) << "sql::Connection is already open."; 814 DLOG(FATAL) << "sql::Connection is already open.";
799 return false; 815 return false;
800 } 816 }
801 817
818 // Make sure sqlite3_initialize() is called before anything else.
819 InitializeSqlite();
820
802 // If |poisoned_| is set, it means an error handler called 821 // If |poisoned_| is set, it means an error handler called
803 // RazeAndClose(). Until regular Close() is called, the caller 822 // RazeAndClose(). Until regular Close() is called, the caller
804 // should be treating the database as open, but is_open() currently 823 // should be treating the database as open, but is_open() currently
805 // only considers the sqlite3 handle's state. 824 // only considers the sqlite3 handle's state.
806 // TODO(shess): Revise is_open() to consider poisoned_, and review 825 // TODO(shess): Revise is_open() to consider poisoned_, and review
807 // to see if any non-testing code even depends on it. 826 // to see if any non-testing code even depends on it.
808 DLOG_IF(FATAL, poisoned_) << "sql::Connection is already open."; 827 DLOG_IF(FATAL, poisoned_) << "sql::Connection is already open.";
809 poisoned_ = false; 828 poisoned_ = false;
810 829
811 int err = sqlite3_open(file_name.c_str(), &db_); 830 int err = sqlite3_open(file_name.c_str(), &db_);
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
1024 } 1043 }
1025 1044
1026 // Best effort to put things back as they were before. 1045 // Best effort to put things back as they were before.
1027 const char kNoWritableSchema[] = "PRAGMA writable_schema = OFF"; 1046 const char kNoWritableSchema[] = "PRAGMA writable_schema = OFF";
1028 ignore_result(Execute(kNoWritableSchema)); 1047 ignore_result(Execute(kNoWritableSchema));
1029 1048
1030 return ret; 1049 return ret;
1031 } 1050 }
1032 1051
1033 } // namespace sql 1052 } // namespace sql
OLDNEW
« no previous file with comments | « no previous file | sql/sql.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698