Chromium Code Reviews| Index: third_party/WebKit/Source/platform/WebTaskRunner.cpp |
| diff --git a/third_party/WebKit/Source/platform/WebTaskRunner.cpp b/third_party/WebKit/Source/platform/WebTaskRunner.cpp |
| index 548dbc9ac1d500a31170856fbe2966d1ce612059..3f2c0d1b5eee72317a5d6311ad33c168b5453b4e 100644 |
| --- a/third_party/WebKit/Source/platform/WebTaskRunner.cpp |
| +++ b/third_party/WebKit/Source/platform/WebTaskRunner.cpp |
| @@ -6,6 +6,65 @@ |
| namespace blink { |
| +// This class holds a reference to a TaskHandle to make sure it keeps alive |
|
dcheng
2016/10/21 06:14:46
Nit: to make sure it keeps alive => to keep it ali
tzik
2016/10/25 07:03:52
Done.
|
| +// while a task is pending in a task queue, and clears its reference to avoid a |
|
dcheng
2016/10/21 06:14:46
Nit: until we read line 22-23, it's not clear when
|
| +// possible circular references in a case below: |
|
haraken
2016/10/20 17:07:37
avoid a circular reference like below
tzik
2016/10/25 07:03:52
Done.
|
| +// struct Foo : GarbageCollected<Foo> { |
| +// void bar() {} |
| +// RefPtr<TaskHandle> m_handle; |
| +// }; |
| +// |
| +// foo->m_handle = taskRunner->postCancellableTask( |
| +// BLINK_FROM_HERE, WTF::bind(&Foo::bar, wrapPersistent(foo))); |
| +// |
| +// There is a circular reference in the example above as: |
| +// foo -> m_handle -> m_task -> Persistent<Foo> in WTF::bind. |
| +// CancelOnScopeOut is needed to cut the circle by clearing |m_task| when the |
|
dcheng
2016/10/21 06:14:46
Nit: cut the circle => break the cycle
tzik
2016/10/25 07:03:52
Done.
|
| +// wrapped WTF::Closure is deleted. |
| +class TaskHandle::CancelOnScopeOut { |
|
haraken
2016/10/20 17:07:37
I'd rename this to CancelOnTaskDestruction
tzik
2016/10/25 07:03:52
Done.
|
| + public: |
| + explicit CancelOnScopeOut(WTF::PassRefPtr<TaskHandle> handle) |
|
dcheng
2016/10/21 06:14:46
Nit: RefPtr here (also no WTF:: prefix is needed)
tzik
2016/10/25 07:03:52
Done.
|
| + : m_handle(std::move(handle)) {} |
| + |
| + CancelOnScopeOut(CancelOnScopeOut&&) = default; |
| + |
| + void cancel() const { |
| + if (m_handle) |
|
dcheng
2016/10/21 06:14:46
Is there a time when this will be null?
tzik
2016/10/25 07:03:52
Yes. We make a temporary object on WTF::bind call
|
| + m_handle->cancel(); |
| + } |
| + |
| + ~CancelOnScopeOut() { cancel(); } |
| + |
| + private: |
| + RefPtr<TaskHandle> m_handle; |
| +}; |
| + |
| +bool TaskHandle::isActive() const { |
| + return static_cast<bool>(m_task); |
| +} |
| + |
| +void TaskHandle::cancel() { |
| + std::unique_ptr<WTF::Closure> task = std::move(m_task); |
| + m_weakPtrFactory.revokeAll(); |
| +} |
| + |
| +TaskHandle::~TaskHandle() {} |
| + |
| +TaskHandle::TaskHandle(std::unique_ptr<WTF::Closure> task) |
| + : m_task(std::move(task)), m_weakPtrFactory(this) { |
| + DCHECK(m_task); |
| +} |
| + |
| +void TaskHandle::run(const CancelOnScopeOut& scoper) { |
| + std::unique_ptr<WTF::Closure> task = std::move(m_task); |
| + cancel(); |
| + (*task)(); |
| +} |
| + |
| +WTF::WeakPtr<TaskHandle> TaskHandle::asWeakPtr() { |
| + return m_weakPtrFactory.createWeakPtr(); |
| +} |
| + |
| void WebTaskRunner::postTask(const WebTraceLocation& location, |
| std::unique_ptr<CrossThreadClosure> task) { |
| toSingleThreadTaskRunner()->PostTask(location, |
| @@ -34,4 +93,26 @@ void WebTaskRunner::postDelayedTask(const WebTraceLocation& location, |
| base::TimeDelta::FromMilliseconds(delayMs)); |
| } |
| +RefPtr<TaskHandle> WebTaskRunner::postCancellableTask( |
| + const WebTraceLocation& location, |
| + std::unique_ptr<WTF::Closure> task) { |
| + DCHECK(runsTasksOnCurrentThread()); |
| + RefPtr<TaskHandle> handle = adoptRef(new TaskHandle(std::move(task))); |
| + postTask(location, WTF::bind(&TaskHandle::run, handle->asWeakPtr(), |
| + TaskHandle::CancelOnScopeOut(handle))); |
| + return handle; |
| +} |
| + |
| +RefPtr<TaskHandle> WebTaskRunner::postDelayedCancellableTask( |
| + const WebTraceLocation& location, |
| + std::unique_ptr<WTF::Closure> task, |
| + long long delayMs) { |
| + DCHECK(runsTasksOnCurrentThread()); |
| + RefPtr<TaskHandle> handle = adoptRef(new TaskHandle(std::move(task))); |
| + postDelayedTask(location, WTF::bind(&TaskHandle::run, handle->asWeakPtr(), |
| + TaskHandle::CancelOnScopeOut(handle)), |
| + delayMs); |
| + return handle; |
| +} |
| + |
| } // namespace blink |