| Index: android_webview/renderer/aw_execution_termination_filter.cc
|
| diff --git a/android_webview/renderer/aw_execution_termination_filter.cc b/android_webview/renderer/aw_execution_termination_filter.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..75f130dbcb07e71cfad1f4c0564202034af53e87
|
| --- /dev/null
|
| +++ b/android_webview/renderer/aw_execution_termination_filter.cc
|
| @@ -0,0 +1,76 @@
|
| +// 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 "android_webview/renderer/aw_execution_termination_filter.h"
|
| +
|
| +#include <v8.h>
|
| +
|
| +#include "android_webview/common/render_view_messages.h"
|
| +#include "base/message_loop/message_loop_proxy.h"
|
| +
|
| +namespace {
|
| +const int kTerminationTimeoutInSeconds = 3;
|
| +} // namespace
|
| +
|
| +namespace android_webview {
|
| +
|
| +AwExecutionTerminationFilter::AwExecutionTerminationFilter(
|
| + const scoped_refptr<base::MessageLoopProxy>& io_message_loop,
|
| + const scoped_refptr<base::MessageLoopProxy>& main_message_loop)
|
| + : io_message_loop_(io_message_loop),
|
| + main_message_loop_(main_message_loop),
|
| + render_thread_isolate_(NULL) {
|
| +}
|
| +
|
| +AwExecutionTerminationFilter::~AwExecutionTerminationFilter() {
|
| +}
|
| +
|
| +void AwExecutionTerminationFilter::SetRenderThreadIsolate(
|
| + v8::Isolate* isolate) {
|
| + render_thread_isolate_ = isolate;
|
| +}
|
| +
|
| +bool AwExecutionTerminationFilter::OnMessageReceived(
|
| + const IPC::Message& message) {
|
| + bool handled = true;
|
| + IPC_BEGIN_MESSAGE_MAP(AwExecutionTerminationFilter, message)
|
| + IPC_MESSAGE_HANDLER(AwViewMsg_CheckRenderThreadResponsiveness,
|
| + OnCheckRenderThreadResponsiveness)
|
| + IPC_MESSAGE_UNHANDLED(handled = false)
|
| + IPC_END_MESSAGE_MAP()
|
| + return handled;
|
| +}
|
| +
|
| +void AwExecutionTerminationFilter::OnCheckRenderThreadResponsiveness() {
|
| + termination_timer_.Start(
|
| + FROM_HERE,
|
| + base::TimeDelta::FromSeconds(kTerminationTimeoutInSeconds),
|
| + base::Bind(&AwExecutionTerminationFilter::TerminateExecution, this));
|
| + // Post a request to stop the timer via render thread's message loop
|
| + // to ensure that render thread is responsive.
|
| + main_message_loop_->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&AwExecutionTerminationFilter::StopTimerOnMainThread,
|
| + this));
|
| +}
|
| +
|
| +void AwExecutionTerminationFilter::StopTimerOnMainThread() {
|
| + io_message_loop_->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&AwExecutionTerminationFilter::StopTimer, this));
|
| +}
|
| +
|
| +void AwExecutionTerminationFilter::StopTimer() {
|
| + termination_timer_.Stop();
|
| +}
|
| +
|
| +void AwExecutionTerminationFilter::TerminateExecution() {
|
| + if (render_thread_isolate_) {
|
| + LOG(WARNING) << "Trying to terminate JavaScript execution because "
|
| + "renderer is unresponsive";
|
| + v8::V8::TerminateExecution(render_thread_isolate_);
|
| + }
|
| +}
|
| +
|
| +} // namespace android_webview
|
|
|