| Index: third_party/WebKit/Source/modules/indexeddb/WebIDBDatabaseCallbacksImpl.cpp
|
| diff --git a/third_party/WebKit/Source/modules/indexeddb/WebIDBDatabaseCallbacksImpl.cpp b/third_party/WebKit/Source/modules/indexeddb/WebIDBDatabaseCallbacksImpl.cpp
|
| index 4b6b8e87603ccf4e2b756924583d64539efe6c18..55dfd32ff01e2e88bcfc03c9c451a43c32512b2e 100644
|
| --- a/third_party/WebKit/Source/modules/indexeddb/WebIDBDatabaseCallbacksImpl.cpp
|
| +++ b/third_party/WebKit/Source/modules/indexeddb/WebIDBDatabaseCallbacksImpl.cpp
|
| @@ -27,10 +27,22 @@
|
|
|
| #include "core/dom/DOMException.h"
|
| #include "wtf/PtrUtil.h"
|
| +#include "wtf/ThreadSpecific.h"
|
| #include <memory>
|
|
|
| namespace blink {
|
|
|
| +// This thread-specific list keeps track of instances of
|
| +// WebIDBDatabaseCallbacksImpl 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.
|
| +using CallbacksList = std::vector<std::unique_ptr<WebIDBDatabaseCallbacksImpl>>;
|
| +static ThreadSpecific<CallbacksList>& outstandingCallbacks() {
|
| + DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<CallbacksList>, callbacks,
|
| + new ThreadSpecific<CallbacksList>);
|
| + return callbacks;
|
| +}
|
| +
|
| // static
|
| std::unique_ptr<WebIDBDatabaseCallbacksImpl>
|
| WebIDBDatabaseCallbacksImpl::create(IDBDatabaseCallbacks* callbacks) {
|
| @@ -39,27 +51,52 @@ WebIDBDatabaseCallbacksImpl::create(IDBDatabaseCallbacks* callbacks) {
|
|
|
| WebIDBDatabaseCallbacksImpl::WebIDBDatabaseCallbacksImpl(
|
| IDBDatabaseCallbacks* callbacks)
|
| - : m_callbacks(callbacks) {}
|
| + : m_callbacks(callbacks) {
|
| + outstandingCallbacks()->push_back(wrapUnique(this));
|
| +}
|
|
|
| -WebIDBDatabaseCallbacksImpl::~WebIDBDatabaseCallbacksImpl() {}
|
| +WebIDBDatabaseCallbacksImpl::~WebIDBDatabaseCallbacksImpl() {
|
| + if (m_callbacks)
|
| + m_callbacks->webCallbacksDestroyed();
|
| +
|
| + CallbacksList& callbacks = *outstandingCallbacks();
|
| + auto it = std::find_if(
|
| + callbacks.begin(), callbacks.end(),
|
| + [this](const std::unique_ptr<WebIDBDatabaseCallbacksImpl>& element) {
|
| + return element.get() == this;
|
| + });
|
| + if (it != callbacks.end()) {
|
| + it->release();
|
| + callbacks.erase(it);
|
| + }
|
| +}
|
|
|
| void WebIDBDatabaseCallbacksImpl::onForcedClose() {
|
| - m_callbacks->onForcedClose();
|
| + if (m_callbacks)
|
| + m_callbacks->onForcedClose();
|
| }
|
|
|
| void WebIDBDatabaseCallbacksImpl::onVersionChange(long long oldVersion,
|
| long long newVersion) {
|
| - m_callbacks->onVersionChange(oldVersion, newVersion);
|
| + if (m_callbacks)
|
| + m_callbacks->onVersionChange(oldVersion, newVersion);
|
| }
|
|
|
| void WebIDBDatabaseCallbacksImpl::onAbort(long long transactionId,
|
| const WebIDBDatabaseError& error) {
|
| - m_callbacks->onAbort(transactionId,
|
| - DOMException::create(error.code(), error.message()));
|
| + if (m_callbacks) {
|
| + m_callbacks->onAbort(transactionId,
|
| + DOMException::create(error.code(), error.message()));
|
| + }
|
| }
|
|
|
| void WebIDBDatabaseCallbacksImpl::onComplete(long long transactionId) {
|
| - m_callbacks->onComplete(transactionId);
|
| + if (m_callbacks)
|
| + m_callbacks->onComplete(transactionId);
|
| +}
|
| +
|
| +void WebIDBDatabaseCallbacksImpl::detach() {
|
| + m_callbacks.clear();
|
| }
|
|
|
| } // namespace blink
|
|
|