| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "bindings/core/v8/ScriptPromiseResolver.h" | 5 #include "bindings/core/v8/ScriptPromiseResolver.h" |
| 6 | 6 |
| 7 #include "core/dom/TaskRunnerHelper.h" | 7 #include "core/dom/TaskRunnerHelper.h" |
| 8 #include "core/inspector/InspectorInstrumentation.h" | 8 #include "core/inspector/InspectorInstrumentation.h" |
| 9 | 9 |
| 10 namespace blink { | 10 namespace blink { |
| 11 | 11 |
| 12 ScriptPromiseResolver::ScriptPromiseResolver(ScriptState* scriptState) | 12 ScriptPromiseResolver::ScriptPromiseResolver(ScriptState* scriptState) |
| 13 : SuspendableObject(scriptState->getExecutionContext()), | 13 : SuspendableObject(scriptState->getExecutionContext()), |
| 14 m_state(Pending), | 14 m_state(Pending), |
| 15 m_scriptState(scriptState), | 15 m_scriptState(scriptState), |
| 16 m_timer(TaskRunnerHelper::get(TaskType::Microtask, getExecutionContext()), | 16 m_timer(TaskRunnerHelper::get(TaskType::Microtask, getExecutionContext()), |
| 17 this, | 17 this, |
| 18 &ScriptPromiseResolver::onTimerFired), | 18 &ScriptPromiseResolver::onTimerFired), |
| 19 m_resolver(scriptState) | 19 m_resolver(scriptState) |
| 20 { | 20 { |
| 21 if (getExecutionContext()->isContextDestroyed()) { | 21 if (getExecutionContext()->isContextDestroyed()) { |
| 22 m_state = Detached; | 22 m_state = Detached; |
| 23 m_resolver.clear(); | 23 m_resolver.clear(); |
| 24 } | 24 } |
| 25 InspectorInstrumentation::asyncTaskScheduled(getExecutionContext(), "Promise", | 25 probe::asyncTaskScheduled(getExecutionContext(), "Promise", this); |
| 26 this); | |
| 27 } | 26 } |
| 28 | 27 |
| 29 void ScriptPromiseResolver::suspend() { | 28 void ScriptPromiseResolver::suspend() { |
| 30 m_timer.stop(); | 29 m_timer.stop(); |
| 31 } | 30 } |
| 32 | 31 |
| 33 void ScriptPromiseResolver::resume() { | 32 void ScriptPromiseResolver::resume() { |
| 34 if (m_state == Resolving || m_state == Rejecting) | 33 if (m_state == Resolving || m_state == Rejecting) |
| 35 m_timer.startOneShot(0, BLINK_FROM_HERE); | 34 m_timer.startOneShot(0, BLINK_FROM_HERE); |
| 36 } | 35 } |
| 37 | 36 |
| 38 void ScriptPromiseResolver::detach() { | 37 void ScriptPromiseResolver::detach() { |
| 39 if (m_state == Detached) | 38 if (m_state == Detached) |
| 40 return; | 39 return; |
| 41 m_timer.stop(); | 40 m_timer.stop(); |
| 42 m_state = Detached; | 41 m_state = Detached; |
| 43 m_resolver.clear(); | 42 m_resolver.clear(); |
| 44 m_value.clear(); | 43 m_value.clear(); |
| 45 m_keepAlive.clear(); | 44 m_keepAlive.clear(); |
| 46 InspectorInstrumentation::asyncTaskCanceled(getExecutionContext(), this); | 45 probe::asyncTaskCanceled(getExecutionContext(), this); |
| 47 } | 46 } |
| 48 | 47 |
| 49 void ScriptPromiseResolver::keepAliveWhilePending() { | 48 void ScriptPromiseResolver::keepAliveWhilePending() { |
| 50 // keepAliveWhilePending() will be called twice if the resolver | 49 // keepAliveWhilePending() will be called twice if the resolver |
| 51 // is created in a suspended execution context and the resolver | 50 // is created in a suspended execution context and the resolver |
| 52 // is then resolved/rejected while in that suspended state. | 51 // is then resolved/rejected while in that suspended state. |
| 53 if (m_state == Detached || m_keepAlive) | 52 if (m_state == Detached || m_keepAlive) |
| 54 return; | 53 return; |
| 55 | 54 |
| 56 // Keep |this| around while the promise is Pending; | 55 // Keep |this| around while the promise is Pending; |
| 57 // see detach() for the dual operation. | 56 // see detach() for the dual operation. |
| 58 m_keepAlive = this; | 57 m_keepAlive = this; |
| 59 } | 58 } |
| 60 | 59 |
| 61 void ScriptPromiseResolver::onTimerFired(TimerBase*) { | 60 void ScriptPromiseResolver::onTimerFired(TimerBase*) { |
| 62 ASSERT(m_state == Resolving || m_state == Rejecting); | 61 ASSERT(m_state == Resolving || m_state == Rejecting); |
| 63 if (!getScriptState()->contextIsValid()) { | 62 if (!getScriptState()->contextIsValid()) { |
| 64 detach(); | 63 detach(); |
| 65 return; | 64 return; |
| 66 } | 65 } |
| 67 | 66 |
| 68 ScriptState::Scope scope(m_scriptState.get()); | 67 ScriptState::Scope scope(m_scriptState.get()); |
| 69 resolveOrRejectImmediately(); | 68 resolveOrRejectImmediately(); |
| 70 } | 69 } |
| 71 | 70 |
| 72 void ScriptPromiseResolver::resolveOrRejectImmediately() { | 71 void ScriptPromiseResolver::resolveOrRejectImmediately() { |
| 73 DCHECK(!getExecutionContext()->isContextDestroyed()); | 72 DCHECK(!getExecutionContext()->isContextDestroyed()); |
| 74 DCHECK(!getExecutionContext()->isContextSuspended()); | 73 DCHECK(!getExecutionContext()->isContextSuspended()); |
| 75 { | 74 { |
| 76 InspectorInstrumentation::AsyncTask asyncTask(getExecutionContext(), this); | 75 probe::AsyncTask asyncTask(getExecutionContext(), this); |
| 77 if (m_state == Resolving) { | 76 if (m_state == Resolving) { |
| 78 m_resolver.resolve(m_value.newLocal(m_scriptState->isolate())); | 77 m_resolver.resolve(m_value.newLocal(m_scriptState->isolate())); |
| 79 } else { | 78 } else { |
| 80 ASSERT(m_state == Rejecting); | 79 ASSERT(m_state == Rejecting); |
| 81 m_resolver.reject(m_value.newLocal(m_scriptState->isolate())); | 80 m_resolver.reject(m_value.newLocal(m_scriptState->isolate())); |
| 82 } | 81 } |
| 83 } | 82 } |
| 84 detach(); | 83 detach(); |
| 85 } | 84 } |
| 86 | 85 |
| 87 DEFINE_TRACE(ScriptPromiseResolver) { | 86 DEFINE_TRACE(ScriptPromiseResolver) { |
| 88 SuspendableObject::trace(visitor); | 87 SuspendableObject::trace(visitor); |
| 89 } | 88 } |
| 90 | 89 |
| 91 } // namespace blink | 90 } // namespace blink |
| OLD | NEW |