diff options
author | Thiago Marcos P. Santos <tmpsantos@gmail.com> | 2019-08-07 14:04:26 +0300 |
---|---|---|
committer | Thiago Marcos P. Santos <tmpsantos@gmail.com> | 2019-08-07 22:41:12 +0300 |
commit | 47f498e642ca4a1f92e0912267978c38e53c4435 (patch) | |
tree | 4cc99a99ac8a47636057bdc3b1e0ee673111c8b7 | |
parent | 572213668070cadab81f27edd88d3d07dffc3eed (diff) | |
download | qtlocation-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.cpp | 16 | ||||
-rw-r--r-- | platform/android/src/run_loop_impl.hpp | 1 |
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; |