OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "public/platform/WebTaskRunner.h" | 5 #include "public/platform/WebTaskRunner.h" |
6 | 6 |
7 namespace blink { | 7 namespace blink { |
8 | 8 |
| 9 // This class holds a reference to a TaskHandle to keep it alive while a task is |
| 10 // pending in a task queue, and clears the reference on the task disposal, so |
| 11 // that it doesn't leave a circular reference like below: |
| 12 // struct Foo : GarbageCollected<Foo> { |
| 13 // void bar() {} |
| 14 // RefPtr<TaskHandle> m_handle; |
| 15 // }; |
| 16 // |
| 17 // foo->m_handle = taskRunner->postCancellableTask( |
| 18 // BLINK_FROM_HERE, WTF::bind(&Foo::bar, wrapPersistent(foo))); |
| 19 // |
| 20 // There is a circular reference in the example above as: |
| 21 // foo -> m_handle -> m_task -> Persistent<Foo> in WTF::bind. |
| 22 // CancelOnTaskDestruction is needed to break the circle by clearing |m_task| |
| 23 // when the wrapped WTF::Closure is deleted. |
| 24 class TaskHandle::CancelOnTaskDestruction { |
| 25 public: |
| 26 explicit CancelOnTaskDestruction(RefPtr<TaskHandle> handle) |
| 27 : m_handle(std::move(handle)) {} |
| 28 |
| 29 CancelOnTaskDestruction(CancelOnTaskDestruction&&) = default; |
| 30 |
| 31 void cancel() const { |
| 32 if (m_handle) |
| 33 m_handle->cancel(); |
| 34 } |
| 35 |
| 36 ~CancelOnTaskDestruction() { cancel(); } |
| 37 |
| 38 private: |
| 39 RefPtr<TaskHandle> m_handle; |
| 40 DISALLOW_COPY_AND_ASSIGN(CancelOnTaskDestruction); |
| 41 }; |
| 42 |
| 43 bool TaskHandle::isActive() const { |
| 44 return static_cast<bool>(m_task); |
| 45 } |
| 46 |
| 47 void TaskHandle::cancel() { |
| 48 std::unique_ptr<WTF::Closure> task = std::move(m_task); |
| 49 m_weakPtrFactory.revokeAll(); |
| 50 } |
| 51 |
| 52 TaskHandle::~TaskHandle() {} |
| 53 |
| 54 TaskHandle::TaskHandle(std::unique_ptr<WTF::Closure> task) |
| 55 : m_task(std::move(task)), m_weakPtrFactory(this) { |
| 56 DCHECK(m_task); |
| 57 } |
| 58 |
| 59 void TaskHandle::run(const CancelOnTaskDestruction& scoper) { |
| 60 std::unique_ptr<WTF::Closure> task = std::move(m_task); |
| 61 cancel(); |
| 62 (*task)(); |
| 63 } |
| 64 |
| 65 WTF::WeakPtr<TaskHandle> TaskHandle::asWeakPtr() { |
| 66 return m_weakPtrFactory.createWeakPtr(); |
| 67 } |
| 68 |
9 void WebTaskRunner::postTask(const WebTraceLocation& location, | 69 void WebTaskRunner::postTask(const WebTraceLocation& location, |
10 std::unique_ptr<CrossThreadClosure> task) { | 70 std::unique_ptr<CrossThreadClosure> task) { |
11 toSingleThreadTaskRunner()->PostTask(location, | 71 toSingleThreadTaskRunner()->PostTask(location, |
12 convertToBaseCallback(std::move(task))); | 72 convertToBaseCallback(std::move(task))); |
13 } | 73 } |
14 | 74 |
15 void WebTaskRunner::postDelayedTask(const WebTraceLocation& location, | 75 void WebTaskRunner::postDelayedTask(const WebTraceLocation& location, |
16 std::unique_ptr<CrossThreadClosure> task, | 76 std::unique_ptr<CrossThreadClosure> task, |
17 long long delayMs) { | 77 long long delayMs) { |
18 toSingleThreadTaskRunner()->PostDelayedTask( | 78 toSingleThreadTaskRunner()->PostDelayedTask( |
19 location, convertToBaseCallback(std::move(task)), | 79 location, convertToBaseCallback(std::move(task)), |
20 base::TimeDelta::FromMilliseconds(delayMs)); | 80 base::TimeDelta::FromMilliseconds(delayMs)); |
21 } | 81 } |
22 | 82 |
23 void WebTaskRunner::postTask(const WebTraceLocation& location, | 83 void WebTaskRunner::postTask(const WebTraceLocation& location, |
24 std::unique_ptr<WTF::Closure> task) { | 84 std::unique_ptr<WTF::Closure> task) { |
25 toSingleThreadTaskRunner()->PostTask(location, | 85 toSingleThreadTaskRunner()->PostTask(location, |
26 convertToBaseCallback(std::move(task))); | 86 convertToBaseCallback(std::move(task))); |
27 } | 87 } |
28 | 88 |
29 void WebTaskRunner::postDelayedTask(const WebTraceLocation& location, | 89 void WebTaskRunner::postDelayedTask(const WebTraceLocation& location, |
30 std::unique_ptr<WTF::Closure> task, | 90 std::unique_ptr<WTF::Closure> task, |
31 long long delayMs) { | 91 long long delayMs) { |
32 toSingleThreadTaskRunner()->PostDelayedTask( | 92 toSingleThreadTaskRunner()->PostDelayedTask( |
33 location, convertToBaseCallback(std::move(task)), | 93 location, convertToBaseCallback(std::move(task)), |
34 base::TimeDelta::FromMilliseconds(delayMs)); | 94 base::TimeDelta::FromMilliseconds(delayMs)); |
35 } | 95 } |
36 | 96 |
| 97 RefPtr<TaskHandle> WebTaskRunner::postCancellableTask( |
| 98 const WebTraceLocation& location, |
| 99 std::unique_ptr<WTF::Closure> task) { |
| 100 DCHECK(runsTasksOnCurrentThread()); |
| 101 RefPtr<TaskHandle> handle = adoptRef(new TaskHandle(std::move(task))); |
| 102 postTask(location, WTF::bind(&TaskHandle::run, handle->asWeakPtr(), |
| 103 TaskHandle::CancelOnTaskDestruction(handle))); |
| 104 return handle; |
| 105 } |
| 106 |
| 107 RefPtr<TaskHandle> WebTaskRunner::postDelayedCancellableTask( |
| 108 const WebTraceLocation& location, |
| 109 std::unique_ptr<WTF::Closure> task, |
| 110 long long delayMs) { |
| 111 DCHECK(runsTasksOnCurrentThread()); |
| 112 RefPtr<TaskHandle> handle = adoptRef(new TaskHandle(std::move(task))); |
| 113 postDelayedTask(location, |
| 114 WTF::bind(&TaskHandle::run, handle->asWeakPtr(), |
| 115 TaskHandle::CancelOnTaskDestruction(handle)), |
| 116 delayMs); |
| 117 return handle; |
| 118 } |
| 119 |
37 } // namespace blink | 120 } // namespace blink |
OLD | NEW |