Commit 6b44cb09 authored by Harkiran Bolaria's avatar Harkiran Bolaria Committed by Commit Bot

[bfcache] Add tracking for IPC tasks posted to cached pages

Add callback to handle specialized behavior when tasks are posted. To be filled with IPC tracking for cached frames in a subsequent Cl.

Bug: 1110344
Change-Id: I7a053747082782a0c2f6c44a7b77aeb6f9694d96
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2316781
Commit-Queue: Harkiran Bolaria <hbolaria@google.com>
Reviewed-by: default avatarAlexander Timin <altimin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#799855}
parent 876f0b19
......@@ -3479,6 +3479,8 @@ void SetOnTaskHandlers(scoped_refptr<TestTaskQueue> task_queue,
[](int* counter, const Task& task, TaskQueue::TaskTiming* task_timing,
LazyNow* lazy_now) { ++(*counter); },
complete_counter));
task_queue->GetTaskQueueImpl()->SetOnTaskPostedHandler(
internal::TaskQueueImpl::OnTaskPostedHandler());
}
void UnsetOnTaskHandlers(scoped_refptr<TestTaskQueue> task_queue) {
......@@ -3486,6 +3488,8 @@ void UnsetOnTaskHandlers(scoped_refptr<TestTaskQueue> task_queue) {
internal::TaskQueueImpl::OnTaskStartedHandler());
task_queue->GetTaskQueueImpl()->SetOnTaskCompletedHandler(
internal::TaskQueueImpl::OnTaskCompletedHandler());
task_queue->GetTaskQueueImpl()->SetOnTaskPostedHandler(
internal::TaskQueueImpl::OnTaskPostedHandler());
}
} // namespace
......
......@@ -183,6 +183,7 @@ void TaskQueue::ShutdownTaskQueue() {
internal::TaskQueueImpl::OnTaskStartedHandler());
impl_->SetOnTaskCompletedHandler(
internal::TaskQueueImpl::OnTaskCompletedHandler());
impl_->SetOnTaskPostedHandler(internal::TaskQueueImpl::OnTaskPostedHandler());
sequence_manager_->UnregisterTaskQueueImpl(TakeTaskQueueImpl());
}
......
......@@ -306,6 +306,10 @@ void TaskQueueImpl::PostImmediateTaskImpl(PostedTask task,
&any_thread_.immediate_incoming_queue.back(), name_);
MaybeReportIpcTaskQueuedFromAnyThreadLocked(
&any_thread_.immediate_incoming_queue.back(), name_);
if (!any_thread_.on_task_posted_handler.is_null()) {
any_thread_.on_task_posted_handler.Run(
any_thread_.immediate_incoming_queue.back());
}
// If this queue was completely empty, then the SequenceManager needs to be
// informed so it can reload the work queue and add us to the
......@@ -1177,6 +1181,12 @@ bool TaskQueueImpl::RequiresTaskTiming() const {
!main_thread_only().on_task_completed_handler.is_null();
}
void TaskQueueImpl::SetOnTaskPostedHandler(OnTaskPostedHandler handler) {
DCHECK(should_notify_observers_ || handler.is_null());
base::internal::CheckedAutoLock lock(any_thread_lock_);
any_thread_.on_task_posted_handler = std::move(handler);
}
bool TaskQueueImpl::IsUnregistered() const {
base::internal::CheckedAutoLock lock(any_thread_lock_);
return any_thread_.unregistered;
......
......@@ -95,6 +95,7 @@ class BASE_EXPORT TaskQueueImpl {
RepeatingCallback<void(const Task&, const TaskQueue::TaskTiming&)>;
using OnTaskCompletedHandler =
RepeatingCallback<void(const Task&, TaskQueue::TaskTiming*, LazyNow*)>;
using OnTaskPostedHandler = RepeatingCallback<void(const Task&)>;
// May be called from any thread.
scoped_refptr<SingleThreadTaskRunner> CreateTaskRunner(
......@@ -217,6 +218,13 @@ class BASE_EXPORT TaskQueueImpl {
LazyNow* lazy_now);
bool RequiresTaskTiming() const;
// Set a callback for adding custom functionality for processing posted task.
// Callback will be dispatched while holding a scheduler lock. As a result,
// callback should not call scheduler APIs directly, as this can lead to
// deadlocks. For example, PostTask should not be called directly and
// ScopedDeferTaskPosting::PostOrDefer should be used instead.
void SetOnTaskPostedHandler(OnTaskPostedHandler handler);
WeakPtr<SequenceManagerImpl> GetSequenceManagerWeakPtr();
SequenceManagerImpl* sequence_manager() const { return sequence_manager_; }
......@@ -497,6 +505,8 @@ class BASE_EXPORT TaskQueueImpl {
bool unregistered = false;
OnTaskPostedHandler on_task_posted_handler;
#if DCHECK_IS_ON()
// A cache of |immediate_work_queue->work_queue_set_index()| which is used
// to index into
......
......@@ -36,6 +36,7 @@ include_rules = [
"+base/synchronization/atomic_flag.h",
"+base/synchronization/cancellation_flag.h",
"+base/synchronization/lock.h",
"+base/task/common/scoped_defer_task_posting.h",
"+base/task/sequence_manager/lazy_now.h",
"+base/task/sequence_manager/sequence_manager.h",
"+base/task/sequence_manager/task_queue.h",
......
......@@ -8,6 +8,7 @@
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_macros.h"
#include "base/task/common/scoped_defer_task_posting.h"
#include "base/task/sequence_manager/lazy_now.h"
#include "base/time/time.h"
#include "base/trace_event/blame_context.h"
......@@ -715,6 +716,11 @@ void FrameSchedulerImpl::ReportActiveSchedulerTrackedFeatures() {
ReportFeaturesToDelegate();
}
base::WeakPtr<FrameSchedulerImpl>
FrameSchedulerImpl::GetInvalidingOnBFCacheRestoreWeakPtr() {
return invalidating_on_bfcache_restore_weak_factory_.GetWeakPtr();
}
void FrameSchedulerImpl::OnAddedAllThrottlingOptOut() {
++all_throttling_opt_out_count_;
opted_out_from_all_throttling_ =
......@@ -1209,6 +1215,48 @@ void FrameSchedulerImpl::OnTaskQueueCreated(
}
}
void FrameSchedulerImpl::SetOnIPCTaskPostedWhileInBackForwardCacheHandler() {
DCHECK(parent_page_scheduler_->IsStoredInBackForwardCache());
for (const auto& task_queue_and_voter :
frame_task_queue_controller_->GetAllTaskQueuesAndVoters()) {
task_queue_and_voter.first->SetOnIPCTaskPosted(base::BindRepeating(
[](scoped_refptr<base::SingleThreadTaskRunner> task_runner,
base::WeakPtr<FrameSchedulerImpl> frame_scheduler,
const base::sequence_manager::Task& task) {
// Only log IPC tasks. IPC tasks are only logged currently as IPC
// hash can be mapped back to a function name, and IPC tasks may
// potentially post sensitive information.
if (!task.ipc_hash) {
return;
}
base::ScopedDeferTaskPosting::PostOrDefer(
task_runner, FROM_HERE,
base::BindOnce(
&FrameSchedulerImpl::OnIPCTaskPostedWhileInBackForwardCache,
frame_scheduler, task.ipc_hash, task.posted_from),
base::TimeDelta());
},
main_thread_scheduler_->DefaultTaskRunner(),
GetInvalidingOnBFCacheRestoreWeakPtr()));
}
}
void FrameSchedulerImpl::DetachOnIPCTaskPostedWhileInBackForwardCacheHandler() {
for (const auto& task_queue_and_voter :
frame_task_queue_controller_->GetAllTaskQueuesAndVoters()) {
task_queue_and_voter.first->DetachOnIPCTaskPostedWhileInBackForwardCache();
}
invalidating_on_bfcache_restore_weak_factory_.InvalidateWeakPtrs();
}
void FrameSchedulerImpl::OnIPCTaskPostedWhileInBackForwardCache(
uint32_t ipc_hash,
const base::Location& task_from) {
DCHECK(parent_page_scheduler_->IsStoredInBackForwardCache());
// TODO - start recording metrics
}
WTF::HashSet<SchedulingPolicy::Feature>
FrameSchedulerImpl::GetActiveFeaturesTrackedForBackForwardCacheMetrics() {
WTF::HashSet<SchedulingPolicy::Feature> result;
......
......@@ -142,6 +142,7 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler,
base::WeakPtr<FrameScheduler> GetWeakPtr() override;
base::WeakPtr<const FrameSchedulerImpl> GetWeakPtr() const;
base::WeakPtr<FrameSchedulerImpl> GetInvalidingOnBFCacheRestoreWeakPtr();
void ReportActiveSchedulerTrackedFeatures() override;
......@@ -180,6 +181,11 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler,
MainThreadTaskQueue*,
base::sequence_manager::TaskQueue::QueueEnabledVoter*) override;
void SetOnIPCTaskPostedWhileInBackForwardCacheHandler();
void DetachOnIPCTaskPostedWhileInBackForwardCacheHandler();
void OnIPCTaskPostedWhileInBackForwardCache(uint32_t ipc_hash,
const base::Location& task_from);
// Returns the list of active features which currently tracked by the
// scheduler for back-forward cache metrics.
WTF::HashSet<SchedulingPolicy::Feature>
......@@ -382,6 +388,12 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler,
// and documents.
base::WeakPtrFactory<FrameSchedulerImpl> document_bound_weak_factory_{this};
// WeakPtrFactory for tracking IPCs posted to frames cached in the
// back-forward cache. These weak pointers are invalidated when the page is
// restored from the cache.
base::WeakPtrFactory<FrameSchedulerImpl>
invalidating_on_bfcache_restore_weak_factory_{this};
mutable base::WeakPtrFactory<FrameSchedulerImpl> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(FrameSchedulerImpl);
......
......@@ -8,6 +8,7 @@
#include <utility>
#include "base/bind.h"
#include "base/task/common/scoped_defer_task_posting.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h"
#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h"
#include "third_party/blink/renderer/platform/wtf/wtf.h"
......@@ -191,11 +192,30 @@ void MainThreadTaskQueue::DetachFromMainThreadScheduler() {
GetTaskQueueImpl()->SetOnTaskCompletedHandler(
base::BindRepeating(&MainThreadSchedulerImpl::OnTaskCompleted,
main_thread_scheduler_->GetWeakPtr(), nullptr));
GetTaskQueueImpl()->SetOnTaskPostedHandler(
internal::TaskQueueImpl::OnTaskPostedHandler());
}
ClearReferencesToSchedulers();
}
void MainThreadTaskQueue::SetOnIPCTaskPosted(
base::RepeatingCallback<void(const base::sequence_manager::Task&)>
on_ipc_task_posted_callback) {
if (GetTaskQueueImpl()) {
// We use the frame_scheduler_ to track metrics so as to ensure that metrics
// are not tied to individual task queues.
GetTaskQueueImpl()->SetOnTaskPostedHandler(on_ipc_task_posted_callback);
}
}
void MainThreadTaskQueue::DetachOnIPCTaskPostedWhileInBackForwardCache() {
if (GetTaskQueueImpl()) {
GetTaskQueueImpl()->SetOnTaskPostedHandler(
internal::TaskQueueImpl::OnTaskPostedHandler());
}
}
void MainThreadTaskQueue::ShutdownTaskQueue() {
ClearReferencesToSchedulers();
TaskQueue::ShutdownTaskQueue();
......
......@@ -383,6 +383,11 @@ class PLATFORM_EXPORT MainThreadTaskQueue
base::sequence_manager::TaskQueue::TaskTiming* task_timing,
base::sequence_manager::LazyNow* lazy_now);
void SetOnIPCTaskPosted(
base::RepeatingCallback<void(const base::sequence_manager::Task&)>
on_ipc_task_posted_callback);
void DetachOnIPCTaskPostedWhileInBackForwardCache();
void DetachFromMainThreadScheduler();
// Override base method to notify MainThreadScheduler about shutdown queue.
......
......@@ -323,6 +323,28 @@ void PageSchedulerImpl::SetPageFrozenImpl(
void PageSchedulerImpl::SetPageBackForwardCached(
bool is_in_back_forward_cache) {
is_stored_in_back_forward_cache_ = is_in_back_forward_cache;
if (!is_stored_in_back_forward_cache_) {
set_ipc_posted_handler_task_.Cancel();
for (FrameSchedulerImpl* frame_scheduler : frame_schedulers_) {
frame_scheduler->DetachOnIPCTaskPostedWhileInBackForwardCacheHandler();
}
} else {
// Incorporate a delay of 15 seconds to allow for caching operations to
// complete before tasks are logged.
set_ipc_posted_handler_task_ = PostDelayedCancellableTask(
*main_thread_scheduler_->ControlTaskRunner(), FROM_HERE,
base::BindRepeating(&PageSchedulerImpl::SetUpIPCTaskDetection,
GetWeakPtr()),
base::TimeDelta::FromSeconds(15));
}
}
void PageSchedulerImpl::SetUpIPCTaskDetection() {
DCHECK(is_stored_in_back_forward_cache_);
for (FrameSchedulerImpl* frame_scheduler : frame_schedulers_) {
frame_scheduler->SetOnIPCTaskPostedWhileInBackForwardCacheHandler();
}
}
void PageSchedulerImpl::SetKeepActive(bool keep_active) {
......
......@@ -21,6 +21,7 @@
#include "third_party/blink/renderer/platform/scheduler/main_thread/page_visibility_state.h"
#include "third_party/blink/renderer/platform/scheduler/public/page_lifecycle_state.h"
#include "third_party/blink/renderer/platform/scheduler/public/page_scheduler.h"
#include "third_party/blink/renderer/platform/scheduler/public/post_cancellable_task.h"
#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
......@@ -62,6 +63,7 @@ class PLATFORM_EXPORT PageSchedulerImpl : public PageScheduler {
void SetPageVisible(bool page_visible) override;
void SetPageFrozen(bool) override;
void SetPageBackForwardCached(bool) override;
bool IsStoredInBackForwardCache() { return is_stored_in_back_forward_cache_; }
void SetKeepActive(bool) override;
bool IsMainFrameLocal() const override;
void SetIsMainFrameLocal(bool is_local) override;
......@@ -128,7 +130,9 @@ class PLATFORM_EXPORT PageSchedulerImpl : public PageScheduler {
PageLifecycleState GetPageLifecycleState() const;
// Generally UKMs are asssociated with the main frame of a page, but the
void SetUpIPCTaskDetection();
// Generally UKMs are associated with the main frame of a page, but the
// implementation allows to request a recorder from any local frame with
// the same result (e.g. for OOPIF support), therefore we need to select
// any frame here.
......@@ -327,6 +331,7 @@ class PLATFORM_EXPORT PageSchedulerImpl : public PageScheduler {
const base::TimeDelta delay_for_background_and_network_idle_tab_freezing_;
bool is_stored_in_back_forward_cache_ = false;
TaskHandle set_ipc_posted_handler_task_;
std::unique_ptr<PageLifecycleStateTracker> page_lifecycle_state_tracker_;
base::WeakPtrFactory<PageSchedulerImpl> weak_factory_{this};
......
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