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

Unified Diff: content/renderer/indexed_db_message_filter.cc

Issue 8747002: Dispatch IndexedDB IPC messages to worker threads (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 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 side-by-side diff with in-line comments
Download patch
Index: content/renderer/indexed_db_message_filter.cc
diff --git a/content/renderer/indexed_db_message_filter.cc b/content/renderer/indexed_db_message_filter.cc
new file mode 100644
index 0000000000000000000000000000000000000000..c2bf218aac021548afcaa894d29a1f2ad9947885
--- /dev/null
+++ b/content/renderer/indexed_db_message_filter.cc
@@ -0,0 +1,262 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/renderer/indexed_db_message_filter.h"
+
+#include "base/bind.h"
+#include "base/location.h"
+#include "content/common/indexed_db_messages.h"
+#include "content/renderer/indexed_db_dispatcher.h"
+#include "content/renderer/render_thread_impl.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebWorkerRunLoop.h"
+
+using WebKit::WebWorkerRunLoop;
+
+IndexedDBMessageFilter::IndexedDBMessageFilter() :
+ WebCoreWorkerTracker(),
+ main_thread_loop_proxy_(base::MessageLoopProxy::current()),
+ main_thread_dispatcher_(new IndexedDBDispatcher(this)) {
+}
+
+void IndexedDBMessageFilter::DidStartWorkerRunLoop(
+ const WebWorkerRunLoop& run_loop) {
+ DCHECK(!tls_worker_run_loop_.Get());
+ base::AutoLock locker(run_loops_lock_);
+ std::pair<LoopSet::iterator, bool> result = run_loops_.insert(run_loop);
+ DCHECK(result.second);
+ // We're storing WebWorkerRunLoop in the set, which doesn't allow
+ // modification through its iterators so as not to invalidate the uniqueness
+ // constraint on the set. But we've overloaded the comparison operators on
+ // WebWorkerRunLoop to ignore the non-const state.
+ WebWorkerRunLoop& a = const_cast<WebWorkerRunLoop&>(*result.first);
+ tls_worker_run_loop_.Set(&a);
+}
+
+void IndexedDBMessageFilter::DidStopWorkerRunLoop(
+ const WebWorkerRunLoop& run_loop) {
+ DCHECK(Contains(run_loop));
+ base::AutoLock locker(run_loops_lock_);
+ run_loops_.erase(run_loop);
+
+ DCHECK(tls_worker_run_loop_.Get());
+ tls_worker_run_loop_.Set(NULL);
michaeln 2011/11/30 21:48:14 Looks like there can tbe other instances of WebWor
+}
+
+WebKit::WebWorkerRunLoop* IndexedDBMessageFilter::current() {
+ return tls_worker_run_loop_.Get();
+}
+
+bool IndexedDBMessageFilter::Contains(const WebWorkerRunLoop& run_loop) {
+ base::AutoLock locker(run_loops_lock_);
+ LoopSet::iterator iter = run_loops_.find(run_loop);
+ return iter != run_loops_.end();
+}
+
+int IndexedDBMessageFilter::GetUniqueID() {
+ base::AutoLock locker(id_lock_);
+ int id = ++unique_id_;
+ if (current()) {
+ base::AutoLock map_locker(map_lock_);
+ id_to_run_loop_[id] = current();
+ }
+ return id;
+}
+
+IndexedDBMessageFilter::~IndexedDBMessageFilter() {
+ // This is never called.
+ DCHECK_EQ(run_loops_.size(), 0UL);
+}
+
+bool IndexedDBMessageFilter::OnMessageReceived(const IPC::Message& msg) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(IndexedDBMessageFilter, msg)
+ IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessIDBCursor,
+ OnSuccessOpenCursor)
+ IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessCursorContinue,
+ OnSuccessCursorContinue)
+ IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessIDBDatabase,
+ OnSuccessIDBDatabase)
+ IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessIndexedDBKey,
+ OnSuccessIndexedDBKey)
+ IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessIDBTransaction,
+ OnSuccessIDBTransaction)
+ IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessStringList,
+ OnSuccessStringList)
+ IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessSerializedScriptValue,
+ OnSuccessSerializedScriptValue)
+ IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksError, OnError)
+ IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksBlocked, OnBlocked)
+ IPC_MESSAGE_HANDLER(IndexedDBMsg_TransactionCallbacksAbort, OnAbort)
+ IPC_MESSAGE_HANDLER(IndexedDBMsg_TransactionCallbacksComplete, OnComplete)
+ IPC_MESSAGE_HANDLER(IndexedDBMsg_DatabaseCallbacksVersionChange,
+ OnVersionChange)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void IndexedDBMessageFilter::ForwardToMainThread(const IPC::Message& msg) {
+ main_thread_loop_proxy_->PostTask(FROM_HERE,
+ base::Bind(&IndexedDBDispatcher::OnMessageReceived,
+ main_thread_dispatcher_, msg));
+}
+
+class MsgForwarderTask : public WebKit::WebWorkerRunLoop::Task {
+ public:
+ MsgForwarderTask(const IPC::Message& msg, IndexedDBMessageFilter* filter) :
+ msg_(msg),
+ filter_(filter) {
+ }
+ virtual ~MsgForwarderTask() { }
+ virtual void Run() {
+ IndexedDBDispatcher* dispatcher = filter_->thread_specific_idb_dispatcher();
+ dispatcher->OnMessageReceived(msg_);
+ }
+ private:
+ const IPC::Message msg_;
+ IndexedDBMessageFilter* filter_;
+};
+
+void IndexedDBMessageFilter::ForwardToThread(const IPC::Message& msg, int32 id,
+ const IDToRunLoop& map) {
+ IDToRunLoop::const_iterator iter = map.find(id);
+ if (iter == map.end()) {
+ ForwardToMainThread(msg);
michaeln 2011/11/30 21:48:14 Do we need a stronger test for whether or not the
dgrogan 2011/11/30 23:25:18 As it stands now these maps aren't cleaned up, so
+ return;
+ }
+ MsgForwarderTask* task = new MsgForwarderTask(msg, this);
+ iter->second->postTask(task);
michaeln 2011/11/30 21:48:14 Should this be under the run_loops_lock_? What gua
dgrogan 2011/11/30 23:25:18 map_lock_, but yes. Fixed.
+}
+
+void IndexedDBMessageFilter::OnSuccessIDBDatabase(const IPC::Message& msg,
+ int32 response_id,
+ int32 object_id) {
+ ForwardToThread(msg, response_id, id_to_run_loop_);
+}
+
+void IndexedDBMessageFilter::OnSuccessIndexedDBKey(const IPC::Message& msg,
+ int32 response_id,
+ const IndexedDBKey& key) {
+ ForwardToThread(msg, response_id, id_to_run_loop_);
+}
+
+void IndexedDBMessageFilter::OnSuccessIDBTransaction(const IPC::Message& msg,
+ int32 response_id,
+ int32 object_id) {
+ ForwardToThread(msg, response_id, id_to_run_loop_);
+}
+
+void IndexedDBMessageFilter::OnSuccessStringList(const IPC::Message& msg,
+ int32 response_id, const std::vector<string16>& value) {
+ ForwardToThread(msg, response_id, id_to_run_loop_);
+}
+
+void IndexedDBMessageFilter::OnSuccessSerializedScriptValue(
+ const IPC::Message& msg, int32 response_id,
+ const content::SerializedScriptValue& value) {
+ ForwardToThread(msg, response_id, id_to_run_loop_);
+}
+
+void IndexedDBMessageFilter::OnSuccessOpenCursor(const IPC::Message& msg,
+ int32 response_id, int32 object_id, const IndexedDBKey& key,
+ const IndexedDBKey& primaryKey,
+ const content::SerializedScriptValue& value) {
+ ForwardToThread(msg, response_id, id_to_run_loop_);
+}
+
+void IndexedDBMessageFilter::OnSuccessCursorContinue(const IPC::Message& msg,
+ int32 response_id,
+ int32 cursor_id,
+ const IndexedDBKey& key,
+ const IndexedDBKey& primary_key,
+ const content::SerializedScriptValue& value) {
+ ForwardToThread(msg, response_id, id_to_run_loop_);
+}
+
+void IndexedDBMessageFilter::OnBlocked(const IPC::Message& msg,
+ int32 response_id) {
+ ForwardToThread(msg, response_id, id_to_run_loop_);
+}
+
+void IndexedDBMessageFilter::OnError(const IPC::Message& msg,
+ int32 response_id,
+ int code,
+ const string16& message) {
+ ForwardToThread(msg, response_id, id_to_run_loop_);
+}
+
+void IndexedDBMessageFilter::OnAbort(const IPC::Message& msg,
+ int32 transaction_id) {
+ ForwardToThread(msg, transaction_id, transaction_id_to_run_loop_);
+}
+
+void IndexedDBMessageFilter::OnComplete(const IPC::Message& msg,
+ int32 transaction_id) {
+ ForwardToThread(msg, transaction_id, transaction_id_to_run_loop_);
+}
+
+void IndexedDBMessageFilter::OnVersionChange(const IPC::Message& msg,
+ int32 database_id,
+ const string16& newVersion) {
+ ForwardToThread(msg, database_id, database_id_to_run_loop_);
+}
+
+IndexedDBDispatcher* IndexedDBMessageFilter::thread_specific_idb_dispatcher() {
+ WebWorkerRunLoop* current_loop = current();
+
+ if (current_loop == NULL) {
+ // If we're not on a worker thread we should be on the main thread.
+ DCHECK(RenderThreadImpl::current());
+ DCHECK(main_thread_dispatcher_.get());
+ return main_thread_dispatcher_.get();
+ }
+ DCHECK(Contains(*current_loop));
+ base::AutoLock lock(dispatchers_lock_);
+ LoopToDispatcherMap::iterator iter = dispatchers_.find(current_loop);
+ if (iter == dispatchers_.end()) {
+ dispatchers_[current_loop] = new IndexedDBDispatcher(this);
michaeln 2011/11/30 21:48:14 where is this map cleaned up?
dgrogan 2011/11/30 23:25:18 It appears that it isn't. I had intended to clean
+ }
+ return dispatchers_[current_loop];
+}
+
+void IndexedDBMessageFilter::RemoveForType(int32 id, WebKit::WebIDBCallbacks*) {
+ RemoveFromMap(id, &id_to_run_loop_);
+}
+
+void IndexedDBMessageFilter::RemoveForType(
+ int32 id,
+ WebKit::WebIDBDatabaseCallbacks*) {
+ RemoveFromMap(id, &database_id_to_run_loop_);
+}
+
+void IndexedDBMessageFilter::RemoveForType(
+ int32 id,
+ WebKit::WebIDBTransactionCallbacks*) {
+ RemoveFromMap(id, &transaction_id_to_run_loop_);
+}
+
+void IndexedDBMessageFilter::RemoveFromMap(int32 id, IDToRunLoop* map) {
+ // We don't store ids that are associated with the main thread.
+ if (!current())
+ return;
+ base::AutoLock map_locker(map_lock_);
+ int num_erased = map->erase(id);
+ DCHECK_EQ(num_erased, 1);
+}
+
+void IndexedDBMessageFilter::NotifyAddWithIDForType(
+ int32 id, WebKit::WebIDBTransactionCallbacks* callbacks) {
+ if (current()) {
+ base::AutoLock map_locker(map_lock_);
+ transaction_id_to_run_loop_[id] = current();
+ }
+}
+
+void IndexedDBMessageFilter::NotifyAddWithIDForType(int32 id,
+ WebKit::WebIDBDatabaseCallbacks* callbacks) {
+ if (current()) {
+ base::AutoLock map_locker(map_lock_);
+ database_id_to_run_loop_[id] = current();
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698