Chromium Code Reviews| Index: third_party/WebKit/Source/bindings/core/v8/RejectedPromises.cpp |
| diff --git a/third_party/WebKit/Source/bindings/core/v8/RejectedPromises.cpp b/third_party/WebKit/Source/bindings/core/v8/RejectedPromises.cpp |
| index 3ed8d247ee5d1659fbe25554de1e4a079984cff1..e88c277eb7a4b4a7eebe4782af8811efe5afd822 100644 |
| --- a/third_party/WebKit/Source/bindings/core/v8/RejectedPromises.cpp |
| +++ b/third_party/WebKit/Source/bindings/core/v8/RejectedPromises.cpp |
| @@ -15,6 +15,12 @@ |
| #include "core/inspector/ConsoleMessage.h" |
| #include "core/inspector/ScriptArguments.h" |
| #include "platform/RuntimeEnabledFeatures.h" |
| +#include "platform/Task.h" |
| +#include "public/platform/Platform.h" |
| +#include "public/platform/WebScheduler.h" |
| +#include "public/platform/WebTaskRunner.h" |
| +#include "public/platform/WebThread.h" |
| +#include "wtf/Functional.h" |
| namespace blink { |
| @@ -59,7 +65,7 @@ public: |
| // Either collected or https://crbug.com/450330 |
| if (value.IsEmpty() || !value->IsPromise()) |
| return; |
| - ASSERT(!v8::Local<v8::Promise>::Cast(value)->HasHandler()); |
| + ASSERT(!hasHandler()); |
| EventTarget* target = executionContext->errorEventTarget(); |
| if (RuntimeEnabledFeatures::promiseRejectionEventEnabled() && target) { |
| @@ -124,6 +130,27 @@ public: |
| } |
| } |
| + void makePromiseWeak() |
| + { |
| + ASSERT(!m_promise.isEmpty() && !m_promise.isWeak()); |
| + m_promise.setWeak(this, &Message::didCollectPromise); |
| + } |
| + |
| + void makePromiseStrong() |
| + { |
| + ASSERT(!m_promise.isEmpty() && m_promise.isWeak()); |
| + m_promise.clearWeak(); |
| + } |
| + |
| + bool hasHandler() |
| + { |
| + if (isCollected()) |
| + return false; |
| + ScriptState::Scope scope(m_scriptState); |
| + v8::Local<v8::Value> value = m_promise.newLocal(m_scriptState->isolate()); |
| + return v8::Local<v8::Promise>::Cast(value)->HasHandler(); |
| + } |
| + |
| private: |
| Message(ScriptState* scriptState, v8::Local<v8::Promise> promise, const ScriptValue& exception, const String& errorMessage, const String& resourceName, int scriptId, int lineNumber, int columnNumber, PassRefPtrWillBeRawPtr<ScriptCallStack> callStack) |
| : m_scriptState(scriptState) |
| @@ -139,7 +166,6 @@ private: |
| , m_collected(false) |
| , m_shouldLogToConsole(true) |
| { |
| - m_promise.setWeak(this, &Message::didCollectPromise); |
| } |
| static void didCollectPromise(const v8::WeakCallbackInfo<Message>& data) |
| @@ -193,7 +219,8 @@ void RejectedPromises::handlerAdded(v8::PromiseRejectMessage data) |
| for (size_t i = 0; i < m_reportedAsErrors.size(); ++i) { |
| auto& message = m_reportedAsErrors.at(i); |
| if (!message->isCollected() && message->hasPromise(data.GetPromise())) { |
| - message->revoke(); |
| + message->makePromiseStrong(); |
| + Platform::current()->currentThread()->scheduler()->timerTaskRunner()->postTask(FROM_HERE, new Task(bind(&RejectedPromises::revokeNow, this, message.release()))); |
| m_reportedAsErrors.remove(i); |
| return; |
| } |
| @@ -202,11 +229,24 @@ void RejectedPromises::handlerAdded(v8::PromiseRejectMessage data) |
| void RejectedPromises::dispose() |
| { |
| - processQueue(); |
| + if (!m_queue.isEmpty()) { |
| + OwnPtrWillBeRawPtr<WillBeHeapDeque<OwnPtrWillBeMember<Message>>> queue = adoptPtr(new WillBeHeapDeque<OwnPtrWillBeMember<Message>>()); |
| + queue->swap(m_queue); |
| + processQueueNow(queue.release()); |
| + } |
| } |
| void RejectedPromises::processQueue() |
| { |
| + if (m_queue.isEmpty()) |
| + return; |
| + OwnPtrWillBeRawPtr<WillBeHeapDeque<OwnPtrWillBeMember<Message>>> queue = adoptPtr(new WillBeHeapDeque<OwnPtrWillBeMember<Message>>()); |
| + queue->swap(m_queue); |
| + Platform::current()->currentThread()->scheduler()->timerTaskRunner()->postTask(FROM_HERE, new Task(bind(&RejectedPromises::processQueueNow, this, queue.release()))); |
|
sof
2015/10/04 20:06:21
To have the closure retain a RefPtr<> to the Rejec
|
| +} |
| + |
| +void RejectedPromises::processQueueNow(PassOwnPtrWillBeRawPtr<WillBeHeapDeque<OwnPtrWillBeMember<Message>>> queue) |
| +{ |
| // Remove collected handlers. |
| for (size_t i = 0; i < m_reportedAsErrors.size();) { |
| if (m_reportedAsErrors.at(i)->isCollected()) |
| @@ -215,16 +255,21 @@ void RejectedPromises::processQueue() |
| ++i; |
| } |
| - while (!m_queue.isEmpty()) { |
| - OwnPtrWillBeRawPtr<Message> message = m_queue.takeFirst(); |
| - if (message->isCollected()) |
| - continue; |
| - |
| - message->report(); |
| - m_reportedAsErrors.append(message.release()); |
| - if (m_reportedAsErrors.size() > maxReportedHandlersPendingResolution) |
| - m_reportedAsErrors.remove(0, maxReportedHandlersPendingResolution / 10); |
| + while (!queue->isEmpty()) { |
| + OwnPtrWillBeRawPtr<Message> message = queue->takeFirst(); |
| + if (!message->hasHandler()) { |
| + message->report(); |
| + message->makePromiseWeak(); |
| + m_reportedAsErrors.append(message.release()); |
| + if (m_reportedAsErrors.size() > maxReportedHandlersPendingResolution) |
| + m_reportedAsErrors.remove(0, maxReportedHandlersPendingResolution / 10); |
| + } |
| } |
| } |
| +void RejectedPromises::revokeNow(PassOwnPtrWillBeRawPtr<Message> message) |
| +{ |
| + message->revoke(); |
| +} |
| + |
| } // namespace blink |