| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/child/indexed_db/indexed_db_dispatcher.h" | 5 #include "content/child/indexed_db/indexed_db_dispatcher.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/format_macros.h" | |
| 10 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
| 11 #include "base/strings/stringprintf.h" | |
| 12 #include "base/threading/thread_local.h" | 10 #include "base/threading/thread_local.h" |
| 13 #include "content/child/indexed_db/indexed_db_key_builders.h" | 11 #include "content/child/indexed_db/indexed_db_key_builders.h" |
| 14 #include "content/child/indexed_db/webidbcursor_impl.h" | 12 #include "content/child/indexed_db/webidbcursor_impl.h" |
| 15 #include "content/child/indexed_db/webidbdatabase_impl.h" | |
| 16 #include "content/child/thread_safe_sender.h" | |
| 17 #include "content/common/indexed_db/indexed_db_messages.h" | 13 #include "content/common/indexed_db/indexed_db_messages.h" |
| 18 #include "ipc/ipc_channel.h" | 14 #include "ipc/ipc_channel.h" |
| 19 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseCal
lbacks.h" | 15 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseCal
lbacks.h" |
| 20 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseErr
or.h" | |
| 21 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseExc
eption.h" | |
| 22 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBObservation
.h" | 16 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBObservation
.h" |
| 23 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBValue.h" | |
| 24 | 17 |
| 25 using blink::WebBlobInfo; | |
| 26 using blink::WebData; | |
| 27 using blink::WebIDBCallbacks; | |
| 28 using blink::WebIDBCursor; | |
| 29 using blink::WebIDBDatabase; | |
| 30 using blink::WebIDBDatabaseCallbacks; | |
| 31 using blink::WebIDBDatabaseError; | |
| 32 using blink::WebIDBKey; | 18 using blink::WebIDBKey; |
| 33 using blink::WebIDBMetadata; | |
| 34 using blink::WebIDBObservation; | 19 using blink::WebIDBObservation; |
| 35 using blink::WebIDBObserver; | 20 using blink::WebIDBObserver; |
| 36 using blink::WebIDBValue; | |
| 37 using blink::WebString; | |
| 38 using blink::WebVector; | |
| 39 using base::ThreadLocalPointer; | 21 using base::ThreadLocalPointer; |
| 40 | 22 |
| 41 namespace content { | 23 namespace content { |
| 42 static base::LazyInstance<ThreadLocalPointer<IndexedDBDispatcher> >::Leaky | 24 static base::LazyInstance<ThreadLocalPointer<IndexedDBDispatcher> >::Leaky |
| 43 g_idb_dispatcher_tls = LAZY_INSTANCE_INITIALIZER; | 25 g_idb_dispatcher_tls = LAZY_INSTANCE_INITIALIZER; |
| 44 | 26 |
| 45 namespace { | 27 namespace { |
| 46 | 28 |
| 47 IndexedDBDispatcher* const kHasBeenDeleted = | 29 IndexedDBDispatcher* const kHasBeenDeleted = |
| 48 reinterpret_cast<IndexedDBDispatcher*>(0x1); | 30 reinterpret_cast<IndexedDBDispatcher*>(0x1); |
| 49 | 31 |
| 50 } // unnamed namespace | 32 } // unnamed namespace |
| 51 | 33 |
| 52 IndexedDBDispatcher::IndexedDBDispatcher(ThreadSafeSender* thread_safe_sender) | 34 IndexedDBDispatcher::IndexedDBDispatcher() { |
| 53 : thread_safe_sender_(thread_safe_sender) { | |
| 54 g_idb_dispatcher_tls.Pointer()->Set(this); | 35 g_idb_dispatcher_tls.Pointer()->Set(this); |
| 55 } | 36 } |
| 56 | 37 |
| 57 IndexedDBDispatcher::~IndexedDBDispatcher() { | 38 IndexedDBDispatcher::~IndexedDBDispatcher() { |
| 58 // Clear any pending callbacks - which may result in dispatch requests - | |
| 59 // before marking the dispatcher as deleted. | |
| 60 pending_callbacks_.Clear(); | |
| 61 | |
| 62 DCHECK(pending_callbacks_.IsEmpty()); | |
| 63 | |
| 64 g_idb_dispatcher_tls.Pointer()->Set(kHasBeenDeleted); | 39 g_idb_dispatcher_tls.Pointer()->Set(kHasBeenDeleted); |
| 65 } | 40 } |
| 66 | 41 |
| 67 IndexedDBDispatcher* IndexedDBDispatcher::ThreadSpecificInstance( | 42 IndexedDBDispatcher* IndexedDBDispatcher::ThreadSpecificInstance() { |
| 68 ThreadSafeSender* thread_safe_sender) { | |
| 69 if (g_idb_dispatcher_tls.Pointer()->Get() == kHasBeenDeleted) { | 43 if (g_idb_dispatcher_tls.Pointer()->Get() == kHasBeenDeleted) { |
| 70 NOTREACHED() << "Re-instantiating TLS IndexedDBDispatcher."; | 44 NOTREACHED() << "Re-instantiating TLS IndexedDBDispatcher."; |
| 71 g_idb_dispatcher_tls.Pointer()->Set(NULL); | 45 g_idb_dispatcher_tls.Pointer()->Set(NULL); |
| 72 } | 46 } |
| 73 if (g_idb_dispatcher_tls.Pointer()->Get()) | 47 if (g_idb_dispatcher_tls.Pointer()->Get()) |
| 74 return g_idb_dispatcher_tls.Pointer()->Get(); | 48 return g_idb_dispatcher_tls.Pointer()->Get(); |
| 75 | 49 |
| 76 IndexedDBDispatcher* dispatcher = new IndexedDBDispatcher(thread_safe_sender); | 50 IndexedDBDispatcher* dispatcher = new IndexedDBDispatcher(); |
| 77 if (WorkerThread::GetCurrentId()) | 51 if (WorkerThread::GetCurrentId()) |
| 78 WorkerThread::AddObserver(dispatcher); | 52 WorkerThread::AddObserver(dispatcher); |
| 79 return dispatcher; | 53 return dispatcher; |
| 80 } | 54 } |
| 81 | 55 |
| 82 void IndexedDBDispatcher::WillStopCurrentWorkerThread() { | 56 void IndexedDBDispatcher::WillStopCurrentWorkerThread() { |
| 83 delete this; | 57 delete this; |
| 84 } | 58 } |
| 85 | 59 |
| 86 std::vector<WebIDBObservation> IndexedDBDispatcher::ConvertObservations( | 60 std::vector<WebIDBObservation> IndexedDBDispatcher::ConvertObservations( |
| 87 const std::vector<IndexedDBMsg_Observation>& idb_observations) { | 61 const std::vector<IndexedDBMsg_Observation>& idb_observations) { |
| 88 std::vector<WebIDBObservation> web_observations; | 62 std::vector<WebIDBObservation> web_observations; |
| 89 for (const auto& idb_observation : idb_observations) { | 63 for (const auto& idb_observation : idb_observations) { |
| 90 WebIDBObservation web_observation; | 64 WebIDBObservation web_observation; |
| 91 web_observation.objectStoreId = idb_observation.object_store_id; | 65 web_observation.objectStoreId = idb_observation.object_store_id; |
| 92 web_observation.type = idb_observation.type; | 66 web_observation.type = idb_observation.type; |
| 93 web_observation.keyRange = | 67 web_observation.keyRange = |
| 94 WebIDBKeyRangeBuilder::Build(idb_observation.key_range); | 68 WebIDBKeyRangeBuilder::Build(idb_observation.key_range); |
| 95 // TODO(palakj): Assign value to web_observation. | 69 // TODO(palakj): Assign value to web_observation. |
| 96 web_observations.push_back(std::move(web_observation)); | 70 web_observations.push_back(std::move(web_observation)); |
| 97 } | 71 } |
| 98 return web_observations; | 72 return web_observations; |
| 99 } | 73 } |
| 100 | 74 |
| 101 void IndexedDBDispatcher::OnMessageReceived(const IPC::Message& msg) { | 75 void IndexedDBDispatcher::OnMessageReceived(const IPC::Message& msg) { |
| 102 bool handled = true; | 76 bool handled = true; |
| 103 IPC_BEGIN_MESSAGE_MAP(IndexedDBDispatcher, msg) | 77 IPC_BEGIN_MESSAGE_MAP(IndexedDBDispatcher, msg) |
| 104 IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessCursorAdvance, | |
| 105 OnSuccessCursorContinue) | |
| 106 IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessCursorContinue, | |
| 107 OnSuccessCursorContinue) | |
| 108 IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessCursorPrefetch, | |
| 109 OnSuccessCursorPrefetch) | |
| 110 IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessValue, OnSuccessValue) | |
| 111 IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksSuccessInteger, OnSuccessInteger) | |
| 112 IPC_MESSAGE_HANDLER(IndexedDBMsg_CallbacksError, OnError) | |
| 113 IPC_MESSAGE_HANDLER(IndexedDBMsg_DatabaseCallbacksChanges, | 78 IPC_MESSAGE_HANDLER(IndexedDBMsg_DatabaseCallbacksChanges, |
| 114 OnDatabaseChanges) | 79 OnDatabaseChanges) |
| 115 IPC_MESSAGE_UNHANDLED(handled = false) | 80 IPC_MESSAGE_UNHANDLED(handled = false) |
| 116 IPC_END_MESSAGE_MAP() | 81 IPC_END_MESSAGE_MAP() |
| 117 // If a message gets here, IndexedDBMessageFilter already determined that it | 82 // If a message gets here, IndexedDBMessageFilter already determined that it |
| 118 // is an IndexedDB message. | 83 // is an IndexedDB message. |
| 119 DCHECK(handled) << "Didn't handle a message defined at line " | 84 DCHECK(handled) << "Didn't handle a message defined at line " |
| 120 << IPC_MESSAGE_ID_LINE(msg.type()); | 85 << IPC_MESSAGE_ID_LINE(msg.type()); |
| 121 } | 86 } |
| 122 | 87 |
| 123 bool IndexedDBDispatcher::Send(IPC::Message* msg) { | |
| 124 return thread_safe_sender_->Send(msg); | |
| 125 } | |
| 126 | |
| 127 int32_t IndexedDBDispatcher::RegisterObserver( | 88 int32_t IndexedDBDispatcher::RegisterObserver( |
| 128 std::unique_ptr<WebIDBObserver> observer) { | 89 std::unique_ptr<WebIDBObserver> observer) { |
| 129 return observers_.Add(observer.release()); | 90 return observers_.Add(observer.release()); |
| 130 } | 91 } |
| 131 | 92 |
| 132 void IndexedDBDispatcher::RemoveObservers( | 93 void IndexedDBDispatcher::RemoveObservers( |
| 133 const std::vector<int32_t>& observer_ids_to_remove) { | 94 const std::vector<int32_t>& observer_ids_to_remove) { |
| 134 for (int32_t id : observer_ids_to_remove) | 95 for (int32_t id : observer_ids_to_remove) |
| 135 observers_.Remove(id); | 96 observers_.Remove(id); |
| 136 } | 97 } |
| 137 | 98 |
| 138 void IndexedDBDispatcher::RequestIDBCursorAdvance( | |
| 139 unsigned long count, | |
| 140 WebIDBCallbacks* callbacks_ptr, | |
| 141 int32_t ipc_cursor_id, | |
| 142 int64_t transaction_id) { | |
| 143 // Reset all cursor prefetch caches except for this cursor. | |
| 144 ResetCursorPrefetchCaches(transaction_id, ipc_cursor_id); | |
| 145 | |
| 146 std::unique_ptr<WebIDBCallbacks> callbacks(callbacks_ptr); | |
| 147 | |
| 148 int32_t ipc_callbacks_id = pending_callbacks_.Add(callbacks.release()); | |
| 149 Send(new IndexedDBHostMsg_CursorAdvance( | |
| 150 ipc_cursor_id, CurrentWorkerId(), ipc_callbacks_id, count)); | |
| 151 } | |
| 152 | |
| 153 void IndexedDBDispatcher::RequestIDBCursorContinue( | |
| 154 const IndexedDBKey& key, | |
| 155 const IndexedDBKey& primary_key, | |
| 156 WebIDBCallbacks* callbacks_ptr, | |
| 157 int32_t ipc_cursor_id, | |
| 158 int64_t transaction_id) { | |
| 159 // Reset all cursor prefetch caches except for this cursor. | |
| 160 ResetCursorPrefetchCaches(transaction_id, ipc_cursor_id); | |
| 161 | |
| 162 std::unique_ptr<WebIDBCallbacks> callbacks(callbacks_ptr); | |
| 163 | |
| 164 int32_t ipc_callbacks_id = pending_callbacks_.Add(callbacks.release()); | |
| 165 Send(new IndexedDBHostMsg_CursorContinue( | |
| 166 ipc_cursor_id, CurrentWorkerId(), ipc_callbacks_id, key, primary_key)); | |
| 167 } | |
| 168 | |
| 169 void IndexedDBDispatcher::RequestIDBCursorPrefetch( | |
| 170 int n, | |
| 171 WebIDBCallbacks* callbacks_ptr, | |
| 172 int32_t ipc_cursor_id) { | |
| 173 std::unique_ptr<WebIDBCallbacks> callbacks(callbacks_ptr); | |
| 174 | |
| 175 int32_t ipc_callbacks_id = pending_callbacks_.Add(callbacks.release()); | |
| 176 Send(new IndexedDBHostMsg_CursorPrefetch( | |
| 177 ipc_cursor_id, CurrentWorkerId(), ipc_callbacks_id, n)); | |
| 178 } | |
| 179 | |
| 180 void IndexedDBDispatcher::RequestIDBCursorPrefetchReset(int used_prefetches, | |
| 181 int unused_prefetches, | |
| 182 int32_t ipc_cursor_id) { | |
| 183 Send(new IndexedDBHostMsg_CursorPrefetchReset( | |
| 184 ipc_cursor_id, used_prefetches, unused_prefetches)); | |
| 185 } | |
| 186 | |
| 187 void IndexedDBDispatcher::RegisterCursor(int32_t ipc_cursor_id, | |
| 188 WebIDBCursorImpl* cursor) { | |
| 189 DCHECK(!base::ContainsKey(cursors_, ipc_cursor_id)); | |
| 190 cursors_[ipc_cursor_id] = cursor; | |
| 191 } | |
| 192 | |
| 193 void IndexedDBDispatcher::CursorDestroyed(int32_t ipc_cursor_id) { | |
| 194 cursors_.erase(ipc_cursor_id); | |
| 195 } | |
| 196 | |
| 197 void IndexedDBDispatcher::RegisterMojoOwnedCallbacks( | 99 void IndexedDBDispatcher::RegisterMojoOwnedCallbacks( |
| 198 IndexedDBCallbacksImpl::InternalState* callbacks) { | 100 IndexedDBCallbacksImpl::InternalState* callbacks) { |
| 199 mojo_owned_callback_state_.insert(callbacks); | 101 mojo_owned_callback_state_.insert(callbacks); |
| 200 } | 102 } |
| 201 | 103 |
| 202 void IndexedDBDispatcher::UnregisterMojoOwnedCallbacks( | 104 void IndexedDBDispatcher::UnregisterMojoOwnedCallbacks( |
| 203 IndexedDBCallbacksImpl::InternalState* callbacks) { | 105 IndexedDBCallbacksImpl::InternalState* callbacks) { |
| 204 DCHECK(base::ContainsValue(mojo_owned_callback_state_, callbacks)); | 106 DCHECK(base::ContainsValue(mojo_owned_callback_state_, callbacks)); |
| 205 mojo_owned_callback_state_.erase(callbacks); | 107 mojo_owned_callback_state_.erase(callbacks); |
| 206 } | 108 } |
| 207 | 109 |
| 208 void IndexedDBDispatcher::RegisterMojoOwnedDatabaseCallbacks( | 110 void IndexedDBDispatcher::RegisterMojoOwnedDatabaseCallbacks( |
| 209 blink::WebIDBDatabaseCallbacks* callbacks) { | 111 blink::WebIDBDatabaseCallbacks* callbacks) { |
| 210 mojo_owned_database_callback_state_.insert(callbacks); | 112 mojo_owned_database_callback_state_.insert(callbacks); |
| 211 } | 113 } |
| 212 | 114 |
| 213 void IndexedDBDispatcher::UnregisterMojoOwnedDatabaseCallbacks( | 115 void IndexedDBDispatcher::UnregisterMojoOwnedDatabaseCallbacks( |
| 214 blink::WebIDBDatabaseCallbacks* callbacks) { | 116 blink::WebIDBDatabaseCallbacks* callbacks) { |
| 215 DCHECK(base::ContainsValue(mojo_owned_database_callback_state_, callbacks)); | 117 DCHECK(base::ContainsValue(mojo_owned_database_callback_state_, callbacks)); |
| 216 mojo_owned_database_callback_state_.erase(callbacks); | 118 mojo_owned_database_callback_state_.erase(callbacks); |
| 217 } | 119 } |
| 218 | 120 |
| 219 // Populate some WebIDBValue members (data & blob info) from the supplied | |
| 220 // value message (IndexedDBMsg_Value or one that includes it). | |
| 221 template <class IndexedDBMsgValueType> | |
| 222 static void PrepareWebValue(const IndexedDBMsgValueType& value, | |
| 223 WebIDBValue* web_value) { | |
| 224 if (value.bits.empty()) | |
| 225 return; | |
| 226 | |
| 227 web_value->data.assign(&*value.bits.begin(), value.bits.size()); | |
| 228 blink::WebVector<WebBlobInfo> local_blob_info(value.blob_or_file_info.size()); | |
| 229 for (size_t i = 0; i < value.blob_or_file_info.size(); ++i) { | |
| 230 const IndexedDBMsg_BlobOrFileInfo& info = value.blob_or_file_info[i]; | |
| 231 if (info.is_file) { | |
| 232 local_blob_info[i] = WebBlobInfo( | |
| 233 WebString::fromUTF8(info.uuid.c_str()), info.file_path, | |
| 234 info.file_name, info.mime_type, info.last_modified, info.size); | |
| 235 } else { | |
| 236 local_blob_info[i] = WebBlobInfo(WebString::fromUTF8(info.uuid.c_str()), | |
| 237 info.mime_type, info.size); | |
| 238 } | |
| 239 } | |
| 240 | |
| 241 web_value->webBlobInfo.swap(local_blob_info); | |
| 242 } | |
| 243 | |
| 244 static void PrepareReturnWebValue(const IndexedDBMsg_ReturnValue& value, | |
| 245 WebIDBValue* web_value) { | |
| 246 PrepareWebValue(value, web_value); | |
| 247 web_value->primaryKey = WebIDBKeyBuilder::Build(value.primary_key); | |
| 248 web_value->keyPath = WebIDBKeyPathBuilder::Build(value.key_path); | |
| 249 } | |
| 250 | |
| 251 void IndexedDBDispatcher::OnSuccessValue( | |
| 252 const IndexedDBMsg_CallbacksSuccessValue_Params& params) { | |
| 253 DCHECK_EQ(params.ipc_thread_id, CurrentWorkerId()); | |
| 254 WebIDBCallbacks* callbacks = | |
| 255 pending_callbacks_.Lookup(params.ipc_callbacks_id); | |
| 256 if (!callbacks) | |
| 257 return; | |
| 258 WebIDBValue web_value; | |
| 259 PrepareReturnWebValue(params.value, &web_value); | |
| 260 if (params.value.primary_key.IsValid()) { | |
| 261 web_value.primaryKey = WebIDBKeyBuilder::Build(params.value.primary_key); | |
| 262 web_value.keyPath = WebIDBKeyPathBuilder::Build(params.value.key_path); | |
| 263 } | |
| 264 callbacks->onSuccess(web_value); | |
| 265 pending_callbacks_.Remove(params.ipc_callbacks_id); | |
| 266 } | |
| 267 | |
| 268 void IndexedDBDispatcher::OnSuccessInteger(int32_t ipc_thread_id, | |
| 269 int32_t ipc_callbacks_id, | |
| 270 int64_t value) { | |
| 271 DCHECK_EQ(ipc_thread_id, CurrentWorkerId()); | |
| 272 WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(ipc_callbacks_id); | |
| 273 if (!callbacks) | |
| 274 return; | |
| 275 callbacks->onSuccess(value); | |
| 276 pending_callbacks_.Remove(ipc_callbacks_id); | |
| 277 } | |
| 278 | |
| 279 void IndexedDBDispatcher::OnSuccessCursorContinue( | |
| 280 const IndexedDBMsg_CallbacksSuccessCursorContinue_Params& p) { | |
| 281 DCHECK_EQ(p.ipc_thread_id, CurrentWorkerId()); | |
| 282 int32_t ipc_callbacks_id = p.ipc_callbacks_id; | |
| 283 int32_t ipc_cursor_id = p.ipc_cursor_id; | |
| 284 const IndexedDBKey& key = p.key; | |
| 285 const IndexedDBKey& primary_key = p.primary_key; | |
| 286 | |
| 287 if (cursors_.find(ipc_cursor_id) == cursors_.end()) | |
| 288 return; | |
| 289 | |
| 290 WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(ipc_callbacks_id); | |
| 291 if (!callbacks) | |
| 292 return; | |
| 293 | |
| 294 WebIDBValue web_value; | |
| 295 PrepareWebValue(p.value, &web_value); | |
| 296 callbacks->onSuccess(WebIDBKeyBuilder::Build(key), | |
| 297 WebIDBKeyBuilder::Build(primary_key), web_value); | |
| 298 | |
| 299 pending_callbacks_.Remove(ipc_callbacks_id); | |
| 300 } | |
| 301 | |
| 302 void IndexedDBDispatcher::OnSuccessCursorPrefetch( | |
| 303 const IndexedDBMsg_CallbacksSuccessCursorPrefetch_Params& p) { | |
| 304 DCHECK_EQ(p.ipc_thread_id, CurrentWorkerId()); | |
| 305 int32_t ipc_callbacks_id = p.ipc_callbacks_id; | |
| 306 int32_t ipc_cursor_id = p.ipc_cursor_id; | |
| 307 std::vector<WebIDBValue> values(p.values.size()); | |
| 308 for (size_t i = 0; i < p.values.size(); ++i) | |
| 309 PrepareWebValue(p.values[i], &values[i]); | |
| 310 std::map<int32_t, WebIDBCursorImpl*>::const_iterator cur_iter = | |
| 311 cursors_.find(ipc_cursor_id); | |
| 312 if (cur_iter == cursors_.end()) | |
| 313 return; | |
| 314 | |
| 315 cur_iter->second->SetPrefetchData(p.keys, p.primary_keys, values); | |
| 316 | |
| 317 WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(ipc_callbacks_id); | |
| 318 DCHECK(callbacks); | |
| 319 cur_iter->second->CachedContinue(callbacks); | |
| 320 pending_callbacks_.Remove(ipc_callbacks_id); | |
| 321 } | |
| 322 | |
| 323 void IndexedDBDispatcher::OnError(int32_t ipc_thread_id, | |
| 324 int32_t ipc_callbacks_id, | |
| 325 int code, | |
| 326 const base::string16& message) { | |
| 327 DCHECK_EQ(ipc_thread_id, CurrentWorkerId()); | |
| 328 WebIDBCallbacks* callbacks = pending_callbacks_.Lookup(ipc_callbacks_id); | |
| 329 if (!callbacks) | |
| 330 return; | |
| 331 if (message.empty()) | |
| 332 callbacks->onError(WebIDBDatabaseError(code)); | |
| 333 else | |
| 334 callbacks->onError(WebIDBDatabaseError(code, message)); | |
| 335 pending_callbacks_.Remove(ipc_callbacks_id); | |
| 336 } | |
| 337 | |
| 338 void IndexedDBDispatcher::OnDatabaseChanges( | 121 void IndexedDBDispatcher::OnDatabaseChanges( |
| 339 int32_t ipc_thread_id, | 122 int32_t ipc_thread_id, |
| 340 const IndexedDBMsg_ObserverChanges& changes) { | 123 const IndexedDBMsg_ObserverChanges& changes) { |
| 341 DCHECK_EQ(ipc_thread_id, CurrentWorkerId()); | 124 DCHECK_EQ(ipc_thread_id, CurrentWorkerId()); |
| 342 std::vector<WebIDBObservation> observations( | 125 std::vector<WebIDBObservation> observations( |
| 343 ConvertObservations(changes.observations)); | 126 ConvertObservations(changes.observations)); |
| 344 for (auto& it : changes.observation_index) { | 127 for (auto& it : changes.observation_index) { |
| 345 WebIDBObserver* observer = observers_.Lookup(it.first); | 128 WebIDBObserver* observer = observers_.Lookup(it.first); |
| 346 // An observer can be removed from the renderer, but still exist in the | 129 // An observer can be removed from the renderer, but still exist in the |
| 347 // backend. Moreover, observer might have recorded some changes before being | 130 // backend. Moreover, observer might have recorded some changes before being |
| 348 // removed from the backend and thus, have its id be present in changes. | 131 // removed from the backend and thus, have its id be present in changes. |
| 349 if (!observer) | 132 if (!observer) |
| 350 continue; | 133 continue; |
| 351 observer->onChange(observations, std::move(it.second)); | 134 observer->onChange(observations, std::move(it.second)); |
| 352 } | 135 } |
| 353 } | 136 } |
| 354 | 137 |
| 138 void IndexedDBDispatcher::RegisterCursor(WebIDBCursorImpl* cursor) { |
| 139 DCHECK(!base::ContainsValue(cursors_, cursor)); |
| 140 cursors_.insert(cursor); |
| 141 } |
| 142 |
| 143 void IndexedDBDispatcher::UnregisterCursor(WebIDBCursorImpl* cursor) { |
| 144 DCHECK(base::ContainsValue(cursors_, cursor)); |
| 145 cursors_.erase(cursor); |
| 146 } |
| 147 |
| 355 void IndexedDBDispatcher::ResetCursorPrefetchCaches( | 148 void IndexedDBDispatcher::ResetCursorPrefetchCaches( |
| 356 int64_t transaction_id, | 149 int64_t transaction_id, |
| 357 int32_t ipc_exception_cursor_id) { | 150 WebIDBCursorImpl* exception_cursor) { |
| 358 typedef std::map<int32_t, WebIDBCursorImpl*>::iterator Iterator; | 151 for (WebIDBCursorImpl* cursor : cursors_) { |
| 359 for (Iterator i = cursors_.begin(); i != cursors_.end(); ++i) { | 152 if (cursor != exception_cursor && |
| 360 if (i->first == ipc_exception_cursor_id || | 153 cursor->transaction_id() == transaction_id) |
| 361 i->second->transaction_id() != transaction_id) | 154 cursor->ResetPrefetchCache(); |
| 362 continue; | |
| 363 i->second->ResetPrefetchCache(); | |
| 364 } | 155 } |
| 365 } | 156 } |
| 366 | 157 |
| 367 } // namespace content | 158 } // namespace content |
| OLD | NEW |