summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThiago Marcos P. Santos <tmpsantos@gmail.com>2019-08-07 14:04:26 +0300
committerThiago Marcos P. Santos <tmpsantos@gmail.com>2019-08-07 22:41:12 +0300
commit47f498e642ca4a1f92e0912267978c38e53c4435 (patch)
tree4cc99a99ac8a47636057bdc3b1e0ee673111c8b7
parent572213668070cadab81f27edd88d3d07dffc3eed (diff)
downloadqtlocation-mapboxgl-47f498e642ca4a1f92e0912267978c38e53c4435.tar.gz
[android] Do not try to wake up the RunLoop if a wake is already pending
Do not flood the RunLoop with wake up calls, potentially causing the socket buffer to overflow. Also, write calls are syscalls and will cause a context switch.
-rw-r--r--platform/android/src/run_loop.cpp16
-rw-r--r--platform/android/src/run_loop_impl.hpp1
2 files changed, 12 insertions, 5 deletions
diff --git a/platform/android/src/run_loop.cpp b/platform/android/src/run_loop.cpp
index 2966ecdfb0..a9cbfb57aa 100644
--- a/platform/android/src/run_loop.cpp
+++ b/platform/android/src/run_loop.cpp
@@ -31,8 +31,10 @@ int looperCallbackNew(int fd, int, void* data) {
int buffer[1];
while (read(fd, buffer, sizeof(buffer)) > 0) {}
- auto loop = reinterpret_cast<ALooper*>(data);
- ALooper_wake(loop);
+ auto runLoopImpl = reinterpret_cast<RunLoop::Impl*>(data);
+
+ runLoopImpl->coalesce.clear();
+ ALooper_wake(runLoopImpl->loop);
return 1;
}
@@ -42,9 +44,9 @@ int looperCallbackDefault(int fd, int, void* data) {
while (read(fd, buffer, sizeof(buffer)) > 0) {}
auto runLoopImpl = reinterpret_cast<RunLoop::Impl*>(data);
- auto runLoop = runLoopImpl->runLoop;
- runLoop->runOnce();
+ runLoopImpl->coalesce.clear();
+ runLoopImpl->runLoop->runOnce();
if (!runLoopImpl->running) {
ALooper_wake(runLoopImpl->loop);
@@ -99,7 +101,7 @@ RunLoop::Impl::Impl(RunLoop* runLoop_, RunLoop::Type type) : runLoop(runLoop_) {
switch (type) {
case Type::New:
ret = ALooper_addFd(loop, fds[PIPE_OUT], ALOOPER_POLL_CALLBACK,
- ALOOPER_EVENT_INPUT, looperCallbackNew, loop);
+ ALOOPER_EVENT_INPUT, looperCallbackNew, this);
break;
case Type::Default:
ret = ALooper_addFd(loop, fds[PIPE_OUT], ALOOPER_POLL_CALLBACK,
@@ -129,6 +131,10 @@ RunLoop::Impl::~Impl() {
}
void RunLoop::Impl::wake() {
+ if (coalesce.test_and_set(std::memory_order_acquire)) {
+ return;
+ }
+
if (write(fds[PIPE_IN], "\n", 1) == -1) {
throw std::runtime_error("Failed to write to file descriptor.");
}
diff --git a/platform/android/src/run_loop_impl.hpp b/platform/android/src/run_loop_impl.hpp
index a76d636188..c6a1b23a7b 100644
--- a/platform/android/src/run_loop_impl.hpp
+++ b/platform/android/src/run_loop_impl.hpp
@@ -41,6 +41,7 @@ public:
ALooper* loop = nullptr;
RunLoop* runLoop = nullptr;
std::atomic<bool> running;
+ std::atomic_flag coalesce = ATOMIC_FLAG_INIT;
private:
friend RunLoop;