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 typedef std::vector<std::unique_ptr<WebIDBCallbacksImpl>> CallbacksList; |
| 63 static ThreadSpecific<CallbacksList>& outstandingCallbacks() |
| 64 { |
| 65 DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<CallbacksList>, callbacks, ne
w ThreadSpecific<CallbacksList>); |
| 66 return callbacks; |
| 67 } |
| 68 |
57 // static | 69 // static |
58 std::unique_ptr<WebIDBCallbacksImpl> WebIDBCallbacksImpl::create(IDBRequest* req
uest) | 70 std::unique_ptr<WebIDBCallbacksImpl> WebIDBCallbacksImpl::create(IDBRequest* req
uest) |
59 { | 71 { |
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 { | 77 { |
66 InspectorInstrumentation::asyncTaskScheduled(m_request->getExecutionContext(
), IndexedDBNames::IndexedDB, this, true); | 78 InspectorInstrumentation::asyncTaskScheduled(m_request->getExecutionContext(
), IndexedDBNames::IndexedDB, this, true); |
| 79 outstandingCallbacks()->push_back(wrapUnique(this)); |
67 } | 80 } |
68 | 81 |
69 WebIDBCallbacksImpl::~WebIDBCallbacksImpl() | 82 WebIDBCallbacksImpl::~WebIDBCallbacksImpl() |
70 { | 83 { |
71 InspectorInstrumentation::asyncTaskCanceled(m_request->getExecutionContext()
, this); | 84 if (m_request) { |
| 85 InspectorInstrumentation::asyncTaskCanceled(m_request->getExecutionConte
xt(), this); |
| 86 m_request->webCallbacksDestroyed(); |
| 87 } |
| 88 |
| 89 CallbacksList& callbacks = *outstandingCallbacks(); |
| 90 auto it = std::find_if( |
| 91 callbacks.begin(), callbacks.end(), |
| 92 [this](const std::unique_ptr<WebIDBCallbacksImpl>& element) |
| 93 { |
| 94 return element.get() == this; |
| 95 }); |
| 96 if (it != callbacks.end()) { |
| 97 it->release(); |
| 98 callbacks.erase(it); |
| 99 } |
72 } | 100 } |
73 | 101 |
74 void WebIDBCallbacksImpl::onError(const WebIDBDatabaseError& error) | 102 void WebIDBCallbacksImpl::onError(const WebIDBDatabaseError& error) |
75 { | 103 { |
76 InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionContext
(), this); | 104 if (m_request) { |
77 m_request->onError(DOMException::create(error.code(), error.message())); | 105 InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionCon
text(), this); |
| 106 m_request->onError(DOMException::create(error.code(), error.message())); |
| 107 } |
78 } | 108 } |
79 | 109 |
80 void WebIDBCallbacksImpl::onSuccess(const WebVector<WebString>& webStringList) | 110 void WebIDBCallbacksImpl::onSuccess(const WebVector<WebString>& webStringList) |
81 { | 111 { |
82 Vector<String> stringList; | 112 if (m_request) { |
83 for (size_t i = 0; i < webStringList.size(); ++i) | 113 Vector<String> stringList; |
84 stringList.append(webStringList[i]); | 114 for (size_t i = 0; i < webStringList.size(); ++i) |
85 InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionContext
(), this); | 115 stringList.append(webStringList[i]); |
86 m_request->onSuccess(stringList); | 116 InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionCon
text(), this); |
| 117 m_request->onSuccess(stringList); |
| 118 } |
87 } | 119 } |
88 | 120 |
89 void WebIDBCallbacksImpl::onSuccess(WebIDBCursor* cursor, const WebIDBKey& key,
const WebIDBKey& primaryKey, const WebIDBValue& value) | 121 void WebIDBCallbacksImpl::onSuccess(WebIDBCursor* cursor, const WebIDBKey& key,
const WebIDBKey& primaryKey, const WebIDBValue& value) |
90 { | 122 { |
91 InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionContext
(), this); | 123 if (m_request) { |
92 m_request->onSuccess(wrapUnique(cursor), key, primaryKey, IDBValue::create(v
alue)); | 124 InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionCon
text(), this); |
| 125 m_request->onSuccess(wrapUnique(cursor), key, primaryKey, IDBValue::crea
te(value)); |
| 126 } |
93 } | 127 } |
94 | 128 |
95 void WebIDBCallbacksImpl::onSuccess(WebIDBDatabase* backend, const WebIDBMetadat
a& metadata) | 129 void WebIDBCallbacksImpl::onSuccess(WebIDBDatabase* backend, const WebIDBMetadat
a& metadata) |
96 { | 130 { |
97 InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionContext
(), this); | 131 std::unique_ptr<WebIDBDatabase> db = wrapUnique(backend); |
98 m_request->onSuccess(wrapUnique(backend), IDBDatabaseMetadata(metadata)); | 132 if (m_request) { |
| 133 InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionCon
text(), this); |
| 134 m_request->onSuccess(std::move(db), IDBDatabaseMetadata(metadata)); |
| 135 } else { |
| 136 db->close(); |
| 137 } |
99 } | 138 } |
100 | 139 |
101 void WebIDBCallbacksImpl::onSuccess(const WebIDBKey& key) | 140 void WebIDBCallbacksImpl::onSuccess(const WebIDBKey& key) |
102 { | 141 { |
103 InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionContext
(), this); | 142 if (m_request) { |
104 m_request->onSuccess(key); | 143 InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionCon
text(), this); |
| 144 m_request->onSuccess(key); |
| 145 } |
105 } | 146 } |
106 | 147 |
107 void WebIDBCallbacksImpl::onSuccess(const WebIDBValue& value) | 148 void WebIDBCallbacksImpl::onSuccess(const WebIDBValue& value) |
108 { | 149 { |
109 InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionContext
(), this); | 150 if (m_request) { |
110 m_request->onSuccess(IDBValue::create(value)); | 151 InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionCon
text(), this); |
| 152 m_request->onSuccess(IDBValue::create(value)); |
| 153 } |
111 } | 154 } |
112 | 155 |
113 void WebIDBCallbacksImpl::onSuccess(const WebVector<WebIDBValue>& values) | 156 void WebIDBCallbacksImpl::onSuccess(const WebVector<WebIDBValue>& values) |
114 { | 157 { |
115 InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionContext
(), this); | 158 if (m_request) { |
116 Vector<RefPtr<IDBValue>> idbValues(values.size()); | 159 InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionCon
text(), this); |
117 for (size_t i = 0; i < values.size(); ++i) | 160 Vector<RefPtr<IDBValue>> idbValues(values.size()); |
118 idbValues[i] = IDBValue::create(values[i]); | 161 for (size_t i = 0; i < values.size(); ++i) |
119 m_request->onSuccess(idbValues); | 162 idbValues[i] = IDBValue::create(values[i]); |
| 163 m_request->onSuccess(idbValues); |
| 164 } |
120 } | 165 } |
121 | 166 |
122 void WebIDBCallbacksImpl::onSuccess(long long value) | 167 void WebIDBCallbacksImpl::onSuccess(long long value) |
123 { | 168 { |
124 InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionContext
(), this); | 169 if (m_request) { |
125 m_request->onSuccess(value); | 170 InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionCon
text(), this); |
| 171 m_request->onSuccess(value); |
| 172 } |
126 } | 173 } |
127 | 174 |
128 void WebIDBCallbacksImpl::onSuccess() | 175 void WebIDBCallbacksImpl::onSuccess() |
129 { | 176 { |
130 InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionContext
(), this); | 177 if (m_request) { |
131 m_request->onSuccess(); | 178 InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionCon
text(), this); |
| 179 m_request->onSuccess(); |
| 180 } |
132 } | 181 } |
133 | 182 |
134 void WebIDBCallbacksImpl::onSuccess(const WebIDBKey& key, const WebIDBKey& prima
ryKey, const WebIDBValue& value) | 183 void WebIDBCallbacksImpl::onSuccess(const WebIDBKey& key, const WebIDBKey& prima
ryKey, const WebIDBValue& value) |
135 { | 184 { |
136 InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionContext
(), this); | 185 if (m_request) { |
137 m_request->onSuccess(key, primaryKey, IDBValue::create(value)); | 186 InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionCon
text(), this); |
| 187 m_request->onSuccess(key, primaryKey, IDBValue::create(value)); |
| 188 } |
138 } | 189 } |
139 | 190 |
140 void WebIDBCallbacksImpl::onBlocked(long long oldVersion) | 191 void WebIDBCallbacksImpl::onBlocked(long long oldVersion) |
141 { | 192 { |
142 InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionContext
(), this); | 193 if (m_request) { |
143 m_request->onBlocked(oldVersion); | 194 InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionCon
text(), this); |
| 195 m_request->onBlocked(oldVersion); |
| 196 } |
144 } | 197 } |
145 | 198 |
146 void WebIDBCallbacksImpl::onUpgradeNeeded(long long oldVersion, WebIDBDatabase*
database, const WebIDBMetadata& metadata, unsigned short dataLoss, WebString dat
aLossMessage) | 199 void WebIDBCallbacksImpl::onUpgradeNeeded(long long oldVersion, WebIDBDatabase*
database, const WebIDBMetadata& metadata, unsigned short dataLoss, WebString dat
aLossMessage) |
147 { | 200 { |
148 InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionContext
(), this); | 201 std::unique_ptr<WebIDBDatabase> db = wrapUnique(database); |
149 m_request->onUpgradeNeeded(oldVersion, wrapUnique(database), IDBDatabaseMeta
data(metadata), static_cast<WebIDBDataLoss>(dataLoss), dataLossMessage); | 202 if (m_request) { |
| 203 InspectorInstrumentation::AsyncTask asyncTask(m_request->getExecutionCon
text(), this); |
| 204 m_request->onUpgradeNeeded(oldVersion, std::move(db), IDBDatabaseMetadat
a(metadata), static_cast<WebIDBDataLoss>(dataLoss), dataLossMessage); |
| 205 } else { |
| 206 db->close(); |
| 207 } |
| 208 } |
| 209 |
| 210 void WebIDBCallbacksImpl::detach() |
| 211 { |
| 212 m_request.clear(); |
150 } | 213 } |
151 | 214 |
152 } // namespace blink | 215 } // namespace blink |
OLD | NEW |