blob: 129a190f6969e41815f1454aaf41883ed0f24bf9 [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "bindings/core/v8/ScriptPromiseResolver.h"
#include "core/inspector/InspectorInstrumentation.h"
namespace blink {
ScriptPromiseResolver::ScriptPromiseResolver(ScriptState* scriptState)
: ActiveDOMObject(scriptState->getExecutionContext()),
m_state(Pending),
m_scriptState(scriptState),
m_timer(this, &ScriptPromiseResolver::onTimerFired),
m_resolver(scriptState)
#if ENABLE(ASSERT)
,
m_isPromiseCalled(false)
#endif
{
if (getExecutionContext()->activeDOMObjectsAreStopped()) {
m_state = Detached;
m_resolver.clear();
}
InspectorInstrumentation::asyncTaskScheduled(getExecutionContext(), "Promise",
this);
}
void ScriptPromiseResolver::suspend() {
m_timer.stop();
}
void ScriptPromiseResolver::resume() {
if (m_state == Resolving || m_state == Rejecting)
m_timer.startOneShot(0, BLINK_FROM_HERE);
}
void ScriptPromiseResolver::detach() {
if (m_state == Detached)
return;
m_timer.stop();
m_state = Detached;
m_resolver.clear();
m_value.clear();
m_keepAlive.clear();
InspectorInstrumentation::asyncTaskCanceled(getExecutionContext(), this);
}
void ScriptPromiseResolver::keepAliveWhilePending() {
// keepAliveWhilePending() will be called twice if the resolver
// is created in a suspended execution context and the resolver
// is then resolved/rejected while in that suspended state.
if (m_state == Detached || m_keepAlive)
return;
// Keep |this| around while the promise is Pending;
// see detach() for the dual operation.
m_keepAlive = this;
}
void ScriptPromiseResolver::onTimerFired(TimerBase*) {
ASSERT(m_state == Resolving || m_state == Rejecting);
if (!getScriptState()->contextIsValid()) {
detach();
return;
}
ScriptState::Scope scope(m_scriptState.get());
resolveOrRejectImmediately();
}
void ScriptPromiseResolver::resolveOrRejectImmediately() {
ASSERT(!getExecutionContext()->activeDOMObjectsAreStopped());
ASSERT(!getExecutionContext()->activeDOMObjectsAreSuspended());
{
InspectorInstrumentation::AsyncTask asyncTask(getExecutionContext(), this);
if (m_state == Resolving) {
m_resolver.resolve(m_value.newLocal(m_scriptState->isolate()));
} else {
ASSERT(m_state == Rejecting);
m_resolver.reject(m_value.newLocal(m_scriptState->isolate()));
}
}
detach();
}
DEFINE_TRACE(ScriptPromiseResolver) {
ActiveDOMObject::trace(visitor);
}
} // namespace blink