Commit aebd9994 authored by Lyubomir Ivanov's avatar Lyubomir Ivanov Committed by Commit Bot

perfetto: Enable deferred posting of delayed tasks until outside the scope of a lock.

This is needed for an upcoming change to perfetto that will post delayed
tasks to the perfetto task runner. This posting could happen from within
PostTask itself and can thus lead to deadlocks. Extend
ScopedDeferTaskPosting::PostOrDefer to include a delay.

Related change in perfetto:
https://android-review.googlesource.com/c/platform/external/perfetto/+/1260461

Bug: 1029298
Change-Id: I1a612d90af3cbc3a6f58ccfcab20fd10910d4b65
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2106176
Commit-Queue: Lyubomir Ivanov <lri@google.com>
Reviewed-by: default avatarSami Kyöstilä <skyostil@chromium.org>
Cr-Commit-Position: refs/heads/master@{#752268}
parent a7037aab
...@@ -22,14 +22,16 @@ ThreadLocalPointer<ScopedDeferTaskPosting>& GetScopedDeferTaskPostingTLS() { ...@@ -22,14 +22,16 @@ ThreadLocalPointer<ScopedDeferTaskPosting>& GetScopedDeferTaskPostingTLS() {
void ScopedDeferTaskPosting::PostOrDefer( void ScopedDeferTaskPosting::PostOrDefer(
scoped_refptr<SequencedTaskRunner> task_runner, scoped_refptr<SequencedTaskRunner> task_runner,
const Location& from_here, const Location& from_here,
OnceClosure task) { OnceClosure task,
base::TimeDelta delay) {
ScopedDeferTaskPosting* scope = Get(); ScopedDeferTaskPosting* scope = Get();
if (scope) { if (scope) {
scope->DeferTaskPosting(std::move(task_runner), from_here, std::move(task)); scope->DeferTaskPosting(std::move(task_runner), from_here, std::move(task),
delay);
return; return;
} }
task_runner->PostTask(from_here, std::move(task)); task_runner->PostDelayedTask(from_here, std::move(task), delay);
} }
// static // static
...@@ -63,18 +65,21 @@ ScopedDeferTaskPosting::~ScopedDeferTaskPosting() { ...@@ -63,18 +65,21 @@ ScopedDeferTaskPosting::~ScopedDeferTaskPosting() {
} }
Set(nullptr); Set(nullptr);
for (DeferredTask& deferred_task : deferred_tasks_) { for (DeferredTask& deferred_task : deferred_tasks_) {
deferred_task.task_runner->PostTask(deferred_task.from_here, deferred_task.task_runner->PostDelayedTask(deferred_task.from_here,
std::move(deferred_task.task)); std::move(deferred_task.task),
deferred_task.delay);
} }
} }
ScopedDeferTaskPosting::DeferredTask::DeferredTask( ScopedDeferTaskPosting::DeferredTask::DeferredTask(
scoped_refptr<SequencedTaskRunner> task_runner, scoped_refptr<SequencedTaskRunner> task_runner,
Location from_here, Location from_here,
OnceClosure task) OnceClosure task,
base::TimeDelta delay)
: task_runner(std::move(task_runner)), : task_runner(std::move(task_runner)),
from_here(from_here), from_here(from_here),
task(std::move(task)) {} task(std::move(task)),
delay(delay) {}
ScopedDeferTaskPosting::DeferredTask::DeferredTask(DeferredTask&&) = default; ScopedDeferTaskPosting::DeferredTask::DeferredTask(DeferredTask&&) = default;
...@@ -83,9 +88,10 @@ ScopedDeferTaskPosting::DeferredTask::~DeferredTask() = default; ...@@ -83,9 +88,10 @@ ScopedDeferTaskPosting::DeferredTask::~DeferredTask() = default;
void ScopedDeferTaskPosting::DeferTaskPosting( void ScopedDeferTaskPosting::DeferTaskPosting(
scoped_refptr<SequencedTaskRunner> task_runner, scoped_refptr<SequencedTaskRunner> task_runner,
const Location& from_here, const Location& from_here,
OnceClosure task) { OnceClosure task,
base::TimeDelta delay) {
deferred_tasks_.push_back( deferred_tasks_.push_back(
{std::move(task_runner), from_here, std::move(task)}); {std::move(task_runner), from_here, std::move(task), delay});
} }
} // namespace base } // namespace base
...@@ -25,7 +25,8 @@ class BASE_EXPORT ScopedDeferTaskPosting { ...@@ -25,7 +25,8 @@ class BASE_EXPORT ScopedDeferTaskPosting {
public: public:
static void PostOrDefer(scoped_refptr<SequencedTaskRunner> task_runner, static void PostOrDefer(scoped_refptr<SequencedTaskRunner> task_runner,
const Location& from_here, const Location& from_here,
OnceClosure task); OnceClosure task,
base::TimeDelta delay);
static bool IsPresent(); static bool IsPresent();
...@@ -40,18 +41,21 @@ class BASE_EXPORT ScopedDeferTaskPosting { ...@@ -40,18 +41,21 @@ class BASE_EXPORT ScopedDeferTaskPosting {
void DeferTaskPosting(scoped_refptr<SequencedTaskRunner> task_runner, void DeferTaskPosting(scoped_refptr<SequencedTaskRunner> task_runner,
const Location& from_here, const Location& from_here,
OnceClosure task); OnceClosure task,
base::TimeDelta delay);
struct DeferredTask { struct DeferredTask {
DeferredTask(scoped_refptr<SequencedTaskRunner> task_runner, DeferredTask(scoped_refptr<SequencedTaskRunner> task_runner,
Location from_here, Location from_here,
OnceClosure task); OnceClosure task,
base::TimeDelta delay);
DeferredTask(DeferredTask&& task); DeferredTask(DeferredTask&& task);
~DeferredTask(); ~DeferredTask();
scoped_refptr<SequencedTaskRunner> task_runner; scoped_refptr<SequencedTaskRunner> task_runner;
Location from_here; Location from_here;
OnceClosure task; OnceClosure task;
base::TimeDelta delay;
DISALLOW_COPY_AND_ASSIGN(DeferredTask); DISALLOW_COPY_AND_ASSIGN(DeferredTask);
}; };
......
...@@ -34,6 +34,11 @@ PerfettoTaskRunner::~PerfettoTaskRunner() { ...@@ -34,6 +34,11 @@ PerfettoTaskRunner::~PerfettoTaskRunner() {
} }
void PerfettoTaskRunner::PostTask(std::function<void()> task) { void PerfettoTaskRunner::PostTask(std::function<void()> task) {
PostDelayedTask(task, /* delay_ms */ 0);
}
void PerfettoTaskRunner::PostDelayedTask(std::function<void()> task,
uint32_t delay_ms) {
base::ScopedDeferTaskPosting::PostOrDefer( base::ScopedDeferTaskPosting::PostOrDefer(
GetOrCreateTaskRunner(), FROM_HERE, GetOrCreateTaskRunner(), FROM_HERE,
base::BindOnce( base::BindOnce(
...@@ -52,23 +57,7 @@ void PerfettoTaskRunner::PostTask(std::function<void()> task) { ...@@ -52,23 +57,7 @@ void PerfettoTaskRunner::PostTask(std::function<void()> task) {
TraceEventDataSource::GetThreadIsInTraceEventTLS()); TraceEventDataSource::GetThreadIsInTraceEventTLS());
task(); task();
}, },
task)); task),
}
void PerfettoTaskRunner::PostDelayedTask(std::function<void()> task,
uint32_t delay_ms) {
if (delay_ms == 0) {
PostTask(std::move(task));
return;
}
// There's currently nothing which uses PostDelayedTask on the ProducerClient
// side, where PostTask sometimes requires blocking. If this DCHECK ever
// triggers, support for deferring delayed tasks need to be added.
DCHECK(!base::ScopedDeferTaskPosting::IsPresent());
GetOrCreateTaskRunner()->PostDelayedTask(
FROM_HERE,
base::BindOnce([](std::function<void()> task) { task(); }, task),
base::TimeDelta::FromMilliseconds(delay_ms)); base::TimeDelta::FromMilliseconds(delay_ms));
} }
......
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