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 d7b0d130780aa540e5ffb9bc11ab21b645b4c390..4cc764b0990fb04a23909e0b15608110a1713ad1 100644 |
--- a/third_party/WebKit/Source/platform/WebTaskRunner.cpp |
+++ b/third_party/WebKit/Source/platform/WebTaskRunner.cpp |
@@ -29,6 +29,14 @@ struct CallbackCancellationTraits< |
namespace blink { |
+namespace { |
+ |
+void runCrossThreadClosure(std::unique_ptr<CrossThreadClosure> task) { |
+ (*task)(); |
+} |
+ |
+} // namespace |
+ |
class TaskHandle::Runner : public WTF::ThreadSafeRefCounted<Runner> { |
public: |
explicit Runner(std::unique_ptr<WTF::Closure> task) |
@@ -103,17 +111,23 @@ TaskHandle::TaskHandle(RefPtr<Runner> runner) : m_runner(std::move(runner)) { |
DCHECK(m_runner); |
} |
+// Use a custom function for base::Bind instead of convertToBaseCallback to |
+// avoid copying the closure later in the call chain. Copying the bound state |
+// can lead to data races with ref counted objects like StringImpl. See |
+// crbug.com/679915 for more details. |
void WebTaskRunner::postTask(const WebTraceLocation& location, |
std::unique_ptr<CrossThreadClosure> task) { |
- toSingleThreadTaskRunner()->PostTask(location, |
- convertToBaseCallback(std::move(task))); |
+ toSingleThreadTaskRunner()->PostTask( |
+ location, |
+ base::Bind(&runCrossThreadClosure, base::Passed(std::move(task)))); |
dcheng
2017/01/11 18:19:16
Nit: base::Passed(&task) here and below.
Charlie Harrison
2017/01/11 18:43:34
Done.
|
} |
void WebTaskRunner::postDelayedTask(const WebTraceLocation& location, |
std::unique_ptr<CrossThreadClosure> task, |
long long delayMs) { |
toSingleThreadTaskRunner()->PostDelayedTask( |
- location, convertToBaseCallback(std::move(task)), |
+ location, |
+ base::Bind(&runCrossThreadClosure, base::Passed(std::move(task))), |
base::TimeDelta::FromMilliseconds(delayMs)); |
} |