Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(27)

Unified Diff: Source/core/workers/WorkerScriptLoader.cpp

Issue 1213443006: Invoke WorkerScriptLoader's m_finishedCallback callback safely. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: review #7 and notify* Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/workers/WorkerScriptLoader.h ('k') | Source/web/WebEmbeddedWorkerImpl.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/workers/WorkerScriptLoader.cpp
diff --git a/Source/core/workers/WorkerScriptLoader.cpp b/Source/core/workers/WorkerScriptLoader.cpp
index 15dee1bffecaf174eb8588d8fefcd8e87308edb9..56db6d6eb858bb719566fc215da83b30ff11fc38 100644
--- a/Source/core/workers/WorkerScriptLoader.cpp
+++ b/Source/core/workers/WorkerScriptLoader.cpp
@@ -47,7 +47,6 @@ WorkerScriptLoader::WorkerScriptLoader()
, m_failed(false)
, m_identifier(0)
, m_appCacheID(0)
- , m_finishing(false)
, m_requestContext(WebURLRequest::RequestContextWorker)
{
}
@@ -95,6 +94,9 @@ void WorkerScriptLoader::loadAsynchronously(ExecutionContext& executionContext,
resourceLoaderOptions.allowCredentials = AllowStoredCredentials;
m_threadableLoader = ThreadableLoader::create(executionContext, this, *request, options, resourceLoaderOptions);
+ if (m_failed)
+ notifyFinished();
+ // Do nothing here since notifyFinished() could delete |this|.
}
const KURL& WorkerScriptLoader::responseURL() const
@@ -115,7 +117,7 @@ void WorkerScriptLoader::didReceiveResponse(unsigned long identifier, const Reso
{
ASSERT_UNUSED(handle, !handle);
if (response.httpStatusCode() / 100 != 2 && response.httpStatusCode()) {
- m_failed = true;
+ notifyError();
return;
}
m_identifier = identifier;
@@ -153,16 +155,10 @@ void WorkerScriptLoader::didReceiveCachedMetadata(const char* data, int size)
void WorkerScriptLoader::didFinishLoading(unsigned long identifier, double)
{
- if (m_failed) {
- notifyError();
- return;
- }
-
- if (m_decoder)
+ if (!m_failed && m_decoder)
m_script.append(m_decoder->flush());
- if (m_finishedCallback)
- (*m_finishedCallback)();
+ notifyFinished();
}
void WorkerScriptLoader::didFail(const ResourceError&)
@@ -175,12 +171,6 @@ void WorkerScriptLoader::didFailRedirectCheck()
notifyError();
}
-void WorkerScriptLoader::notifyError()
-{
- m_failed = true;
- notifyFinished();
-}
-
void WorkerScriptLoader::cancel()
{
if (m_threadableLoader)
@@ -192,14 +182,26 @@ String WorkerScriptLoader::script()
return m_script.toString();
}
+void WorkerScriptLoader::notifyError()
+{
+ m_failed = true;
+ // notifyError() could be called before ThreadableLoader::create() returns
+ // e.g. from didFail(), and in that case m_threadableLoader is not yet set
+ // (i.e. still null).
+ // Since the callback invocation in notifyFinished() potentially delete
+ // |this| object, the callback invocation should be postponed until the
+ // create() call returns. See loadAsynchronously() for the postponed call.
+ if (m_threadableLoader)
+ notifyFinished();
+}
+
void WorkerScriptLoader::notifyFinished()
{
- if (!m_finishedCallback || m_finishing)
+ if (!m_finishedCallback)
return;
- m_finishing = true;
- if (m_finishedCallback)
- (*m_finishedCallback)();
+ OwnPtr<Closure> callback = m_finishedCallback.release();
+ (*callback)();
}
void WorkerScriptLoader::processContentSecurityPolicy(const ResourceResponse& response)
« no previous file with comments | « Source/core/workers/WorkerScriptLoader.h ('k') | Source/web/WebEmbeddedWorkerImpl.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698