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>>; |
| 63 static ThreadSpecific<CallbacksList>& outstandingCallbacks() { |
| 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(), |
| 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 |