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

Side by Side Diff: chrome/browser/renderer_host/database_dispatcher_host.cc

Issue 174232: Chromium side patch for DB support on Linux. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Final version, including changes to the DEPS file. Created 11 years, 3 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
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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 "chrome/browser/renderer_host/database_dispatcher_host.h" 5 #include "chrome/browser/renderer_host/database_dispatcher_host.h"
6 6
7 #if defined(OS_WIN) 7 #if defined(OS_WIN)
8 #include <windows.h> 8 #include <windows.h>
9 #endif 9 #endif
10 10
11 #if defined(USE_SYSTEM_SQLITE) 11 #if defined(USE_SYSTEM_SQLITE)
12 #include <sqlite3.h> 12 #include <sqlite3.h>
13 #else 13 #else
14 #include "third_party/sqlite/preprocessed/sqlite3.h" 14 #include "third_party/sqlite/preprocessed/sqlite3.h"
15 #endif 15 #endif
16 16
17 #include "base/file_path.h" 17 #include "base/file_path.h"
18 #include "base/file_util.h" 18 #include "base/file_util.h"
19 #include "base/message_loop.h" 19 #include "base/message_loop.h"
20 #include "base/platform_file.h" 20 #include "base/platform_file.h"
21 #include "base/process.h" 21 #include "base/process.h"
22 #include "base/scoped_ptr.h" 22 #include "base/scoped_ptr.h"
23 #include "base/task.h" 23 #include "base/task.h"
24 #include "base/thread.h" 24 #include "base/thread.h"
25 #include "chrome/browser/browser_process.h" 25 #include "chrome/browser/browser_process.h"
26 #include "chrome/browser/renderer_host/resource_message_filter.h" 26 #include "chrome/browser/renderer_host/resource_message_filter.h"
27 #include "chrome/common/render_messages.h" 27 #include "chrome/common/render_messages.h"
28 #include "ipc/ipc_message.h" 28 #include "ipc/ipc_message.h"
29 29
30 #if defined(OS_POSIX)
31 #include "base/file_descriptor_posix.h"
32 #endif
33
30 const int kNumDeleteRetries = 5; 34 const int kNumDeleteRetries = 5;
31 const int kDelayDeleteRetryMs = 100; 35 const int kDelayDeleteRetryMs = 100;
32 36
33 namespace { 37 namespace {
34 38
35 struct OpenFileParams { 39 struct OpenFileParams {
36 FilePath db_dir; // directory where all DB files are stored 40 FilePath db_dir; // directory where all DB files are stored
37 FilePath file_name; // DB file 41 FilePath file_name; // DB file
38 int desired_flags; // flags to be used to open the file 42 int desired_flags; // flags to be used to open the file
39 base::ProcessHandle handle; // the handle of the renderer process 43 base::ProcessHandle handle; // the handle of the renderer process
40 }; 44 };
41 45
46 struct DeleteFileParams {
47 FilePath db_dir; // directory where all DB files are stored
48 FilePath file_name; // DB file
49 bool sync_dir; // sync DB directory after the file is deleted?
50 };
51
42 // Scheduled by the file Thread on the IO thread. 52 // Scheduled by the file Thread on the IO thread.
43 // Sends back to the renderer process the given message. 53 // Sends back to the renderer process the given message.
44 static void SendMessage(ResourceMessageFilter* sender, 54 static void SendMessage(ResourceMessageFilter* sender,
45 IPC::Message* message) { 55 IPC::Message* message) {
46 sender->Send(message); 56 sender->Send(message);
47 57
48 // Every time we get a DB-related message, we AddRef() the resource 58 // Every time we get a DB-related message, we AddRef() the resource
49 // message filterto make sure it doesn't get destroyed before we have 59 // message filterto make sure it doesn't get destroyed before we have
50 // a chance to send the reply back. So we need to Release() is here 60 // a chance to send the reply back. So we need to Release() is here
51 // and allow it to be destroyed if needed. 61 // and allow it to be destroyed if needed.
52 sender->Release(); 62 sender->Release();
53 } 63 }
54 64
65 // Make sure the flags used to open a DB file are consistent.
66 static bool OpenFileFlagsAreConsistent(const OpenFileParams& params) {
67 if (params.file_name == params.db_dir) {
68 return (params.desired_flags == SQLITE_OPEN_READONLY);
69 }
70
71 const int file_type = params.desired_flags & 0x00007F00;
72 const bool is_exclusive =
73 (params.desired_flags & SQLITE_OPEN_EXCLUSIVE) != 0;
74 const bool is_delete =
75 (params.desired_flags & SQLITE_OPEN_DELETEONCLOSE) != 0;
76 const bool is_create =
77 (params.desired_flags & SQLITE_OPEN_CREATE) != 0;
78 const bool is_read_only =
79 (params.desired_flags & SQLITE_OPEN_READONLY) != 0;
80 const bool is_read_write =
81 (params.desired_flags & SQLITE_OPEN_READWRITE) != 0;
82
83 // All files should be opened either read-write or read-only.
84 if (!(is_read_only ^ is_read_write)) {
85 return false;
86 }
87
88 // If a new file is created, it must also be writtable.
89 if (is_create && !is_read_write) {
90 return false;
91 }
92
93 // We must be able to create a new file, if exclusive access is desired.
94 if (is_exclusive && !is_create) {
95 return false;
96 }
97
98 // We cannot delete the files that we expect to already exist.
99 if (is_delete && !is_create) {
100 return false;
101 }
102
103 // The main DB, main journal and master journal cannot be auto-deleted.
104 if (((file_type == SQLITE_OPEN_MAIN_DB) ||
105 (file_type == SQLITE_OPEN_MAIN_JOURNAL) ||
106 (file_type == SQLITE_OPEN_MASTER_JOURNAL)) &&
107 is_delete) {
108 return false;
109 }
110
111 // Make sure we're opening the DB directory or that a file type is set.
112 if ((file_type != SQLITE_OPEN_MAIN_DB) &&
113 (file_type != SQLITE_OPEN_TEMP_DB) &&
114 (file_type != SQLITE_OPEN_MAIN_JOURNAL) &&
115 (file_type != SQLITE_OPEN_TEMP_JOURNAL) &&
116 (file_type != SQLITE_OPEN_SUBJOURNAL) &&
117 (file_type != SQLITE_OPEN_MASTER_JOURNAL) &&
118 (file_type != SQLITE_OPEN_TRANSIENT_DB)) {
119 return false;
120 }
121
122 return true;
123 }
124
55 // Scheduled by the IO thread on the file thread. 125 // Scheduled by the IO thread on the file thread.
56 // Opens the given database file, then schedules 126 // Opens the given database file, then schedules
57 // a task on the IO thread's message loop to send an IPC back to 127 // a task on the IO thread's message loop to send an IPC back to
58 // corresponding renderer process with the file handle. 128 // corresponding renderer process with the file handle.
59 static void DatabaseOpenFile(MessageLoop* io_thread_message_loop, 129 static void DatabaseOpenFile(MessageLoop* io_thread_message_loop,
60 const OpenFileParams& params, 130 const OpenFileParams& params,
61 int32 message_id, 131 int32 message_id,
62 ResourceMessageFilter* sender) { 132 ResourceMessageFilter* sender) {
63 base::PlatformFile target_handle = base::kInvalidPlatformFileValue; 133 base::PlatformFile target_handle = base::kInvalidPlatformFileValue;
64 // Create the database directory if it doesn't exist. 134 #if defined(OS_POSIX)
65 if (file_util::CreateDirectory(params.db_dir)) { 135 base::PlatformFile target_dir_handle = base::kInvalidPlatformFileValue;
136 #endif
137
138 // Verify the flags for consistency and create the database
139 // directory if it doesn't exist.
140 if (OpenFileFlagsAreConsistent(params) &&
141 file_util::CreateDirectory(params.db_dir)) {
66 int flags = 0; 142 int flags = 0;
67 flags |= base::PLATFORM_FILE_READ; 143 flags |= base::PLATFORM_FILE_READ;
68 if (params.desired_flags & SQLITE_OPEN_READWRITE) { 144 if (params.desired_flags & SQLITE_OPEN_READWRITE) {
69 flags |= base::PLATFORM_FILE_WRITE; 145 flags |= base::PLATFORM_FILE_WRITE;
70 } 146 }
71 147
72 if (!(params.desired_flags & SQLITE_OPEN_MAIN_DB)) { 148 if (!(params.desired_flags & SQLITE_OPEN_MAIN_DB)) {
73 flags |= base::PLATFORM_FILE_EXCLUSIVE_READ | 149 flags |= base::PLATFORM_FILE_EXCLUSIVE_READ |
74 base::PLATFORM_FILE_EXCLUSIVE_WRITE; 150 base::PLATFORM_FILE_EXCLUSIVE_WRITE;
75 } 151 }
76 152
77 if (params.desired_flags & SQLITE_OPEN_CREATE) { 153 if (params.desired_flags & SQLITE_OPEN_CREATE) {
78 flags |= base::PLATFORM_FILE_OPEN_ALWAYS; 154 flags |= base::PLATFORM_FILE_OPEN_ALWAYS;
79 } else { 155 } else {
80 flags |= base::PLATFORM_FILE_OPEN; 156 flags |= base::PLATFORM_FILE_OPEN;
81 } 157 }
82 158
159 if (params.desired_flags & SQLITE_OPEN_EXCLUSIVE) {
160 flags |= base::PLATFORM_FILE_EXCLUSIVE_READ |
161 base::PLATFORM_FILE_EXCLUSIVE_WRITE;
162 }
163
83 if (params.desired_flags & SQLITE_OPEN_DELETEONCLOSE) { 164 if (params.desired_flags & SQLITE_OPEN_DELETEONCLOSE) {
84 flags |= base::PLATFORM_FILE_TEMPORARY | base::PLATFORM_FILE_HIDDEN | 165 flags |= base::PLATFORM_FILE_TEMPORARY | base::PLATFORM_FILE_HIDDEN |
85 base::PLATFORM_FILE_DELETE_ON_CLOSE; 166 base::PLATFORM_FILE_DELETE_ON_CLOSE;
86 } 167 }
87 168
88 // Try to open/create the DB file. 169 // Try to open/create the DB file.
170 base::PlatformFile file_handle =
171 base::CreatePlatformFile(params.file_name.ToWStringHack(), flags, NULL);
172 if (file_handle != base::kInvalidPlatformFileValue) {
89 #if defined(OS_WIN) 173 #if defined(OS_WIN)
90 base::PlatformFile file_handle =
91 base::CreatePlatformFile(params.file_name.value(), flags, NULL);
92 if (file_handle != base::kInvalidPlatformFileValue) {
93 // Duplicate the file handle. 174 // Duplicate the file handle.
94 if (!DuplicateHandle(GetCurrentProcess(), file_handle, 175 if (!DuplicateHandle(GetCurrentProcess(), file_handle,
95 params.handle, &target_handle, 0, false, 176 params.handle, &target_handle, 0, false,
96 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { 177 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
97 // file_handle is closed whether or not DuplicateHandle succeeds. 178 // file_handle is closed whether or not DuplicateHandle succeeds.
98 target_handle = INVALID_HANDLE_VALUE; 179 target_handle = INVALID_HANDLE_VALUE;
99 } 180 }
181 #elif defined(OS_POSIX)
182 target_handle = file_handle;
183
184 int file_type = params.desired_flags & 0x00007F00;
185 bool creating_new_file = (params.desired_flags & SQLITE_OPEN_CREATE);
186 if (creating_new_file && ((file_type == SQLITE_OPEN_MASTER_JOURNAL) ||
187 (file_type == SQLITE_OPEN_MAIN_JOURNAL))) {
188 // We return a handle to the containing directory because on POSIX
189 // systems the VFS might want to fsync it after changing a file.
190 // By returning it here, we avoid an extra IPC call.
191 target_dir_handle = base::CreatePlatformFile(
192 params.db_dir.ToWStringHack(),
193 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ, NULL);
194 if (target_dir_handle == base::kInvalidPlatformFileValue) {
195 base::ClosePlatformFile(target_handle);
196 target_handle = base::kInvalidPlatformFileValue;
197 }
198 }
199 #endif
100 } 200 }
101 #endif
102 } 201 }
103 202
104 io_thread_message_loop->PostTask(FROM_HERE, 203 ViewMsg_DatabaseOpenFileResponse_Params response_params =
105 NewRunnableFunction(SendMessage, sender, 204 #if defined(OS_WIN)
106 new ViewMsg_DatabaseOpenFileResponse(message_id, target_handle))); 205 { target_handle };
206 #elif defined(OS_POSIX)
207 { base::FileDescriptor(target_handle, true),
208 base::FileDescriptor(target_dir_handle, true) };
209 #endif
210
211 io_thread_message_loop->PostTask(FROM_HERE,
212 NewRunnableFunction(SendMessage, sender,
213 new ViewMsg_DatabaseOpenFileResponse(message_id, response_params)));
107 } 214 }
108 215
109 // Scheduled by the IO thread on the file thread. 216 // Scheduled by the IO thread on the file thread.
110 // Deletes the given database file, then schedules 217 // Deletes the given database file, then schedules
111 // a task on the IO thread's message loop to send an IPC back to 218 // a task on the IO thread's message loop to send an IPC back to
112 // corresponding renderer process with the error code. 219 // corresponding renderer process with the error code.
113 static void DatabaseDeleteFile( 220 static void DatabaseDeleteFile(
114 MessageLoop* io_thread_message_loop, 221 MessageLoop* io_thread_message_loop,
115 const FilePath& file_name, 222 const DeleteFileParams& params,
116 int32 message_id, 223 int32 message_id,
117 int reschedule_count, 224 int reschedule_count,
118 ResourceMessageFilter* sender) { 225 ResourceMessageFilter* sender) {
119 if (reschedule_count > 0 && file_util::PathExists(file_name) && 226 // Return an error if the file could not be deleted
120 !file_util::Delete(file_name, false)) { 227 // after kNumDeleteRetries times.
121 MessageLoop::current()->PostDelayedTask(FROM_HERE, 228 if (!reschedule_count) {
122 NewRunnableFunction(DatabaseDeleteFile, io_thread_message_loop,
123 file_name, message_id, reschedule_count - 1, sender),
124 kDelayDeleteRetryMs);
125 } else {
126 io_thread_message_loop->PostTask(FROM_HERE, 229 io_thread_message_loop->PostTask(FROM_HERE,
127 NewRunnableFunction(SendMessage, sender, 230 NewRunnableFunction(SendMessage, sender,
128 new ViewMsg_DatabaseDeleteFileResponse( 231 new ViewMsg_DatabaseDeleteFileResponse(
129 message_id, reschedule_count > 0))); 232 message_id, SQLITE_IOERR_DELETE)));
233 return;
130 } 234 }
235
236 // If the file does not exist, we're done.
237 if (!file_util::PathExists(params.file_name)) {
238 io_thread_message_loop->PostTask(FROM_HERE,
239 NewRunnableFunction(SendMessage, sender,
240 new ViewMsg_DatabaseDeleteFileResponse(message_id, SQLITE_OK)));
241 return;
242 }
243
244
245 // If the file could not be deleted, try again.
246 if (!file_util::Delete(params.file_name, false)) {
247 MessageLoop::current()->PostDelayedTask(FROM_HERE,
248 NewRunnableFunction(DatabaseDeleteFile, io_thread_message_loop,
249 params, message_id, reschedule_count - 1, sender),
250 kDelayDeleteRetryMs);
251 return;
252 }
253
254 // File existed and it was successfully deleted
255 int error_code = SQLITE_OK;
256 #if defined(OS_POSIX)
257 // sync the DB directory if needed
258 if (params.sync_dir) {
259 base::PlatformFile dir_fd = base::CreatePlatformFile(
260 params.db_dir.ToWStringHack(), base::PLATFORM_FILE_READ, NULL);
261 if (dir_fd == base::kInvalidPlatformFileValue) {
262 error_code = SQLITE_CANTOPEN;
263 } else {
264 if (fsync(dir_fd)) {
265 error_code = SQLITE_IOERR_DIR_FSYNC;
266 }
267 base::ClosePlatformFile(dir_fd);
268 }
269 }
270 #endif
271
272 io_thread_message_loop->PostTask(FROM_HERE,
273 NewRunnableFunction(SendMessage, sender,
274 new ViewMsg_DatabaseDeleteFileResponse(message_id, error_code)));
131 } 275 }
132 276
133 // Scheduled by the IO thread on the file thread. 277 // Scheduled by the IO thread on the file thread.
134 // Gets the attributes of the given database file, then schedules 278 // Gets the attributes of the given database file, then schedules
135 // a task on the IO thread's message loop to send an IPC back to 279 // a task on the IO thread's message loop to send an IPC back to
136 // corresponding renderer process. 280 // corresponding renderer process.
137 static void DatabaseGetFileAttributes( 281 static void DatabaseGetFileAttributes(
138 MessageLoop* io_thread_message_loop, 282 MessageLoop* io_thread_message_loop,
139 const FilePath& file_name, 283 const FilePath& file_name,
140 int32 message_id, 284 int32 message_id,
141 ResourceMessageFilter* sender) { 285 ResourceMessageFilter* sender) {
142 #if defined(OS_WIN) 286 #if defined(OS_WIN)
143 uint32 attributes = GetFileAttributes(file_name.value().c_str()); 287 uint32 attributes = GetFileAttributes(file_name.value().c_str());
144 #else 288 #elif defined(OS_POSIX)
145 uint32 attributes = -1L; 289 uint32 attributes = 0;
290 if (!access(file_name.value().c_str(), R_OK)) {
291 attributes |= static_cast<uint32>(R_OK);
292 }
293 if (!access(file_name.value().c_str(), W_OK)) {
294 attributes |= static_cast<uint32>(W_OK);
295 }
296 if (!attributes) {
297 attributes = -1;
298 }
146 #endif 299 #endif
147 300
148 io_thread_message_loop->PostTask(FROM_HERE, 301 io_thread_message_loop->PostTask(FROM_HERE,
149 NewRunnableFunction(SendMessage, sender, 302 NewRunnableFunction(SendMessage, sender,
150 new ViewMsg_DatabaseGetFileAttributesResponse(message_id, attributes))); 303 new ViewMsg_DatabaseGetFileAttributesResponse(message_id, attributes)));
151 } 304 }
152 305
153 // Scheduled by the IO thread on the file thread. 306 // Scheduled by the IO thread on the file thread.
154 // Gets the size of the given file, then schedules a task 307 // Gets the size of the given file, then schedules a task
155 // on the IO thread's message loop to send an IPC back to 308 // on the IO thread's message loop to send an IPC back to
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 (file.find('/') != std::wstring::npos) || 378 (file.find('/') != std::wstring::npos) ||
226 (file.find(':') != std::wstring::npos)) { 379 (file.find(':') != std::wstring::npos)) {
227 return FilePath(); 380 return FilePath();
228 } 381 }
229 return GetDBDir().Append(file_name); 382 return GetDBDir().Append(file_name);
230 } 383 }
231 384
232 void DatabaseDispatcherHost::OnDatabaseOpenFile( 385 void DatabaseDispatcherHost::OnDatabaseOpenFile(
233 const FilePath& file_name, int desired_flags, 386 const FilePath& file_name, int desired_flags,
234 int32 message_id) { 387 int32 message_id) {
235 FilePath db_dir = GetDBDir();
236 FilePath db_file_name = GetDBFileFullPath(file_name); 388 FilePath db_file_name = GetDBFileFullPath(file_name);
237 389
238 if (db_file_name.empty()) { 390 if (db_file_name.empty()) {
391 ViewMsg_DatabaseOpenFileResponse_Params response_params =
392 #if defined(OS_WIN)
393 { base::kInvalidPlatformFileValue };
394 #elif defined(OS_POSIX)
395 { base::FileDescriptor(base::kInvalidPlatformFileValue, true),
396 base::FileDescriptor(base::kInvalidPlatformFileValue, true) };
397 #endif
239 resource_message_filter_->Send(new ViewMsg_DatabaseOpenFileResponse( 398 resource_message_filter_->Send(new ViewMsg_DatabaseOpenFileResponse(
240 message_id, base::kInvalidPlatformFileValue)); 399 message_id, response_params));
241 return; 400 return;
242 } 401 }
243 402
244 OpenFileParams params = { db_dir, db_file_name, desired_flags, 403 OpenFileParams params = { GetDBDir(), db_file_name, desired_flags,
245 resource_message_filter_->handle() }; 404 resource_message_filter_->handle() };
246 resource_message_filter_->AddRef(); 405 resource_message_filter_->AddRef();
247 file_thread_message_loop_->PostTask(FROM_HERE, 406 file_thread_message_loop_->PostTask(FROM_HERE,
248 NewRunnableFunction(DatabaseOpenFile, MessageLoop::current(), 407 NewRunnableFunction(DatabaseOpenFile, MessageLoop::current(),
249 params, message_id, resource_message_filter_)); 408 params, message_id, resource_message_filter_));
250 } 409 }
251 410
252 void DatabaseDispatcherHost::OnDatabaseDeleteFile( 411 void DatabaseDispatcherHost::OnDatabaseDeleteFile(
253 const FilePath& file_name, int32 message_id) { 412 const FilePath& file_name, const bool& sync_dir, int32 message_id) {
254 FilePath db_file_name = GetDBFileFullPath(file_name); 413 FilePath db_file_name = GetDBFileFullPath(file_name);
255 if (db_file_name.empty()) { 414 if (db_file_name.empty()) {
256 resource_message_filter_->Send(new ViewMsg_DatabaseDeleteFileResponse( 415 resource_message_filter_->Send(new ViewMsg_DatabaseDeleteFileResponse(
257 message_id, false)); 416 message_id, SQLITE_IOERR_DELETE));
258 return; 417 return;
259 } 418 }
260 419
420 DeleteFileParams params = { GetDBDir(), db_file_name, sync_dir };
261 resource_message_filter_->AddRef(); 421 resource_message_filter_->AddRef();
262 file_thread_message_loop_->PostTask(FROM_HERE, 422 file_thread_message_loop_->PostTask(FROM_HERE,
263 NewRunnableFunction(DatabaseDeleteFile, MessageLoop::current(), 423 NewRunnableFunction(DatabaseDeleteFile, MessageLoop::current(),
264 db_file_name, message_id, kNumDeleteRetries, resource_message_filter_)); 424 params, message_id, kNumDeleteRetries, resource_message_filter_));
265 } 425 }
266 426
267 void DatabaseDispatcherHost::OnDatabaseGetFileAttributes( 427 void DatabaseDispatcherHost::OnDatabaseGetFileAttributes(
268 const FilePath& file_name, int32 message_id) { 428 const FilePath& file_name, int32 message_id) {
269 FilePath db_file_name = GetDBFileFullPath(file_name); 429 FilePath db_file_name = GetDBFileFullPath(file_name);
270 if (db_file_name.empty()) { 430 if (db_file_name.empty()) {
271 resource_message_filter_->Send( 431 resource_message_filter_->Send(
272 new ViewMsg_DatabaseGetFileAttributesResponse( 432 new ViewMsg_DatabaseGetFileAttributesResponse(
273 message_id, -1)); 433 message_id, -1));
274 return; 434 return;
(...skipping 12 matching lines...) Expand all
287 resource_message_filter_->Send(new ViewMsg_DatabaseGetFileSizeResponse( 447 resource_message_filter_->Send(new ViewMsg_DatabaseGetFileSizeResponse(
288 message_id, 0)); 448 message_id, 0));
289 return; 449 return;
290 } 450 }
291 451
292 resource_message_filter_->AddRef(); 452 resource_message_filter_->AddRef();
293 file_thread_message_loop_->PostTask(FROM_HERE, 453 file_thread_message_loop_->PostTask(FROM_HERE,
294 NewRunnableFunction(DatabaseGetFileSize, MessageLoop::current(), 454 NewRunnableFunction(DatabaseGetFileSize, MessageLoop::current(),
295 db_file_name, message_id, resource_message_filter_)); 455 db_file_name, message_id, resource_message_filter_));
296 } 456 }
OLDNEW
« no previous file with comments | « chrome/browser/renderer_host/database_dispatcher_host.h ('k') | chrome/common/db_message_filter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698