Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * | 10 * |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 34 #include "modules/indexeddb/IDBMetadata.h" | 34 #include "modules/indexeddb/IDBMetadata.h" |
| 35 #include "modules/indexeddb/IDBRequest.h" | 35 #include "modules/indexeddb/IDBRequest.h" |
| 36 #include "modules/indexeddb/IDBValue.h" | 36 #include "modules/indexeddb/IDBValue.h" |
| 37 #include "platform/SharedBuffer.h" | 37 #include "platform/SharedBuffer.h" |
| 38 #include "public/platform/modules/indexeddb/WebIDBCursor.h" | 38 #include "public/platform/modules/indexeddb/WebIDBCursor.h" |
| 39 #include "public/platform/modules/indexeddb/WebIDBDatabase.h" | 39 #include "public/platform/modules/indexeddb/WebIDBDatabase.h" |
| 40 #include "public/platform/modules/indexeddb/WebIDBDatabaseError.h" | 40 #include "public/platform/modules/indexeddb/WebIDBDatabaseError.h" |
| 41 #include "public/platform/modules/indexeddb/WebIDBKey.h" | 41 #include "public/platform/modules/indexeddb/WebIDBKey.h" |
| 42 #include "public/platform/modules/indexeddb/WebIDBValue.h" | 42 #include "public/platform/modules/indexeddb/WebIDBValue.h" |
| 43 #include "wtf/PtrUtil.h" | 43 #include "wtf/PtrUtil.h" |
| 44 #include "wtf/ThreadSpecific.h" | |
| 44 #include <memory> | 45 #include <memory> |
| 45 | 46 |
| 46 using blink::WebIDBCursor; | 47 using blink::WebIDBCursor; |
| 47 using blink::WebIDBDatabase; | 48 using blink::WebIDBDatabase; |
| 48 using blink::WebIDBDatabaseError; | 49 using blink::WebIDBDatabaseError; |
| 49 using blink::WebIDBKey; | 50 using blink::WebIDBKey; |
| 50 using blink::WebIDBKeyPath; | 51 using blink::WebIDBKeyPath; |
| 51 using blink::WebIDBMetadata; | 52 using blink::WebIDBMetadata; |
| 52 using blink::WebIDBValue; | 53 using blink::WebIDBValue; |
| 53 using blink::WebVector; | 54 using blink::WebVector; |
| 54 | 55 |
| 55 namespace blink { | 56 namespace blink { |
| 56 | 57 |
| 58 // This thread-specific list keeps track of instances of WebIDBCallbacksImpl | |
| 59 // created by each thread. If a thread exits before they are destroyed then they | |
| 60 // would otherwise be leaked because the IO thread can no longer post a task to | |
| 61 // the thread on which they were created. | |
| 62 using CallbacksList = std::vector<std::unique_ptr<WebIDBCallbacksImpl>>; | |
|
dcheng
2016/10/17 05:33:44
Inside Blink, we should probably be using WTF::Vec
| |
| 63 static ThreadSpecific<CallbacksList>& outstandingCallbacks() { | |
|
haraken
2016/10/18 19:01:29
It's not really nice to use ThreadSpecific to keep
Reilly Grant (use Gerrit)
2016/10/19 00:36:51
The only per-worker object I know of that could ho
| |
| 64 DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<CallbacksList>, callbacks, | |
| 65 new ThreadSpecific<CallbacksList>); | |
| 66 return callbacks; | |
| 67 } | |
| 68 | |
| 57 // static | 69 // static |
| 58 std::unique_ptr<WebIDBCallbacksImpl> WebIDBCallbacksImpl::create( | 70 std::unique_ptr<WebIDBCallbacksImpl> WebIDBCallbacksImpl::create( |
| 59 IDBRequest* request) { | 71 IDBRequest* request) { |
| 60 return wrapUnique(new WebIDBCallbacksImpl(request)); | 72 return wrapUnique(new WebIDBCallbacksImpl(request)); |
| 61 } | 73 } |
| 62 | 74 |
| 63 WebIDBCallbacksImpl::WebIDBCallbacksImpl(IDBRequest* request) | 75 WebIDBCallbacksImpl::WebIDBCallbacksImpl(IDBRequest* request) |
| 64 : m_request(request) { | 76 : m_request(request) { |
| 65 InspectorInstrumentation::asyncTaskScheduled( | 77 InspectorInstrumentation::asyncTaskScheduled( |
| 66 m_request->getExecutionContext(), IndexedDBNames::IndexedDB, this, true); | 78 m_request->getExecutionContext(), IndexedDBNames::IndexedDB, this, true); |
| 79 outstandingCallbacks()->push_back(wrapUnique(this)); | |
| 67 } | 80 } |
| 68 | 81 |
| 69 WebIDBCallbacksImpl::~WebIDBCallbacksImpl() { | 82 WebIDBCallbacksImpl::~WebIDBCallbacksImpl() { |
| 70 InspectorInstrumentation::asyncTaskCanceled(m_request->getExecutionContext(), | 83 if (m_request) { |
| 71 this); | 84 InspectorInstrumentation::asyncTaskCanceled( |
| 85 m_request->getExecutionContext(), this); | |
| 86 m_request->webCallbacksDestroyed(); | |
| 87 } | |
| 88 | |
| 89 CallbacksList& callbacks = *outstandingCallbacks(); | |
| 90 auto it = | |
| 91 std::find_if(callbacks.begin(), callbacks.end(), | |
|
haraken
2016/10/18 19:01:29
To avoid the O(N) search, would it be better to us
Reilly Grant (use Gerrit)
2016/10/19 00:36:51
The number of outstanding requests is expected to
| |
| 92 [this](const std::unique_ptr<WebIDBCallbacksImpl>& element) { | |
| 93 return element.get() == this; | |
| 94 }); | |
| 95 if (it != callbacks.end()) { | |
| 96 it->release(); | |
| 97 callbacks.erase(it); | |
| 98 } | |
| 72 } | 99 } |
| 73 | 100 |
| 74 void WebIDBCallbacksImpl::onError(const WebIDBDatabaseError& error) { | 101 void WebIDBCallbacksImpl::onError(const WebIDBDatabaseError& error) { |
| 102 if (!m_request) | |
| 103 return; | |
| 104 | |
| 75 InspectorInstrumentation::AsyncTask asyncTask( | 105 InspectorInstrumentation::AsyncTask asyncTask( |
| 76 m_request->getExecutionContext(), this); | 106 m_request->getExecutionContext(), this); |
| 77 m_request->onError(DOMException::create(error.code(), error.message())); | 107 m_request->onError(DOMException::create(error.code(), error.message())); |
| 78 } | 108 } |
| 79 | 109 |
| 80 void WebIDBCallbacksImpl::onSuccess(const WebVector<WebString>& webStringList) { | 110 void WebIDBCallbacksImpl::onSuccess(const WebVector<WebString>& webStringList) { |
| 111 if (!m_request) | |
| 112 return; | |
| 113 | |
| 81 Vector<String> stringList; | 114 Vector<String> stringList; |
| 82 for (size_t i = 0; i < webStringList.size(); ++i) | 115 for (size_t i = 0; i < webStringList.size(); ++i) |
| 83 stringList.append(webStringList[i]); | 116 stringList.append(webStringList[i]); |
| 84 InspectorInstrumentation::AsyncTask asyncTask( | 117 InspectorInstrumentation::AsyncTask asyncTask( |
| 85 m_request->getExecutionContext(), this); | 118 m_request->getExecutionContext(), this); |
| 86 m_request->onSuccess(stringList); | 119 m_request->onSuccess(stringList); |
| 87 } | 120 } |
| 88 | 121 |
| 89 void WebIDBCallbacksImpl::onSuccess(WebIDBCursor* cursor, | 122 void WebIDBCallbacksImpl::onSuccess(WebIDBCursor* cursor, |
| 90 const WebIDBKey& key, | 123 const WebIDBKey& key, |
| 91 const WebIDBKey& primaryKey, | 124 const WebIDBKey& primaryKey, |
| 92 const WebIDBValue& value) { | 125 const WebIDBValue& value) { |
| 126 if (!m_request) | |
| 127 return; | |
| 128 | |
| 93 InspectorInstrumentation::AsyncTask asyncTask( | 129 InspectorInstrumentation::AsyncTask asyncTask( |
| 94 m_request->getExecutionContext(), this); | 130 m_request->getExecutionContext(), this); |
| 95 m_request->onSuccess(wrapUnique(cursor), key, primaryKey, | 131 m_request->onSuccess(wrapUnique(cursor), key, primaryKey, |
| 96 IDBValue::create(value)); | 132 IDBValue::create(value)); |
| 97 } | 133 } |
| 98 | 134 |
| 99 void WebIDBCallbacksImpl::onSuccess(WebIDBDatabase* backend, | 135 void WebIDBCallbacksImpl::onSuccess(WebIDBDatabase* backend, |
| 100 const WebIDBMetadata& metadata) { | 136 const WebIDBMetadata& metadata) { |
| 101 InspectorInstrumentation::AsyncTask asyncTask( | 137 std::unique_ptr<WebIDBDatabase> db = wrapUnique(backend); |
| 102 m_request->getExecutionContext(), this); | 138 if (m_request) { |
| 103 m_request->onSuccess(wrapUnique(backend), IDBDatabaseMetadata(metadata)); | 139 InspectorInstrumentation::AsyncTask asyncTask( |
| 140 m_request->getExecutionContext(), this); | |
| 141 m_request->onSuccess(std::move(db), IDBDatabaseMetadata(metadata)); | |
| 142 } else if (db) { | |
| 143 db->close(); | |
| 144 } | |
| 104 } | 145 } |
| 105 | 146 |
| 106 void WebIDBCallbacksImpl::onSuccess(const WebIDBKey& key) { | 147 void WebIDBCallbacksImpl::onSuccess(const WebIDBKey& key) { |
| 148 if (!m_request) | |
| 149 return; | |
| 150 | |
| 107 InspectorInstrumentation::AsyncTask asyncTask( | 151 InspectorInstrumentation::AsyncTask asyncTask( |
| 108 m_request->getExecutionContext(), this); | 152 m_request->getExecutionContext(), this); |
| 109 m_request->onSuccess(key); | 153 m_request->onSuccess(key); |
| 110 } | 154 } |
| 111 | 155 |
| 112 void WebIDBCallbacksImpl::onSuccess(const WebIDBValue& value) { | 156 void WebIDBCallbacksImpl::onSuccess(const WebIDBValue& value) { |
| 157 if (!m_request) | |
| 158 return; | |
| 159 | |
| 113 InspectorInstrumentation::AsyncTask asyncTask( | 160 InspectorInstrumentation::AsyncTask asyncTask( |
| 114 m_request->getExecutionContext(), this); | 161 m_request->getExecutionContext(), this); |
| 115 m_request->onSuccess(IDBValue::create(value)); | 162 m_request->onSuccess(IDBValue::create(value)); |
| 116 } | 163 } |
| 117 | 164 |
| 118 void WebIDBCallbacksImpl::onSuccess(const WebVector<WebIDBValue>& values) { | 165 void WebIDBCallbacksImpl::onSuccess(const WebVector<WebIDBValue>& values) { |
| 166 if (!m_request) | |
| 167 return; | |
| 168 | |
| 119 InspectorInstrumentation::AsyncTask asyncTask( | 169 InspectorInstrumentation::AsyncTask asyncTask( |
| 120 m_request->getExecutionContext(), this); | 170 m_request->getExecutionContext(), this); |
| 121 Vector<RefPtr<IDBValue>> idbValues(values.size()); | 171 Vector<RefPtr<IDBValue>> idbValues(values.size()); |
| 122 for (size_t i = 0; i < values.size(); ++i) | 172 for (size_t i = 0; i < values.size(); ++i) |
| 123 idbValues[i] = IDBValue::create(values[i]); | 173 idbValues[i] = IDBValue::create(values[i]); |
| 124 m_request->onSuccess(idbValues); | 174 m_request->onSuccess(idbValues); |
| 125 } | 175 } |
| 126 | 176 |
| 127 void WebIDBCallbacksImpl::onSuccess(long long value) { | 177 void WebIDBCallbacksImpl::onSuccess(long long value) { |
| 178 if (!m_request) | |
| 179 return; | |
| 180 | |
| 128 InspectorInstrumentation::AsyncTask asyncTask( | 181 InspectorInstrumentation::AsyncTask asyncTask( |
| 129 m_request->getExecutionContext(), this); | 182 m_request->getExecutionContext(), this); |
| 130 m_request->onSuccess(value); | 183 m_request->onSuccess(value); |
| 131 } | 184 } |
| 132 | 185 |
| 133 void WebIDBCallbacksImpl::onSuccess() { | 186 void WebIDBCallbacksImpl::onSuccess() { |
| 187 if (!m_request) | |
| 188 return; | |
| 189 | |
| 134 InspectorInstrumentation::AsyncTask asyncTask( | 190 InspectorInstrumentation::AsyncTask asyncTask( |
| 135 m_request->getExecutionContext(), this); | 191 m_request->getExecutionContext(), this); |
| 136 m_request->onSuccess(); | 192 m_request->onSuccess(); |
| 137 } | 193 } |
| 138 | 194 |
| 139 void WebIDBCallbacksImpl::onSuccess(const WebIDBKey& key, | 195 void WebIDBCallbacksImpl::onSuccess(const WebIDBKey& key, |
| 140 const WebIDBKey& primaryKey, | 196 const WebIDBKey& primaryKey, |
| 141 const WebIDBValue& value) { | 197 const WebIDBValue& value) { |
| 198 if (!m_request) | |
| 199 return; | |
| 200 | |
| 142 InspectorInstrumentation::AsyncTask asyncTask( | 201 InspectorInstrumentation::AsyncTask asyncTask( |
| 143 m_request->getExecutionContext(), this); | 202 m_request->getExecutionContext(), this); |
| 144 m_request->onSuccess(key, primaryKey, IDBValue::create(value)); | 203 m_request->onSuccess(key, primaryKey, IDBValue::create(value)); |
| 145 } | 204 } |
| 146 | 205 |
| 147 void WebIDBCallbacksImpl::onBlocked(long long oldVersion) { | 206 void WebIDBCallbacksImpl::onBlocked(long long oldVersion) { |
| 207 if (!m_request) | |
| 208 return; | |
| 209 | |
| 148 InspectorInstrumentation::AsyncTask asyncTask( | 210 InspectorInstrumentation::AsyncTask asyncTask( |
| 149 m_request->getExecutionContext(), this); | 211 m_request->getExecutionContext(), this); |
| 150 m_request->onBlocked(oldVersion); | 212 m_request->onBlocked(oldVersion); |
| 151 } | 213 } |
| 152 | 214 |
| 153 void WebIDBCallbacksImpl::onUpgradeNeeded(long long oldVersion, | 215 void WebIDBCallbacksImpl::onUpgradeNeeded(long long oldVersion, |
| 154 WebIDBDatabase* database, | 216 WebIDBDatabase* database, |
| 155 const WebIDBMetadata& metadata, | 217 const WebIDBMetadata& metadata, |
| 156 unsigned short dataLoss, | 218 unsigned short dataLoss, |
| 157 WebString dataLossMessage) { | 219 WebString dataLossMessage) { |
| 158 InspectorInstrumentation::AsyncTask asyncTask( | 220 std::unique_ptr<WebIDBDatabase> db = wrapUnique(database); |
| 159 m_request->getExecutionContext(), this); | 221 if (m_request) { |
| 160 m_request->onUpgradeNeeded( | 222 InspectorInstrumentation::AsyncTask asyncTask( |
| 161 oldVersion, wrapUnique(database), IDBDatabaseMetadata(metadata), | 223 m_request->getExecutionContext(), this); |
| 162 static_cast<WebIDBDataLoss>(dataLoss), dataLossMessage); | 224 m_request->onUpgradeNeeded( |
| 225 oldVersion, std::move(db), IDBDatabaseMetadata(metadata), | |
| 226 static_cast<WebIDBDataLoss>(dataLoss), dataLossMessage); | |
| 227 } else { | |
| 228 db->close(); | |
| 229 } | |
| 230 } | |
| 231 | |
| 232 void WebIDBCallbacksImpl::detach() { | |
| 233 m_request.clear(); | |
| 163 } | 234 } |
| 164 | 235 |
| 165 } // namespace blink | 236 } // namespace blink |
| OLD | NEW |