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

Side by Side Diff: content/browser/indexed_db/indexed_db_dispatcher_host.cc

Issue 2500263003: Port messages sent by WebIDBCursorImpl to Mojo. (Closed)
Patch Set: Address yzshen@'s comments and fix leak. Created 4 years, 1 month 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
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 "content/browser/indexed_db/indexed_db_dispatcher_host.h" 5 #include "content/browser/indexed_db/indexed_db_dispatcher_host.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/files/file_path.h" 11 #include "base/files/file_path.h"
12 #include "base/guid.h" 12 #include "base/guid.h"
13 #include "base/memory/ptr_util.h" 13 #include "base/memory/ptr_util.h"
14 #include "base/process/process.h" 14 #include "base/process/process.h"
15 #include "base/stl_util.h" 15 #include "base/stl_util.h"
16 #include "base/strings/utf_string_conversions.h" 16 #include "base/strings/utf_string_conversions.h"
17 #include "content/browser/bad_message.h" 17 #include "content/browser/bad_message.h"
18 #include "content/browser/indexed_db/indexed_db_callbacks.h" 18 #include "content/browser/indexed_db/indexed_db_callbacks.h"
19 #include "content/browser/indexed_db/indexed_db_connection.h" 19 #include "content/browser/indexed_db/indexed_db_connection.h"
20 #include "content/browser/indexed_db/indexed_db_context_impl.h" 20 #include "content/browser/indexed_db/indexed_db_context_impl.h"
21 #include "content/browser/indexed_db/indexed_db_cursor.h"
22 #include "content/browser/indexed_db/indexed_db_database_callbacks.h" 21 #include "content/browser/indexed_db/indexed_db_database_callbacks.h"
23 #include "content/browser/indexed_db/indexed_db_observation.h" 22 #include "content/browser/indexed_db/indexed_db_observation.h"
24 #include "content/browser/indexed_db/indexed_db_observer_changes.h" 23 #include "content/browser/indexed_db/indexed_db_observer_changes.h"
25 #include "content/browser/indexed_db/indexed_db_pending_connection.h" 24 #include "content/browser/indexed_db/indexed_db_pending_connection.h"
26 #include "content/browser/indexed_db/indexed_db_value.h" 25 #include "content/browser/indexed_db/indexed_db_value.h"
27 #include "content/browser/renderer_host/render_message_filter.h" 26 #include "content/browser/renderer_host/render_message_filter.h"
28 #include "content/common/indexed_db/indexed_db_messages.h" 27 #include "content/common/indexed_db/indexed_db_messages.h"
29 #include "content/common/indexed_db/indexed_db_metadata.h" 28 #include "content/common/indexed_db/indexed_db_metadata.h"
30 #include "content/public/browser/browser_thread.h" 29 #include "content/public/browser/browser_thread.h"
31 #include "content/public/browser/user_metrics.h" 30 #include "content/public/browser/user_metrics.h"
(...skipping 24 matching lines...) Expand all
56 IndexedDBDispatcherHost::IndexedDBDispatcherHost( 55 IndexedDBDispatcherHost::IndexedDBDispatcherHost(
57 int ipc_process_id, 56 int ipc_process_id,
58 net::URLRequestContextGetter* request_context_getter, 57 net::URLRequestContextGetter* request_context_getter,
59 IndexedDBContextImpl* indexed_db_context, 58 IndexedDBContextImpl* indexed_db_context,
60 ChromeBlobStorageContext* blob_storage_context) 59 ChromeBlobStorageContext* blob_storage_context)
61 : BrowserMessageFilter(IndexedDBMsgStart), 60 : BrowserMessageFilter(IndexedDBMsgStart),
62 BrowserAssociatedInterface(this, this), 61 BrowserAssociatedInterface(this, this),
63 request_context_getter_(request_context_getter), 62 request_context_getter_(request_context_getter),
64 indexed_db_context_(indexed_db_context), 63 indexed_db_context_(indexed_db_context),
65 blob_storage_context_(blob_storage_context), 64 blob_storage_context_(blob_storage_context),
66 cursor_dispatcher_host_(base::MakeUnique<CursorDispatcherHost>(this)),
67 ipc_process_id_(ipc_process_id) { 65 ipc_process_id_(ipc_process_id) {
68 DCHECK(indexed_db_context_.get()); 66 DCHECK(indexed_db_context_.get());
69 } 67 }
70 68
71 IndexedDBDispatcherHost::~IndexedDBDispatcherHost() { 69 IndexedDBDispatcherHost::~IndexedDBDispatcherHost() {
72 // TODO(alecflett): uncomment these when we find the source of these leaks. 70 // TODO(alecflett): uncomment these when we find the source of these leaks.
73 // DCHECK(transaction_size_map_.empty()); 71 // DCHECK(transaction_size_map_.empty());
74 // DCHECK(transaction_origin_map_.empty()); 72 // DCHECK(transaction_origin_map_.empty());
75 } 73 }
76 74
(...skipping 17 matching lines...) Expand all
94 92
95 void IndexedDBDispatcherHost::ResetDispatcherHosts() { 93 void IndexedDBDispatcherHost::ResetDispatcherHosts() {
96 // It is important that the various *_dispatcher_host_ members are reset 94 // It is important that the various *_dispatcher_host_ members are reset
97 // on the IndexedDB thread, since there might be incoming messages on that 95 // on the IndexedDB thread, since there might be incoming messages on that
98 // thread, and we must not reset the dispatcher hosts until after those 96 // thread, and we must not reset the dispatcher hosts until after those
99 // messages are processed. 97 // messages are processed.
100 DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread()); 98 DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
101 99
102 // Prevent any pending connections from being processed. 100 // Prevent any pending connections from being processed.
103 is_open_ = false; 101 is_open_ = false;
104
105 cursor_dispatcher_host_.reset();
106 }
107
108 base::TaskRunner* IndexedDBDispatcherHost::OverrideTaskRunnerForMessage(
109 const IPC::Message& message) {
110 if (IPC_MESSAGE_CLASS(message) != IndexedDBMsgStart)
111 return NULL;
112
113 switch (message.type()) {
114 case IndexedDBHostMsg_AckReceivedBlobs::ID:
115 return NULL;
116 default:
117 return indexed_db_context_->TaskRunner();
118 }
119 } 102 }
120 103
121 bool IndexedDBDispatcherHost::OnMessageReceived(const IPC::Message& message) { 104 bool IndexedDBDispatcherHost::OnMessageReceived(const IPC::Message& message) {
122 if (IPC_MESSAGE_CLASS(message) != IndexedDBMsgStart) 105 return false;
dcheng 2016/11/17 03:46:23 Does this still need to be a BrowserMessageFilter?
Reilly Grant (use Gerrit) 2016/11/17 20:04:52 It still needs to send one IPC message. My next pa
123 return false;
124
125 DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread() ||
126 message.type() == IndexedDBHostMsg_AckReceivedBlobs::ID);
127
128 bool handled = cursor_dispatcher_host_->OnMessageReceived(message);
129
130 if (!handled) {
131 handled = true;
132 IPC_BEGIN_MESSAGE_MAP(IndexedDBDispatcherHost, message)
133 IPC_MESSAGE_HANDLER(IndexedDBHostMsg_AckReceivedBlobs, OnAckReceivedBlobs)
134 IPC_MESSAGE_UNHANDLED(handled = false)
135 IPC_END_MESSAGE_MAP()
136 }
137 return handled;
138 }
139
140 int32_t IndexedDBDispatcherHost::Add(IndexedDBCursor* cursor) {
141 if (!cursor_dispatcher_host_) {
142 return 0;
143 }
144 return cursor_dispatcher_host_->map_.Add(cursor);
145 } 106 }
146 107
147 bool IndexedDBDispatcherHost::RegisterTransactionId(int64_t host_transaction_id, 108 bool IndexedDBDispatcherHost::RegisterTransactionId(int64_t host_transaction_id,
148 const url::Origin& origin) { 109 const url::Origin& origin) {
149 if (base::ContainsKey(transaction_size_map_, host_transaction_id)) 110 if (base::ContainsKey(transaction_size_map_, host_transaction_id))
150 return false; 111 return false;
151 transaction_size_map_[host_transaction_id] = 0; 112 transaction_size_map_[host_transaction_id] = 0;
152 transaction_origin_map_[host_transaction_id] = origin; 113 transaction_origin_map_[host_transaction_id] = origin;
153 return true; 114 return true;
154 } 115 }
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 blob_data_handle_map_.erase(iter); 200 blob_data_handle_map_.erase(iter);
240 else 201 else
241 --iter->second.second; 202 --iter->second.second;
242 } 203 }
243 204
244 bool IndexedDBDispatcherHost::IsOpen() const { 205 bool IndexedDBDispatcherHost::IsOpen() const {
245 DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread()); 206 DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
246 return is_open_; 207 return is_open_;
247 } 208 }
248 209
249 IndexedDBCursor* IndexedDBDispatcherHost::GetCursorFromId(
250 int32_t ipc_cursor_id) {
251 DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
252 return cursor_dispatcher_host_->map_.Lookup(ipc_cursor_id);
253 }
254
255 IndexedDBMsg_ObserverChanges IndexedDBDispatcherHost::ConvertObserverChanges( 210 IndexedDBMsg_ObserverChanges IndexedDBDispatcherHost::ConvertObserverChanges(
256 std::unique_ptr<IndexedDBObserverChanges> changes) { 211 std::unique_ptr<IndexedDBObserverChanges> changes) {
257 IndexedDBMsg_ObserverChanges idb_changes; 212 IndexedDBMsg_ObserverChanges idb_changes;
258 idb_changes.observation_index = changes->release_observation_indices_map(); 213 idb_changes.observation_index = changes->release_observation_indices_map();
259 for (const auto& observation : changes->release_observations()) 214 for (const auto& observation : changes->release_observations())
260 idb_changes.observations.push_back(ConvertObservation(observation.get())); 215 idb_changes.observations.push_back(ConvertObservation(observation.get()));
261 return idb_changes; 216 return idb_changes;
262 } 217 }
263 218
264 IndexedDBMsg_Observation IndexedDBDispatcherHost::ConvertObservation( 219 IndexedDBMsg_Observation IndexedDBDispatcherHost::ConvertObservation(
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
378 const url::Origin& origin, 333 const url::Origin& origin,
379 const base::string16& name) { 334 const base::string16& name) {
380 DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread()); 335 DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
381 336
382 base::FilePath indexed_db_path = indexed_db_context_->data_path(); 337 base::FilePath indexed_db_path = indexed_db_context_->data_path();
383 DCHECK(request_context_getter_); 338 DCHECK(request_context_getter_);
384 context()->GetIDBFactory()->DeleteDatabase( 339 context()->GetIDBFactory()->DeleteDatabase(
385 name, request_context_getter_, callbacks, origin, indexed_db_path); 340 name, request_context_getter_, callbacks, origin, indexed_db_path);
386 } 341 }
387 342
388 void IndexedDBDispatcherHost::OnAckReceivedBlobs(
389 const std::vector<std::string>& uuids) {
390 DCHECK_CURRENTLY_ON(BrowserThread::IO);
391 for (const auto& uuid : uuids)
392 DropBlobData(uuid);
393 }
394
395 void IndexedDBDispatcherHost::FinishTransaction(int64_t host_transaction_id, 343 void IndexedDBDispatcherHost::FinishTransaction(int64_t host_transaction_id,
396 bool committed) { 344 bool committed) {
397 DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread()); 345 DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
398 if (committed) { 346 if (committed) {
399 context()->TransactionComplete( 347 context()->TransactionComplete(
400 transaction_origin_map_[host_transaction_id]); 348 transaction_origin_map_[host_transaction_id]);
401 } 349 }
402 transaction_origin_map_.erase(host_transaction_id); 350 transaction_origin_map_.erase(host_transaction_id);
403 transaction_size_map_.erase(host_transaction_id); 351 transaction_size_map_.erase(host_transaction_id);
404 } 352 }
405 353
406 //////////////////////////////////////////////////////////////////////
407 // Helper templates.
408 //
409
410 template <typename ObjectType>
411 ObjectType* IndexedDBDispatcherHost::GetOrTerminateProcess(
412 RefIDMap<ObjectType>* map,
413 int32_t ipc_return_object_id) {
414 DCHECK(indexed_db_context_->TaskRunner()->RunsTasksOnCurrentThread());
415 ObjectType* return_object = map->Lookup(ipc_return_object_id);
416 if (!return_object) {
417 NOTREACHED() << "Uh oh, couldn't find object with id "
418 << ipc_return_object_id;
419 bad_message::ReceivedBadMessage(this, bad_message::IDBDH_GET_OR_TERMINATE);
420 }
421 return return_object;
422 }
423
424 template <typename MapType>
425 void IndexedDBDispatcherHost::DestroyObject(MapType* map,
426 int32_t ipc_object_id) {
427 GetOrTerminateProcess(map, ipc_object_id);
428 map->Remove(ipc_object_id);
429 }
430
431 //////////////////////////////////////////////////////////////////////
432 // IndexedDBDispatcherHost::CursorDispatcherHost
433 //
434
435 IndexedDBDispatcherHost::CursorDispatcherHost::CursorDispatcherHost(
436 IndexedDBDispatcherHost* parent)
437 : parent_(parent) {
438 }
439
440 IndexedDBDispatcherHost::CursorDispatcherHost::~CursorDispatcherHost() {}
441
442 bool IndexedDBDispatcherHost::CursorDispatcherHost::OnMessageReceived(
443 const IPC::Message& message) {
444 bool handled = true;
445 IPC_BEGIN_MESSAGE_MAP(
446 IndexedDBDispatcherHost::CursorDispatcherHost, message)
447 IPC_MESSAGE_HANDLER(IndexedDBHostMsg_CursorAdvance, OnAdvance)
448 IPC_MESSAGE_HANDLER(IndexedDBHostMsg_CursorContinue, OnContinue)
449 IPC_MESSAGE_HANDLER(IndexedDBHostMsg_CursorPrefetch, OnPrefetch)
450 IPC_MESSAGE_HANDLER(IndexedDBHostMsg_CursorPrefetchReset, OnPrefetchReset)
451 IPC_MESSAGE_HANDLER(IndexedDBHostMsg_CursorDestroyed, OnDestroyed)
452 IPC_MESSAGE_UNHANDLED(handled = false)
453 IPC_END_MESSAGE_MAP()
454
455 DCHECK(!handled ||
456 parent_->context()->TaskRunner()->RunsTasksOnCurrentThread());
457
458 return handled;
459 }
460
461 void IndexedDBDispatcherHost::CursorDispatcherHost::OnAdvance(
462 int32_t ipc_cursor_id,
463 int32_t ipc_thread_id,
464 int32_t ipc_callbacks_id,
465 uint32_t count) {
466 DCHECK(parent_->context()->TaskRunner()->RunsTasksOnCurrentThread());
467 IndexedDBCursor* idb_cursor =
468 parent_->GetOrTerminateProcess(&map_, ipc_cursor_id);
469 if (!idb_cursor)
470 return;
471
472 idb_cursor->Advance(
473 count,
474 new IndexedDBCallbacks(
475 parent_, ipc_thread_id, ipc_callbacks_id, ipc_cursor_id));
476 }
477
478 void IndexedDBDispatcherHost::CursorDispatcherHost::OnContinue(
479 int32_t ipc_cursor_id,
480 int32_t ipc_thread_id,
481 int32_t ipc_callbacks_id,
482 const IndexedDBKey& key,
483 const IndexedDBKey& primary_key) {
484 DCHECK(parent_->context()->TaskRunner()->RunsTasksOnCurrentThread());
485 IndexedDBCursor* idb_cursor =
486 parent_->GetOrTerminateProcess(&map_, ipc_cursor_id);
487 if (!idb_cursor)
488 return;
489
490 idb_cursor->Continue(key.IsValid() ? base::MakeUnique<IndexedDBKey>(key)
491 : std::unique_ptr<IndexedDBKey>(),
492 primary_key.IsValid()
493 ? base::MakeUnique<IndexedDBKey>(primary_key)
494 : std::unique_ptr<IndexedDBKey>(),
495 new IndexedDBCallbacks(parent_, ipc_thread_id,
496 ipc_callbacks_id, ipc_cursor_id));
497 }
498
499 void IndexedDBDispatcherHost::CursorDispatcherHost::OnPrefetch(
500 int32_t ipc_cursor_id,
501 int32_t ipc_thread_id,
502 int32_t ipc_callbacks_id,
503 int n) {
504 DCHECK(parent_->context()->TaskRunner()->RunsTasksOnCurrentThread());
505 IndexedDBCursor* idb_cursor =
506 parent_->GetOrTerminateProcess(&map_, ipc_cursor_id);
507 if (!idb_cursor)
508 return;
509
510 idb_cursor->PrefetchContinue(
511 n,
512 new IndexedDBCallbacks(
513 parent_, ipc_thread_id, ipc_callbacks_id, ipc_cursor_id));
514 }
515
516 void IndexedDBDispatcherHost::CursorDispatcherHost::OnPrefetchReset(
517 int32_t ipc_cursor_id,
518 int used_prefetches,
519 int unused_prefetches) {
520 DCHECK(parent_->context()->TaskRunner()->RunsTasksOnCurrentThread());
521 IndexedDBCursor* idb_cursor =
522 parent_->GetOrTerminateProcess(&map_, ipc_cursor_id);
523 if (!idb_cursor)
524 return;
525
526 leveldb::Status s =
527 idb_cursor->PrefetchReset(used_prefetches, unused_prefetches);
528 // TODO(cmumford): Handle this error (crbug.com/363397)
529 if (!s.ok())
530 DLOG(ERROR) << "Unable to reset prefetch";
531 }
532
533 void IndexedDBDispatcherHost::CursorDispatcherHost::OnDestroyed(
534 int32_t ipc_object_id) {
535 DCHECK(parent_->context()->TaskRunner()->RunsTasksOnCurrentThread());
536 parent_->DestroyObject(&map_, ipc_object_id);
537 }
538
539 } // namespace content 354 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698