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

Side by Side Diff: webkit/support/simple_database_system.cc

Issue 16950028: Move file_util::Delete to the base namespace (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 | « webkit/plugins/npapi/plugin_stream_posix.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "webkit/support/simple_database_system.h"
6
7 #include "base/auto_reset.h"
8 #include "base/bind.h"
9 #include "base/bind_helpers.h"
10 #include "base/file_util.h"
11 #include "base/message_loop.h"
12 #include "base/message_loop/message_loop_proxy.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "base/synchronization/waitable_event.h"
15 #include "base/threading/platform_thread.h"
16 #include "third_party/WebKit/public/platform/WebCString.h"
17 #include "third_party/WebKit/public/platform/WebString.h"
18 #include "third_party/WebKit/public/web/WebDatabase.h"
19 #include "third_party/sqlite/sqlite3.h"
20 #include "webkit/browser/database/database_util.h"
21 #include "webkit/browser/database/vfs_backend.h"
22
23 using webkit_database::DatabaseTracker;
24 using webkit_database::DatabaseUtil;
25 using webkit_database::OriginInfo;
26 using webkit_database::VfsBackend;
27
28 SimpleDatabaseSystem* SimpleDatabaseSystem::instance_ = NULL;
29
30 SimpleDatabaseSystem* SimpleDatabaseSystem::GetInstance() {
31 DCHECK(instance_);
32 return instance_;
33 }
34
35 SimpleDatabaseSystem::SimpleDatabaseSystem()
36 : db_thread_("SimpleDBThread"),
37 quota_per_origin_(5 * 1024 * 1024),
38 open_connections_(new webkit_database::DatabaseConnectionsWrapper) {
39 DCHECK(!instance_);
40 instance_ = this;
41 CHECK(temp_dir_.CreateUniqueTempDir());
42 db_tracker_ =
43 new DatabaseTracker(temp_dir_.path(), false, NULL, NULL, NULL);
44 db_tracker_->AddObserver(this);
45 db_thread_.Start();
46 db_thread_proxy_ = db_thread_.message_loop_proxy();
47 }
48
49 SimpleDatabaseSystem::~SimpleDatabaseSystem() {
50 base::WaitableEvent done_event(false, false);
51 db_thread_proxy_->PostTask(
52 FROM_HERE,
53 base::Bind(&SimpleDatabaseSystem::ThreadCleanup,
54 base::Unretained(this), &done_event));
55 done_event.Wait();
56 instance_ = NULL;
57 }
58
59 void SimpleDatabaseSystem::databaseOpened(const WebKit::WebDatabase& database) {
60 std::string origin_identifier =
61 database.securityOrigin().databaseIdentifier().utf8();
62 base::string16 database_name = database.name();
63 open_connections_->AddOpenConnection(origin_identifier, database_name);
64 db_thread_proxy_->PostTask(
65 FROM_HERE,
66 base::Bind(&SimpleDatabaseSystem::DatabaseOpened,
67 base::Unretained(this),
68 origin_identifier,
69 database_name, database.displayName(),
70 database.estimatedSize()));
71 }
72
73 void SimpleDatabaseSystem::databaseModified(
74 const WebKit::WebDatabase& database) {
75 db_thread_proxy_->PostTask(
76 FROM_HERE,
77 base::Bind(&SimpleDatabaseSystem::DatabaseModified,
78 base::Unretained(this),
79 database.securityOrigin().databaseIdentifier().utf8(),
80 database.name()));
81 }
82
83 void SimpleDatabaseSystem::databaseClosed(const WebKit::WebDatabase& database) {
84 std::string origin_identifier =
85 database.securityOrigin().databaseIdentifier().utf8();
86 base::string16 database_name = database.name();
87 db_thread_proxy_->PostTask(
88 FROM_HERE,
89 base::Bind(&SimpleDatabaseSystem::DatabaseClosed,
90 base::Unretained(this), origin_identifier, database_name));
91 }
92
93 base::PlatformFile SimpleDatabaseSystem::OpenFile(
94 const base::string16& vfs_file_name, int desired_flags) {
95 base::PlatformFile result = base::kInvalidPlatformFileValue;
96 base::WaitableEvent done_event(false, false);
97 db_thread_proxy_->PostTask(
98 FROM_HERE,
99 base::Bind(&SimpleDatabaseSystem::VfsOpenFile,
100 base::Unretained(this),
101 vfs_file_name, desired_flags,
102 &result, &done_event));
103 done_event.Wait();
104 return result;
105 }
106
107 int SimpleDatabaseSystem::DeleteFile(
108 const base::string16& vfs_file_name, bool sync_dir) {
109 int result = SQLITE_OK;
110 base::WaitableEvent done_event(false, false);
111 db_thread_proxy_->PostTask(
112 FROM_HERE,
113 base::Bind(&SimpleDatabaseSystem::VfsDeleteFile,
114 base::Unretained(this),
115 vfs_file_name, sync_dir,
116 &result, &done_event));
117 done_event.Wait();
118 return result;
119 }
120
121 uint32 SimpleDatabaseSystem::GetFileAttributes(
122 const base::string16& vfs_file_name) {
123 uint32 result = 0;
124 base::WaitableEvent done_event(false, false);
125 db_thread_proxy_->PostTask(
126 FROM_HERE,
127 base::Bind(&SimpleDatabaseSystem::VfsGetFileAttributes,
128 base::Unretained(this), vfs_file_name, &result, &done_event));
129 done_event.Wait();
130 return result;
131 }
132
133 int64 SimpleDatabaseSystem::GetFileSize(const base::string16& vfs_file_name) {
134 int64 result = 0;
135 base::WaitableEvent done_event(false, false);
136 db_thread_proxy_->PostTask(
137 FROM_HERE,
138 base::Bind(&SimpleDatabaseSystem::VfsGetFileSize,
139 base::Unretained(this), vfs_file_name, &result, &done_event));
140 done_event.Wait();
141 return result;
142 }
143
144 int64 SimpleDatabaseSystem::GetSpaceAvailable(
145 const std::string& origin_identifier) {
146 int64 result = 0;
147 base::WaitableEvent done_event(false, false);
148 db_thread_proxy_->PostTask(
149 FROM_HERE,
150 base::Bind(&SimpleDatabaseSystem::VfsGetSpaceAvailable,
151 base::Unretained(this), origin_identifier,
152 &result, &done_event));
153 done_event.Wait();
154 return result;
155 }
156
157 void SimpleDatabaseSystem::ClearAllDatabases() {
158 open_connections_->WaitForAllDatabasesToClose();
159 db_thread_proxy_->PostTask(
160 FROM_HERE,
161 base::Bind(&SimpleDatabaseSystem::ResetTracker, base::Unretained(this)));
162 }
163
164 void SimpleDatabaseSystem::SetDatabaseQuota(int64 quota) {
165 if (!db_thread_proxy_->BelongsToCurrentThread()) {
166 db_thread_proxy_->PostTask(
167 FROM_HERE,
168 base::Bind(&SimpleDatabaseSystem::SetDatabaseQuota,
169 base::Unretained(this), quota));
170 return;
171 }
172 quota_per_origin_ = quota;
173 }
174
175 void SimpleDatabaseSystem::DatabaseOpened(
176 const std::string& origin_identifier,
177 const base::string16& database_name,
178 const base::string16& description,
179 int64 estimated_size) {
180 DCHECK(db_thread_proxy_->BelongsToCurrentThread());
181 int64 database_size = 0;
182 db_tracker_->DatabaseOpened(
183 origin_identifier, database_name, description,
184 estimated_size, &database_size);
185 OnDatabaseSizeChanged(origin_identifier, database_name,
186 database_size);
187 }
188
189 void SimpleDatabaseSystem::DatabaseModified(
190 const std::string& origin_identifier,
191 const base::string16& database_name) {
192 DCHECK(db_thread_proxy_->BelongsToCurrentThread());
193 db_tracker_->DatabaseModified(origin_identifier, database_name);
194 }
195
196 void SimpleDatabaseSystem::DatabaseClosed(
197 const std::string& origin_identifier,
198 const base::string16& database_name) {
199 DCHECK(db_thread_proxy_->BelongsToCurrentThread());
200 db_tracker_->DatabaseClosed(origin_identifier, database_name);
201 open_connections_->RemoveOpenConnection(origin_identifier, database_name);
202 }
203
204 void SimpleDatabaseSystem::OnDatabaseSizeChanged(
205 const std::string& origin_identifier,
206 const base::string16& database_name,
207 int64 database_size) {
208 DCHECK(db_thread_proxy_->BelongsToCurrentThread());
209 // We intentionally call into webkit on our background db_thread_
210 // to better emulate what happens in chrome where this method is
211 // invoked on the background ipc thread.
212 WebKit::WebDatabase::updateDatabaseSize(
213 WebKit::WebString::fromUTF8(origin_identifier),
214 database_name, database_size);
215 }
216
217 void SimpleDatabaseSystem::OnDatabaseScheduledForDeletion(
218 const std::string& origin_identifier,
219 const base::string16& database_name) {
220 DCHECK(db_thread_proxy_->BelongsToCurrentThread());
221 // We intentionally call into webkit on our background db_thread_
222 // to better emulate what happens in chrome where this method is
223 // invoked on the background ipc thread.
224 WebKit::WebDatabase::closeDatabaseImmediately(
225 WebKit::WebString::fromUTF8(origin_identifier), database_name);
226 }
227
228 void SimpleDatabaseSystem::VfsOpenFile(
229 const base::string16& vfs_file_name, int desired_flags,
230 base::PlatformFile* file_handle, base::WaitableEvent* done_event ) {
231 DCHECK(db_thread_proxy_->BelongsToCurrentThread());
232 base::FilePath file_name = GetFullFilePathForVfsFile(vfs_file_name);
233 if (file_name.empty()) {
234 VfsBackend::OpenTempFileInDirectory(
235 db_tracker_->DatabaseDirectory(), desired_flags, file_handle);
236 } else {
237 VfsBackend::OpenFile(file_name, desired_flags, file_handle);
238 }
239 done_event->Signal();
240 }
241
242 void SimpleDatabaseSystem::VfsDeleteFile(
243 const base::string16& vfs_file_name, bool sync_dir,
244 int* result, base::WaitableEvent* done_event) {
245 DCHECK(db_thread_proxy_->BelongsToCurrentThread());
246 // We try to delete the file multiple times, because that's what the default
247 // VFS does (apparently deleting a file can sometimes fail on Windows).
248 // We sleep for 10ms between retries for the same reason.
249 const int kNumDeleteRetries = 3;
250 int num_retries = 0;
251 *result = SQLITE_OK;
252 base::FilePath file_name = GetFullFilePathForVfsFile(vfs_file_name);
253 do {
254 *result = VfsBackend::DeleteFile(file_name, sync_dir);
255 } while ((++num_retries < kNumDeleteRetries) &&
256 (*result == SQLITE_IOERR_DELETE) &&
257 (base::PlatformThread::Sleep(
258 base::TimeDelta::FromMilliseconds(10)),
259 1));
260
261 done_event->Signal();
262 }
263
264 void SimpleDatabaseSystem::VfsGetFileAttributes(
265 const base::string16& vfs_file_name,
266 uint32* result, base::WaitableEvent* done_event) {
267 DCHECK(db_thread_proxy_->BelongsToCurrentThread());
268 *result = VfsBackend::GetFileAttributes(
269 GetFullFilePathForVfsFile(vfs_file_name));
270 done_event->Signal();
271 }
272
273 void SimpleDatabaseSystem::VfsGetFileSize(
274 const base::string16& vfs_file_name,
275 int64* result, base::WaitableEvent* done_event) {
276 DCHECK(db_thread_proxy_->BelongsToCurrentThread());
277 *result = VfsBackend::GetFileSize(GetFullFilePathForVfsFile(vfs_file_name));
278 done_event->Signal();
279 }
280
281 void SimpleDatabaseSystem::VfsGetSpaceAvailable(
282 const std::string& origin_identifier,
283 int64* result, base::WaitableEvent* done_event) {
284 DCHECK(db_thread_proxy_->BelongsToCurrentThread());
285 // This method isn't actually part of the "vfs" interface, but it is
286 // used from within webcore and handled here in the same fashion.
287 OriginInfo info;
288 if (db_tracker_->GetOriginInfo(origin_identifier, &info)) {
289 int64 space_available = quota_per_origin_ - info.TotalSize();
290 *result = space_available < 0 ? 0 : space_available;
291 } else {
292 NOTREACHED();
293 *result = 0;
294 }
295 done_event->Signal();
296 }
297
298 base::FilePath SimpleDatabaseSystem::GetFullFilePathForVfsFile(
299 const base::string16& vfs_file_name) {
300 DCHECK(db_thread_proxy_->BelongsToCurrentThread());
301 if (vfs_file_name.empty()) // temp file, used for vacuuming
302 return base::FilePath();
303 return DatabaseUtil::GetFullFilePathForVfsFile(
304 db_tracker_.get(), vfs_file_name);
305 }
306
307 void SimpleDatabaseSystem::ResetTracker() {
308 DCHECK(db_thread_proxy_->BelongsToCurrentThread());
309 db_tracker_->CloseTrackerDatabaseAndClearCaches();
310 base::Delete(db_tracker_->DatabaseDirectory(), true);
311 }
312
313 void SimpleDatabaseSystem::ThreadCleanup(base::WaitableEvent* done_event) {
314 ResetTracker();
315 db_tracker_->RemoveObserver(this);
316 db_tracker_ = NULL;
317 done_event->Signal();
318 }
319
OLDNEW
« no previous file with comments | « webkit/plugins/npapi/plugin_stream_posix.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698