From 5da5ba7706eb28b359b5d781bd2c769e336ca5ca Mon Sep 17 00:00:00 2001 From: Chris Loer Date: Wed, 22 Nov 2017 13:18:22 -0800 Subject: [PATCH] [core, ios, qt, android] Close race condition in RunLoop (issue #9620) Because a message we queue from the foreground may cause the background to complete, exit, and tear down the AsyncTask, we have to block queue processing until we've finished our call to AsyncTask::send(). Broadening the scope of a mutex is scary, but I audited the code of our four implementations of AsyncTask and I don't see any way this could cause a deadlock. --- platform/android/src/run_loop.cpp | 6 ++++-- platform/darwin/src/run_loop.cpp | 6 ++++-- platform/default/run_loop.cpp | 6 ++++-- platform/qt/src/run_loop.cpp | 6 ++++-- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/platform/android/src/run_loop.cpp b/platform/android/src/run_loop.cpp index dff7d1d98..1d284a9e7 100644 --- a/platform/android/src/run_loop.cpp +++ b/platform/android/src/run_loop.cpp @@ -217,8 +217,10 @@ LOOP_HANDLE RunLoop::getLoopHandle() { } void RunLoop::push(std::shared_ptr task) { - withMutex([&] { queue.push(std::move(task)); }); - impl->wake(); + withMutex([&] { + queue.push(std::move(task)); + impl->wake(); + }); } void RunLoop::run() { diff --git a/platform/darwin/src/run_loop.cpp b/platform/darwin/src/run_loop.cpp index 2ba8f8415..d60a88cf5 100644 --- a/platform/darwin/src/run_loop.cpp +++ b/platform/darwin/src/run_loop.cpp @@ -30,8 +30,10 @@ RunLoop::~RunLoop() { } void RunLoop::push(std::shared_ptr task) { - withMutex([&] { queue.push(std::move(task)); }); - impl->async->send(); + withMutex([&] { + queue.push(std::move(task)); + impl->async->send(); + }); } void RunLoop::run() { diff --git a/platform/default/run_loop.cpp b/platform/default/run_loop.cpp index 6375dba78..5bccd21d5 100644 --- a/platform/default/run_loop.cpp +++ b/platform/default/run_loop.cpp @@ -130,8 +130,10 @@ LOOP_HANDLE RunLoop::getLoopHandle() { } void RunLoop::push(std::shared_ptr task) { - withMutex([&] { queue.push(std::move(task)); }); - impl->async->send(); + withMutex([&] { + queue.push(std::move(task)); + impl->async->send(); + }); } void RunLoop::run() { diff --git a/platform/qt/src/run_loop.cpp b/platform/qt/src/run_loop.cpp index 71ea19032..af0c50ebb 100644 --- a/platform/qt/src/run_loop.cpp +++ b/platform/qt/src/run_loop.cpp @@ -53,8 +53,10 @@ LOOP_HANDLE RunLoop::getLoopHandle() { } void RunLoop::push(std::shared_ptr task) { - withMutex([&] { queue.push(task); }); - impl->async->send(); + withMutex([&] { + queue.push(std::move(task)); + impl->async->send(); + }); } void RunLoop::run() {