History

Make script cache thread safe

Brad Davis committed 10 years ago

Commit ee017cf1 parent f97e61e2 files · +42 −12Browse files

Showing the changes to libraries/script-engine/src/ScriptCache.cpp (1 of 2 files). Show all

Unified · Split

libraries/script-engine/src/ScriptCache.cpp+37−12
@@ -28,21 +28,26 @@ ScriptCache::ScriptCache(QObject* parent) { · 27 unmodified lines
2828 }
2929
3030 void ScriptCache::clearCache() {
31+ Lock lock(_containerLock);
3132 _scriptCache.clear();
3233 }
3334
3435 QString ScriptCache::getScript(const QUrl& unnormalizedURL, ScriptUser* scriptUser, bool& isPending, bool reload) {
3536 QUrl url = ResourceManager::normalizeURL(unnormalizedURL);
3637 QString scriptContents;
38+
39+ Lock lock(_containerLock);
3740 if (_scriptCache.contains(url) && !reload) {
3841 qCDebug(scriptengine) << "Found script in cache:" << url.toString();
3942 scriptContents = _scriptCache[url];
43+ lock.unlock();
4044 scriptUser->scriptContentsAvailable(url, scriptContents);
4145 isPending = false;
4246 } else {
4347 isPending = true;
4448 bool alreadyWaiting = _scriptUsers.contains(url);
4549 _scriptUsers.insert(url, scriptUser);
50+ lock.unlock();
4651
4752 if (alreadyWaiting) {
4853 qCDebug(scriptengine) << "Already downloading script at:" << url.toString();
@@ -58,6 +63,7 @@ QString ScriptCache::getScript(const QUrl& unnormalizedURL, ScriptUser* scriptUs · 9 unmodified lines
5863
5964 void ScriptCache::deleteScript(const QUrl& unnormalizedURL) {
6065 QUrl url = ResourceManager::normalizeURL(unnormalizedURL);
66+ Lock lock(_containerLock);
6167 if (_scriptCache.contains(url)) {
6268 qCDebug(scriptengine) << "Delete script from cache:" << url.toString();
6369 _scriptCache.remove(url);
@@ -67,17 +73,22 @@ void ScriptCache::deleteScript(const QUrl& unnormalizedURL) { · 3 unmodified lines
6773 void ScriptCache::scriptDownloaded() {
6874 ResourceRequest* req = qobject_cast<ResourceRequest*>(sender());
6975 QUrl url = req->getUrl();
76+
77+ Lock lock(_containerLock);
7078 QList<ScriptUser*> scriptUsers = _scriptUsers.values(url);
7179 _scriptUsers.remove(url);
7280
7381 if (req->getResult() == ResourceRequest::Success) {
74− _scriptCache[url] = req->getData();
82+ auto scriptContents = req->getData();
83+ _scriptCache[url] = scriptContents;
84+ lock.unlock();
7585 qCDebug(scriptengine) << "Done downloading script at:" << url.toString();
7686
7787 foreach(ScriptUser* user, scriptUsers) {
78− user->scriptContentsAvailable(url, _scriptCache[url]);
88+ user->scriptContentsAvailable(url, scriptContents);
7989 }
8090 } else {
91+ lock.unlock();
8192 qCWarning(scriptengine) << "Error loading script from URL " << url;
8293 foreach(ScriptUser* user, scriptUsers) {
8394 user->errorInLoadingScript(url);
@@ -99,15 +110,19 @@ void ScriptCache::getScriptContents(const QString& scriptOrURL, contentAvailable · 15 unmodified lines
99110 return;
100111 }
101112
113+ Lock lock(_containerLock);
102114 if (_scriptCache.contains(url) && !forceDownload) {
115+ auto scriptContent = _scriptCache[url];
116+ lock.unlock();
103117 qCDebug(scriptengine) << "Found script in cache:" << url.toString();
104118 #if 1 // def THREAD_DEBUGGING
105119 qCDebug(scriptengine) << "ScriptCache::getScriptContents() about to call contentAvailable() on thread [" << QThread::currentThread() << "] expected thread [" << thread() << "]";
106120 #endif
107− contentAvailable(url.toString(), _scriptCache[url], true, true);
121+ contentAvailable(url.toString(), scriptContent, true, true);
108122 } else {
109123 bool alreadyWaiting = _contentCallbacks.contains(url);
110124 _contentCallbacks.insert(url, contentAvailable);
125+ lock.unlock();
111126
112127 if (alreadyWaiting) {
113128 qCDebug(scriptengine) << "Already downloading script at:" << url.toString();
@@ -129,19 +144,29 @@ void ScriptCache::scriptContentAvailable() { · 15 unmodified lines
129144 #endif
130145 ResourceRequest* req = qobject_cast<ResourceRequest*>(sender());
131146 QUrl url = req->getUrl();
132− QList<contentAvailableCallback> allCallbacks = _contentCallbacks.values(url);
133− _contentCallbacks.remove(url);
134147
135− bool success = req->getResult() == ResourceRequest::Success;
148+ QString scriptContent;
149+ QList<contentAvailableCallback> allCallbacks;
150+ bool success { false };
136151
137− if (success) {
138− _scriptCache[url] = req->getData();
139− qCDebug(scriptengine) << "Done downloading script at:" << url.toString();
140− } else {
141− qCWarning(scriptengine) << "Error loading script from URL " << url;
152+ {
153+ Lock lock(_containerLock);
154+ allCallbacks = _contentCallbacks.values(url);
155+ _contentCallbacks.remove(url);
156+ success = req->getResult() == ResourceRequest::Success;
157+
158+ if (success) {
159+ _scriptCache[url] = scriptContent = req->getData();
160+ qCDebug(scriptengine) << "Done downloading script at:" << url.toString();
161+ } else {
162+ // Dubious, but retained here because it matches the behavior before fixing the threading
163+ scriptContent = _scriptCache[url];
164+ qCWarning(scriptengine) << "Error loading script from URL " << url;
165+ }
142166 }
167+
143168 foreach(contentAvailableCallback thisCallback, allCallbacks) {
144− thisCallback(url.toString(), _scriptCache[url], true, success);
169+ thisCallback(url.toString(), scriptContent, true, success);
145170 }
146171 req->deleteLater();
147172 }