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 |