Commit c2a875c9 authored by Hajime Hoshi's avatar Hajime Hoshi Committed by Commit Bot

Make MediaElementEventQueue and EventQueueImpl inherit ContextLifecycleObserver

When the ExecutionContext is destroyed in an event queue, the event
queue should no longer be available. Then it must delete all the queued
events and close itself.

Design Doc: https://docs.google.com/document/d/1BBtBPTarOF4NeVKSWZe3XaDHo4yTGhdlqYm35yVzPs4/edit#

Bug: 846618
Change-Id: I2de831956238bc2e783e9c8c2eadc56f75f3faaf
Reviewed-on: https://chromium-review.googlesource.com/1088341Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Commit-Queue: Hajime Hoshi <hajimehoshi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#564810}
parent 001f7c4a
......@@ -40,14 +40,16 @@ EventQueueImpl* EventQueueImpl::Create(ExecutionContext* context,
}
EventQueueImpl::EventQueueImpl(ExecutionContext* context, TaskType task_type)
: context_(context), task_type_(task_type), is_closed_(false) {}
: ContextLifecycleObserver(context),
task_type_(task_type),
is_closed_(false) {}
EventQueueImpl::~EventQueueImpl() = default;
void EventQueueImpl::Trace(blink::Visitor* visitor) {
visitor->Trace(context_);
visitor->Trace(queued_events_);
EventQueue::Trace(visitor);
ContextLifecycleObserver::Trace(visitor);
}
bool EventQueueImpl::EnqueueEvent(const base::Location& from_here,
......@@ -55,6 +57,8 @@ bool EventQueueImpl::EnqueueEvent(const base::Location& from_here,
if (is_closed_)
return false;
DCHECK(GetExecutionContext());
DCHECK(event->target());
probe::AsyncTaskScheduled(event->target()->GetExecutionContext(),
event->type(), event);
......@@ -63,7 +67,7 @@ bool EventQueueImpl::EnqueueEvent(const base::Location& from_here,
DCHECK(was_added); // It should not have already been in the list.
scoped_refptr<base::SingleThreadTaskRunner> task_runner =
context_->GetTaskRunner(task_type_);
GetExecutionContext()->GetTaskRunner(task_type_);
// Pass the event as a weak persistent so that GC can collect an event-related
// object like IDBTransaction as soon as possible.
......@@ -107,4 +111,8 @@ void EventQueueImpl::DispatchEvent(Event* event) {
event_target->DispatchEvent(event);
}
void EventQueueImpl::ContextDestroyed(ExecutionContext*) {
Close();
}
} // namespace blink
......@@ -28,6 +28,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_EVENTS_EVENT_QUEUE_IMPL_H_
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/dom/events/event_queue.h"
#include "third_party/blink/renderer/platform/wtf/linked_hash_set.h"
......@@ -36,7 +37,10 @@ namespace blink {
class Event;
class ExecutionContext;
class CORE_EXPORT EventQueueImpl final : public EventQueue {
class CORE_EXPORT EventQueueImpl final : public EventQueue,
public ContextLifecycleObserver {
USING_GARBAGE_COLLECTED_MIXIN(EventQueueImpl);
public:
// TODO(hajimehoshi): TaskType should be determined based on an event instead
// of specifying here.
......@@ -55,7 +59,8 @@ class CORE_EXPORT EventQueueImpl final : public EventQueue {
bool RemoveEvent(Event*);
void DispatchEvent(Event*);
Member<ExecutionContext> context_;
void ContextDestroyed(ExecutionContext*) override;
const TaskType task_type_;
HeapLinkedHashSet<Member<Event>> queued_events_;
bool is_closed_;
......
......@@ -40,14 +40,14 @@ MediaElementEventQueue* MediaElementEventQueue::Create(
MediaElementEventQueue::MediaElementEventQueue(EventTarget* owner,
ExecutionContext* context)
: owner_(owner), context_(context), is_closed_(false) {}
: ContextLifecycleObserver(context), owner_(owner), is_closed_(false) {}
MediaElementEventQueue::~MediaElementEventQueue() = default;
void MediaElementEventQueue::Trace(blink::Visitor* visitor) {
visitor->Trace(owner_);
visitor->Trace(context_);
visitor->Trace(pending_events_);
ContextLifecycleObserver::Trace(visitor);
}
bool MediaElementEventQueue::EnqueueEvent(const base::Location& from_here,
......@@ -55,6 +55,8 @@ bool MediaElementEventQueue::EnqueueEvent(const base::Location& from_here,
if (is_closed_)
return false;
DCHECK(GetExecutionContext());
TRACE_EVENT_ASYNC_BEGIN1("event", "MediaElementEventQueue:enqueueEvent",
event, "type", event->type().Ascii());
EventTarget* target = event->target() ? event->target() : owner_.Get();
......@@ -62,7 +64,8 @@ bool MediaElementEventQueue::EnqueueEvent(const base::Location& from_here,
event);
pending_events_.insert(event);
context_->GetTaskRunner(TaskType::kMediaElementEvent)
GetExecutionContext()
->GetTaskRunner(TaskType::kMediaElementEvent)
->PostTask(FROM_HERE,
WTF::Bind(&MediaElementEventQueue::DispatchEvent,
WrapPersistent(this), WrapPersistent(event)));
......@@ -94,6 +97,7 @@ void MediaElementEventQueue::DispatchEvent(Event* event) {
void MediaElementEventQueue::Close() {
is_closed_ = true;
CancelAllEvents();
owner_.Clear();
}
void MediaElementEventQueue::CancelAllEvents() {
......@@ -111,4 +115,8 @@ bool MediaElementEventQueue::HasPendingEvents() const {
return pending_events_.size() > 0;
}
void MediaElementEventQueue::ContextDestroyed(ExecutionContext*) {
Close();
}
} // namespace blink
......@@ -29,6 +29,7 @@
#include "base/location.h"
#include "base/memory/scoped_refptr.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h"
#include "third_party/blink/renderer/core/dom/events/event_target.h"
#include "third_party/blink/renderer/platform/timer.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
......@@ -38,12 +39,15 @@ namespace blink {
// Queue for events originating in MediaElement and having
// "media element event" task type according to the spec.
class CORE_EXPORT MediaElementEventQueue final
: public GarbageCollectedFinalized<MediaElementEventQueue> {
: public GarbageCollectedFinalized<MediaElementEventQueue>,
public ContextLifecycleObserver {
USING_GARBAGE_COLLECTED_MIXIN(MediaElementEventQueue);
public:
static MediaElementEventQueue* Create(EventTarget*, ExecutionContext*);
~MediaElementEventQueue();
void Trace(blink::Visitor*);
void Trace(blink::Visitor*) override;
bool EnqueueEvent(const base::Location&, Event*);
void Close();
......@@ -55,8 +59,9 @@ class CORE_EXPORT MediaElementEventQueue final
bool RemoveEvent(Event* event);
void DispatchEvent(Event* event);
void ContextDestroyed(ExecutionContext*) override;
Member<EventTarget> owner_;
Member<ExecutionContext> context_;
HeapHashSet<Member<Event>> pending_events_;
bool is_closed_;
......
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