| Index: third_party/WebKit/Source/modules/indexeddb/WebIDBCallbacksImpl.cpp
|
| diff --git a/third_party/WebKit/Source/modules/indexeddb/WebIDBCallbacksImpl.cpp b/third_party/WebKit/Source/modules/indexeddb/WebIDBCallbacksImpl.cpp
|
| index f8a3fa44c9e8c17f3da31d21739e7ebb19da4284..bc0c454ebfd1706f81c0bb413b5c33f7478bbf00 100644
|
| --- a/third_party/WebKit/Source/modules/indexeddb/WebIDBCallbacksImpl.cpp
|
| +++ b/third_party/WebKit/Source/modules/indexeddb/WebIDBCallbacksImpl.cpp
|
| @@ -41,6 +41,7 @@
|
| #include "public/platform/modules/indexeddb/WebIDBKey.h"
|
| #include "public/platform/modules/indexeddb/WebIDBValue.h"
|
| #include "wtf/PtrUtil.h"
|
| +#include "wtf/ThreadSpecific.h"
|
| #include <memory>
|
|
|
| using blink::WebIDBCursor;
|
| @@ -54,6 +55,17 @@ using blink::WebVector;
|
|
|
| namespace blink {
|
|
|
| +// This thread-specific list keeps track of instances of WebIDBCallbacksImpl
|
| +// created by each thread. If a thread exits before they are destroyed then they
|
| +// would otherwise be leaked because the IO thread can no longer post a task to
|
| +// the thread on which they were created.
|
| +typedef std::vector<std::unique_ptr<WebIDBCallbacksImpl>> CallbacksList;
|
| +static ThreadSpecific<CallbacksList>& outstandingCallbacks()
|
| +{
|
| + DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<CallbacksList>, callbacks, new ThreadSpecific<CallbacksList>);
|
| + return callbacks;
|
| +}
|
| +
|
| // static
|
| std::unique_ptr<WebIDBCallbacksImpl> WebIDBCallbacksImpl::create(IDBRequest* request)
|
| {
|
| @@ -64,89 +76,140 @@ WebIDBCallbacksImpl::WebIDBCallbacksImpl(IDBRequest* request)
|
| : m_request(request)
|
| {
|
| InspectorInstrumentation::asyncTaskScheduled(m_request->getExecutionContext(), IndexedDBNames::IndexedDB, this, true);
|
| + outstandingCallbacks()->push_back(wrapUnique(this));
|
| }
|
|
|
| WebIDBCallbacksImpl::~WebIDBCallbacksImpl()
|
| {
|
| - InspectorInstrumentation::asyncTaskCanceled(m_request->getExecutionContext(), this);
|
| + if (m_request) {
|
| + InspectorInstrumentation::asyncTaskCanceled(m_request->getExecutionContext(), this);
|
| + m_request->webCallbacksDestroyed();
|
| + }
|
| +
|
| + CallbacksList& callbacks = *outstandingCallbacks();
|
| + auto it = std::find_if(
|
| + callbacks.begin(), callbacks.end(),
|
| + [this](const std::unique_ptr<WebIDBCallbacksImpl>& element)
|
| + {
|
| + return element.get() == this;
|
| + });
|
| + if (it != callbacks.end()) {
|
| + it->release();
|
| + callbacks.erase(it);
|
| + }
|
| }
|
|
|
| void WebIDBCallbacksImpl::onError(const WebIDBDatabaseError& error)
|
| {
|
| - InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionContext(), this);
|
| - m_request->onError(DOMException::create(error.code(), error.message()));
|
| + if (m_request) {
|
| + InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionContext(), this);
|
| + m_request->onError(DOMException::create(error.code(), error.message()));
|
| + }
|
| }
|
|
|
| void WebIDBCallbacksImpl::onSuccess(const WebVector<WebString>& webStringList)
|
| {
|
| - Vector<String> stringList;
|
| - for (size_t i = 0; i < webStringList.size(); ++i)
|
| - stringList.append(webStringList[i]);
|
| - InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionContext(), this);
|
| - m_request->onSuccess(stringList);
|
| + if (m_request) {
|
| + Vector<String> stringList;
|
| + for (size_t i = 0; i < webStringList.size(); ++i)
|
| + stringList.append(webStringList[i]);
|
| + InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionContext(), this);
|
| + m_request->onSuccess(stringList);
|
| + }
|
| }
|
|
|
| void WebIDBCallbacksImpl::onSuccess(WebIDBCursor* cursor, const WebIDBKey& key, const WebIDBKey& primaryKey, const WebIDBValue& value)
|
| {
|
| - InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionContext(), this);
|
| - m_request->onSuccess(wrapUnique(cursor), key, primaryKey, IDBValue::create(value));
|
| + if (m_request) {
|
| + InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionContext(), this);
|
| + m_request->onSuccess(wrapUnique(cursor), key, primaryKey, IDBValue::create(value));
|
| + }
|
| }
|
|
|
| void WebIDBCallbacksImpl::onSuccess(WebIDBDatabase* backend, const WebIDBMetadata& metadata)
|
| {
|
| - InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionContext(), this);
|
| - m_request->onSuccess(wrapUnique(backend), IDBDatabaseMetadata(metadata));
|
| + std::unique_ptr<WebIDBDatabase> db = wrapUnique(backend);
|
| + if (m_request) {
|
| + InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionContext(), this);
|
| + m_request->onSuccess(std::move(db), IDBDatabaseMetadata(metadata));
|
| + } else {
|
| + db->close();
|
| + }
|
| }
|
|
|
| void WebIDBCallbacksImpl::onSuccess(const WebIDBKey& key)
|
| {
|
| - InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionContext(), this);
|
| - m_request->onSuccess(key);
|
| + if (m_request) {
|
| + InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionContext(), this);
|
| + m_request->onSuccess(key);
|
| + }
|
| }
|
|
|
| void WebIDBCallbacksImpl::onSuccess(const WebIDBValue& value)
|
| {
|
| - InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionContext(), this);
|
| - m_request->onSuccess(IDBValue::create(value));
|
| + if (m_request) {
|
| + InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionContext(), this);
|
| + m_request->onSuccess(IDBValue::create(value));
|
| + }
|
| }
|
|
|
| void WebIDBCallbacksImpl::onSuccess(const WebVector<WebIDBValue>& values)
|
| {
|
| - InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionContext(), this);
|
| - Vector<RefPtr<IDBValue>> idbValues(values.size());
|
| - for (size_t i = 0; i < values.size(); ++i)
|
| - idbValues[i] = IDBValue::create(values[i]);
|
| - m_request->onSuccess(idbValues);
|
| + if (m_request) {
|
| + InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionContext(), this);
|
| + Vector<RefPtr<IDBValue>> idbValues(values.size());
|
| + for (size_t i = 0; i < values.size(); ++i)
|
| + idbValues[i] = IDBValue::create(values[i]);
|
| + m_request->onSuccess(idbValues);
|
| + }
|
| }
|
|
|
| void WebIDBCallbacksImpl::onSuccess(long long value)
|
| {
|
| - InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionContext(), this);
|
| - m_request->onSuccess(value);
|
| + if (m_request) {
|
| + InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionContext(), this);
|
| + m_request->onSuccess(value);
|
| + }
|
| }
|
|
|
| void WebIDBCallbacksImpl::onSuccess()
|
| {
|
| - InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionContext(), this);
|
| - m_request->onSuccess();
|
| + if (m_request) {
|
| + InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionContext(), this);
|
| + m_request->onSuccess();
|
| + }
|
| }
|
|
|
| void WebIDBCallbacksImpl::onSuccess(const WebIDBKey& key, const WebIDBKey& primaryKey, const WebIDBValue& value)
|
| {
|
| - InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionContext(), this);
|
| - m_request->onSuccess(key, primaryKey, IDBValue::create(value));
|
| + if (m_request) {
|
| + InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionContext(), this);
|
| + m_request->onSuccess(key, primaryKey, IDBValue::create(value));
|
| + }
|
| }
|
|
|
| void WebIDBCallbacksImpl::onBlocked(long long oldVersion)
|
| {
|
| - InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionContext(), this);
|
| - m_request->onBlocked(oldVersion);
|
| + if (m_request) {
|
| + InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionContext(), this);
|
| + m_request->onBlocked(oldVersion);
|
| + }
|
| }
|
|
|
| void WebIDBCallbacksImpl::onUpgradeNeeded(long long oldVersion, WebIDBDatabase* database, const WebIDBMetadata& metadata, unsigned short dataLoss, WebString dataLossMessage)
|
| {
|
| - InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionContext(), this);
|
| - m_request->onUpgradeNeeded(oldVersion, wrapUnique(database), IDBDatabaseMetadata(metadata), static_cast<WebIDBDataLoss>(dataLoss), dataLossMessage);
|
| + std::unique_ptr<WebIDBDatabase> db = wrapUnique(database);
|
| + if (m_request) {
|
| + InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionContext(), this);
|
| + m_request->onUpgradeNeeded(oldVersion, std::move(db), IDBDatabaseMetadata(metadata), static_cast<WebIDBDataLoss>(dataLoss), dataLossMessage);
|
| + } else {
|
| + db->close();
|
| + }
|
| +}
|
| +
|
| +void WebIDBCallbacksImpl::detach()
|
| +{
|
| + m_request.clear();
|
| }
|
|
|
| } // namespace blink
|
|
|