Commit 0755c943 authored by Alexander Timin's avatar Alexander Timin Committed by Commit Bot

[blink] Use per-frame task runner in AsyncMethodRunner

Posting async tasks to the default timer queue can lead to media tasks
being throttled, which may lead to videos being stopped in background.

R=haraken@chromium.org,hajimehoshi@chromium.org
BUG=779962, 786332

Change-Id: Ic50890f909ed824a9d8048d5ef5af590b3cd086b
Reviewed-on: https://chromium-review.googlesource.com/822931Reviewed-by: default avatarHajime Hoshi <hajimehoshi@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Commit-Queue: Alexander Timin <altimin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#524292}
parent 9ee1f839
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "platform/AsyncMethodRunner.h" #include "platform/AsyncMethodRunner.h"
#include "platform/bindings/ScriptWrappable.h" #include "platform/bindings/ScriptWrappable.h"
#include "platform/fonts/FontSelector.h" #include "platform/fonts/FontSelector.h"
#include "public/platform/TaskType.h"
// Mac OS X 10.6 SDK defines check() macro that interferes with our check() // Mac OS X 10.6 SDK defines check() macro that interferes with our check()
// method // method
...@@ -44,9 +45,11 @@ class CORE_EXPORT FontFaceSet : public EventTargetWithInlineData, ...@@ -44,9 +45,11 @@ class CORE_EXPORT FontFaceSet : public EventTargetWithInlineData,
ready_(new ReadyProperty(GetExecutionContext(), ready_(new ReadyProperty(GetExecutionContext(),
this, this,
ReadyProperty::kReady)), ReadyProperty::kReady)),
// TODO(scheduler-dev): Create an internal task type for fonts.
async_runner_(AsyncMethodRunner<FontFaceSet>::Create( async_runner_(AsyncMethodRunner<FontFaceSet>::Create(
this, this,
&FontFaceSet::HandlePendingEventsAndPromises)) {} &FontFaceSet::HandlePendingEventsAndPromises,
context.GetTaskRunner(TaskType::kUnthrottled))) {}
~FontFaceSet() = default; ~FontFaceSet() = default;
DEFINE_ATTRIBUTE_EVENT_LISTENER(loading); DEFINE_ATTRIBUTE_EVENT_LISTENER(loading);
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "modules/gamepad/GamepadDispatcher.h" #include "modules/gamepad/GamepadDispatcher.h"
#include "modules/gamepad/GamepadEvent.h" #include "modules/gamepad/GamepadEvent.h"
#include "modules/gamepad/GamepadList.h" #include "modules/gamepad/GamepadList.h"
#include "public/platform/TaskType.h"
namespace { namespace {
...@@ -173,8 +174,10 @@ void NavigatorGamepad::DispatchOneEvent() { ...@@ -173,8 +174,10 @@ void NavigatorGamepad::DispatchOneEvent() {
DomWindow()->DispatchEvent( DomWindow()->DispatchEvent(
GamepadEvent::Create(event_name, false, true, gamepad)); GamepadEvent::Create(event_name, false, true, gamepad));
if (!pending_events_.IsEmpty()) if (!pending_events_.IsEmpty()) {
DCHECK(dispatch_one_event_runner_);
dispatch_one_event_runner_->RunAsync(); dispatch_one_event_runner_->RunAsync();
}
} }
NavigatorGamepad::NavigatorGamepad(Navigator& navigator) NavigatorGamepad::NavigatorGamepad(Navigator& navigator)
...@@ -182,9 +185,13 @@ NavigatorGamepad::NavigatorGamepad(Navigator& navigator) ...@@ -182,9 +185,13 @@ NavigatorGamepad::NavigatorGamepad(Navigator& navigator)
DOMWindowClient(navigator.DomWindow()), DOMWindowClient(navigator.DomWindow()),
PlatformEventController( PlatformEventController(
navigator.GetFrame() ? navigator.GetFrame()->GetDocument() : nullptr), navigator.GetFrame() ? navigator.GetFrame()->GetDocument() : nullptr),
dispatch_one_event_runner_(AsyncMethodRunner<NavigatorGamepad>::Create( dispatch_one_event_runner_(
navigator.GetFrame() ? AsyncMethodRunner<NavigatorGamepad>::Create(
this, this,
&NavigatorGamepad::DispatchOneEvent)) { &NavigatorGamepad::DispatchOneEvent,
navigator.GetFrame()->GetTaskRunner(
TaskType::kMiscPlatformAPI))
: nullptr) {
if (navigator.DomWindow()) if (navigator.DomWindow())
navigator.DomWindow()->RegisterEventListenerObserver(this); navigator.DomWindow()->RegisterEventListenerObserver(this);
} }
...@@ -197,10 +204,12 @@ const char* NavigatorGamepad::SupplementName() { ...@@ -197,10 +204,12 @@ const char* NavigatorGamepad::SupplementName() {
void NavigatorGamepad::RegisterWithDispatcher() { void NavigatorGamepad::RegisterWithDispatcher() {
GamepadDispatcher::Instance().AddController(this); GamepadDispatcher::Instance().AddController(this);
if (dispatch_one_event_runner_)
dispatch_one_event_runner_->Unpause(); dispatch_one_event_runner_->Unpause();
} }
void NavigatorGamepad::UnregisterWithDispatcher() { void NavigatorGamepad::UnregisterWithDispatcher() {
if (dispatch_one_event_runner_)
dispatch_one_event_runner_->Pause(); dispatch_one_event_runner_->Pause();
GamepadDispatcher::Instance().RemoveController(this); GamepadDispatcher::Instance().RemoveController(this);
} }
...@@ -245,6 +254,7 @@ void NavigatorGamepad::DidRemoveAllEventListeners(LocalDOMWindow*) { ...@@ -245,6 +254,7 @@ void NavigatorGamepad::DidRemoveAllEventListeners(LocalDOMWindow*) {
void NavigatorGamepad::DidRemoveGamepadEventListeners() { void NavigatorGamepad::DidRemoveGamepadEventListeners() {
has_event_listener_ = false; has_event_listener_ = false;
if (dispatch_one_event_runner_)
dispatch_one_event_runner_->Stop(); dispatch_one_event_runner_->Stop();
pending_events_.clear(); pending_events_.clear();
StopUpdating(); StopUpdating();
...@@ -268,9 +278,11 @@ void NavigatorGamepad::SampleAndCheckConnectedGamepads() { ...@@ -268,9 +278,11 @@ void NavigatorGamepad::SampleAndCheckConnectedGamepads() {
// recreate the buffer. // recreate the buffer.
gamepads_ = GamepadList::Create(); gamepads_ = GamepadList::Create();
} }
if (!pending_events_.IsEmpty()) if (!pending_events_.IsEmpty()) {
DCHECK(dispatch_one_event_runner_);
dispatch_one_event_runner_->RunAsync(); dispatch_one_event_runner_->RunAsync();
} }
}
SampleGamepads<Gamepad>(gamepads_.Get()); SampleGamepads<Gamepad>(gamepads_.Get());
} }
} }
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "platform/wtf/PtrUtil.h" #include "platform/wtf/PtrUtil.h"
#include "platform/wtf/Time.h" #include "platform/wtf/Time.h"
#include "public/platform/Platform.h" #include "public/platform/Platform.h"
#include "public/platform/TaskType.h"
#include "public/platform/WebMediaStream.h" #include "public/platform/WebMediaStream.h"
namespace blink { namespace blink {
...@@ -168,9 +169,12 @@ MediaRecorder::MediaRecorder(ExecutionContext* context, ...@@ -168,9 +169,12 @@ MediaRecorder::MediaRecorder(ExecutionContext* context,
audio_bits_per_second_(0), audio_bits_per_second_(0),
video_bits_per_second_(0), video_bits_per_second_(0),
state_(State::kInactive), state_(State::kInactive),
// MediaStream recording should use DOM manipulation task source.
// https://www.w3.org/TR/mediastream-recording/
dispatch_scheduled_event_runner_(AsyncMethodRunner<MediaRecorder>::Create( dispatch_scheduled_event_runner_(AsyncMethodRunner<MediaRecorder>::Create(
this, this,
&MediaRecorder::DispatchScheduledEvent)) { &MediaRecorder::DispatchScheduledEvent,
context->GetTaskRunner(TaskType::kDOMManipulation))) {
DCHECK(stream_->getTracks().size()); DCHECK(stream_->getTracks().size());
recorder_handler_ = Platform::Current()->CreateMediaRecorderHandler(); recorder_handler_ = Platform::Current()->CreateMediaRecorderHandler();
......
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
#include "platform/instrumentation/tracing/TraceEvent.h" #include "platform/instrumentation/tracing/TraceEvent.h"
#include "platform/runtime_enabled_features.h" #include "platform/runtime_enabled_features.h"
#include "platform/wtf/MathExtras.h" #include "platform/wtf/MathExtras.h"
#include "public/platform/TaskType.h"
#include "public/platform/WebSourceBuffer.h" #include "public/platform/WebSourceBuffer.h"
#ifndef BLINK_SBLOG #ifndef BLINK_SBLOG
...@@ -129,12 +130,14 @@ SourceBuffer::SourceBuffer(std::unique_ptr<WebSourceBuffer> web_source_buffer, ...@@ -129,12 +130,14 @@ SourceBuffer::SourceBuffer(std::unique_ptr<WebSourceBuffer> web_source_buffer,
pending_append_data_offset_(0), pending_append_data_offset_(0),
append_buffer_async_part_runner_(AsyncMethodRunner<SourceBuffer>::Create( append_buffer_async_part_runner_(AsyncMethodRunner<SourceBuffer>::Create(
this, this,
&SourceBuffer::AppendBufferAsyncPart)), &SourceBuffer::AppendBufferAsyncPart,
GetExecutionContext()->GetTaskRunner(TaskType::kMediaElementEvent))),
pending_remove_start_(-1), pending_remove_start_(-1),
pending_remove_end_(-1), pending_remove_end_(-1),
remove_async_part_runner_(AsyncMethodRunner<SourceBuffer>::Create( remove_async_part_runner_(AsyncMethodRunner<SourceBuffer>::Create(
this, this,
&SourceBuffer::RemoveAsyncPart)) { &SourceBuffer::RemoveAsyncPart,
GetExecutionContext()->GetTaskRunner(TaskType::kMediaElementEvent))) {
BLINK_SBLOG << __func__ << " this=" << this; BLINK_SBLOG << __func__ << " this=" << this;
DCHECK(web_source_buffer_); DCHECK(web_source_buffer_);
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "modules/mediastream/UserMediaRequest.h" #include "modules/mediastream/UserMediaRequest.h"
#include "platform/bindings/ScriptState.h" #include "platform/bindings/ScriptState.h"
#include "platform/wtf/Functional.h" #include "platform/wtf/Functional.h"
#include "public/platform/TaskType.h"
#include "services/service_manager/public/cpp/interface_provider.h" #include "services/service_manager/public/cpp/interface_provider.h"
using blink::mojom::blink::MediaDeviceType; using blink::mojom::blink::MediaDeviceType;
...@@ -69,9 +70,12 @@ MediaDevices::MediaDevices(ExecutionContext* context) ...@@ -69,9 +70,12 @@ MediaDevices::MediaDevices(ExecutionContext* context)
: PausableObject(context), : PausableObject(context),
observing_(false), observing_(false),
stopped_(false), stopped_(false),
dispatch_scheduled_event_runner_(AsyncMethodRunner<MediaDevices>::Create( dispatch_scheduled_event_runner_(
context ? AsyncMethodRunner<MediaDevices>::Create(
this, this,
&MediaDevices::DispatchScheduledEvent)) {} &MediaDevices::DispatchScheduledEvent,
context->GetTaskRunner(TaskType::kMediaElementEvent))
: nullptr) {}
MediaDevices::~MediaDevices() {} MediaDevices::~MediaDevices() {}
...@@ -191,15 +195,18 @@ void MediaDevices::ContextDestroyed(ExecutionContext*) { ...@@ -191,15 +195,18 @@ void MediaDevices::ContextDestroyed(ExecutionContext*) {
} }
void MediaDevices::Pause() { void MediaDevices::Pause() {
DCHECK(dispatch_scheduled_event_runner_);
dispatch_scheduled_event_runner_->Pause(); dispatch_scheduled_event_runner_->Pause();
} }
void MediaDevices::Unpause() { void MediaDevices::Unpause() {
DCHECK(dispatch_scheduled_event_runner_);
dispatch_scheduled_event_runner_->Unpause(); dispatch_scheduled_event_runner_->Unpause();
} }
void MediaDevices::ScheduleDispatchEvent(Event* event) { void MediaDevices::ScheduleDispatchEvent(Event* event) {
scheduled_events_.push_back(event); scheduled_events_.push_back(event);
DCHECK(dispatch_scheduled_event_runner_);
dispatch_scheduled_event_runner_->RunAsync(); dispatch_scheduled_event_runner_->RunAsync();
} }
......
...@@ -100,6 +100,8 @@ class MODULES_EXPORT MediaDevices final ...@@ -100,6 +100,8 @@ class MODULES_EXPORT MediaDevices final
bool observing_; bool observing_;
bool stopped_; bool stopped_;
// Async runner may be null when there is no valid execution context.
// No async work may be posted in this scenario.
Member<AsyncMethodRunner<MediaDevices>> dispatch_scheduled_event_runner_; Member<AsyncMethodRunner<MediaDevices>> dispatch_scheduled_event_runner_;
HeapVector<Member<Event>> scheduled_events_; HeapVector<Member<Event>> scheduled_events_;
mojom::blink::MediaDevicesDispatcherHostPtr dispatcher_host_; mojom::blink::MediaDevicesDispatcherHostPtr dispatcher_host_;
......
...@@ -164,8 +164,9 @@ void Notification::SchedulePrepareShow() { ...@@ -164,8 +164,9 @@ void Notification::SchedulePrepareShow() {
DCHECK_EQ(state_, State::kLoading); DCHECK_EQ(state_, State::kLoading);
DCHECK(!prepare_show_method_runner_); DCHECK(!prepare_show_method_runner_);
prepare_show_method_runner_ = prepare_show_method_runner_ = AsyncMethodRunner<Notification>::Create(
AsyncMethodRunner<Notification>::Create(this, &Notification::PrepareShow); this, &Notification::PrepareShow,
GetExecutionContext()->GetTaskRunner(TaskType::kMiscPlatformAPI));
prepare_show_method_runner_->RunAsync(); prepare_show_method_runner_->RunAsync();
} }
......
...@@ -91,6 +91,7 @@ ...@@ -91,6 +91,7 @@
#include "platform/wtf/PtrUtil.h" #include "platform/wtf/PtrUtil.h"
#include "platform/wtf/Time.h" #include "platform/wtf/Time.h"
#include "public/platform/Platform.h" #include "public/platform/Platform.h"
#include "public/platform/TaskType.h"
#include "public/platform/WebCryptoAlgorithmParams.h" #include "public/platform/WebCryptoAlgorithmParams.h"
#include "public/platform/WebMediaStream.h" #include "public/platform/WebMediaStream.h"
#include "public/platform/WebRTCAnswerOptions.h" #include "public/platform/WebRTCAnswerOptions.h"
...@@ -492,10 +493,13 @@ RTCPeerConnection::RTCPeerConnection(ExecutionContext* context, ...@@ -492,10 +493,13 @@ RTCPeerConnection::RTCPeerConnection(ExecutionContext* context,
signaling_state_(kSignalingStateStable), signaling_state_(kSignalingStateStable),
ice_gathering_state_(kICEGatheringStateNew), ice_gathering_state_(kICEGatheringStateNew),
ice_connection_state_(kICEConnectionStateNew), ice_connection_state_(kICEConnectionStateNew),
// WebRTC spec specifies kNetworking as task source.
// https://www.w3.org/TR/webrtc/#operation
dispatch_scheduled_event_runner_( dispatch_scheduled_event_runner_(
AsyncMethodRunner<RTCPeerConnection>::Create( AsyncMethodRunner<RTCPeerConnection>::Create(
this, this,
&RTCPeerConnection::DispatchScheduledEvent)), &RTCPeerConnection::DispatchScheduledEvent,
context->GetTaskRunner(TaskType::kNetworking))),
stopped_(false), stopped_(false),
closed_(false), closed_(false),
has_data_channels_(false) { has_data_channels_(false) {
......
...@@ -45,8 +45,10 @@ class AsyncMethodRunner final ...@@ -45,8 +45,10 @@ class AsyncMethodRunner final
public: public:
typedef void (TargetClass::*TargetMethod)(); typedef void (TargetClass::*TargetMethod)();
static AsyncMethodRunner* Create(TargetClass* object, TargetMethod method) { static AsyncMethodRunner* Create(TargetClass* object,
return new AsyncMethodRunner(object, method); TargetMethod method,
scoped_refptr<WebTaskRunner> task_runner) {
return new AsyncMethodRunner(object, method, std::move(task_runner));
} }
~AsyncMethodRunner() {} ~AsyncMethodRunner() {}
...@@ -112,8 +114,12 @@ class AsyncMethodRunner final ...@@ -112,8 +114,12 @@ class AsyncMethodRunner final
void Trace(blink::Visitor* visitor) { visitor->Trace(object_); } void Trace(blink::Visitor* visitor) { visitor->Trace(object_); }
private: private:
AsyncMethodRunner(TargetClass* object, TargetMethod method) AsyncMethodRunner(TargetClass* object,
: timer_(this, &AsyncMethodRunner<TargetClass>::Fired), TargetMethod method,
scoped_refptr<WebTaskRunner> task_runner)
: timer_(std::move(task_runner),
this,
&AsyncMethodRunner<TargetClass>::Fired),
object_(object), object_(object),
method_(method), method_(method),
paused_(false), paused_(false),
...@@ -121,7 +127,7 @@ class AsyncMethodRunner final ...@@ -121,7 +127,7 @@ class AsyncMethodRunner final
void Fired(TimerBase*) { (object_->*method_)(); } void Fired(TimerBase*) { (object_->*method_)(); }
Timer<AsyncMethodRunner<TargetClass>> timer_; TaskRunnerTimer<AsyncMethodRunner<TargetClass>> timer_;
Member<TargetClass> object_; Member<TargetClass> object_;
TargetMethod method_; TargetMethod method_;
......
...@@ -46,7 +46,6 @@ TimerBase::TimerBase(scoped_refptr<WebTaskRunner> web_task_runner) ...@@ -46,7 +46,6 @@ TimerBase::TimerBase(scoped_refptr<WebTaskRunner> web_task_runner)
thread_(CurrentThread()), thread_(CurrentThread()),
#endif #endif
weak_ptr_factory_(this) { weak_ptr_factory_(this) {
DCHECK(web_task_runner_);
} }
TimerBase::~TimerBase() { TimerBase::~TimerBase() {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment