From 360a5fbd078cd0392087c0387dc51c6694dffb8e Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Thu, 31 Aug 2017 15:29:57 -0700 Subject: [PATCH] Don't throw an exception every 10ms in the RPC worker Cuts the time taken to run the react native tests on my machine from 198 seconds to 41 seconds. Probably has a similar impact on the react native debugger performance. --- src/concurrent_deque.hpp | 48 ++++++++++++++-------------------------- src/rpc.cpp | 19 ++++++++-------- 2 files changed, 26 insertions(+), 41 deletions(-) diff --git a/src/concurrent_deque.hpp b/src/concurrent_deque.hpp index 4c05b372..260ff107 100644 --- a/src/concurrent_deque.hpp +++ b/src/concurrent_deque.hpp @@ -20,37 +20,26 @@ #include #include -#include #include +#include + namespace realm { -class ConcurrentDequeTimeout : public std::exception { - public: - ConcurrentDequeTimeout() : std::exception() {} -}; - template class ConcurrentDeque { - public: - T pop_front(size_t timeout = 0) { +public: + T pop_back() { std::unique_lock lock(m_mutex); - while (m_deque.empty()) { - wait(lock, timeout); - } - T item = std::move(m_deque.front()); - m_deque.pop_front(); - return item; + m_condition.wait(lock, [this] { return !m_deque.empty(); }); + return do_pop_back(); } - T pop_back(size_t timeout = 0) { + util::Optional try_pop_back(size_t timeout) { std::unique_lock lock(m_mutex); - while (m_deque.empty()) { - wait(lock, timeout); - } - T item = std::move(m_deque.back()); - m_deque.pop_back(); - return item; + m_condition.wait_for(lock, std::chrono::milliseconds(timeout), + [this] { return !m_deque.empty(); }); + return m_deque.empty() ? util::none : util::make_optional(do_pop_back()); } void push_front(T&& item) { @@ -72,19 +61,16 @@ class ConcurrentDeque { return m_deque.empty(); } - void wait(std::unique_lock &lock, size_t timeout = 0) { - if (!timeout) { - m_condition.wait(lock); - } - else if (m_condition.wait_for(lock, std::chrono::milliseconds(timeout)) == std::cv_status::timeout) { - throw ConcurrentDequeTimeout(); - } - } - - private: +private: std::condition_variable m_condition; std::mutex m_mutex; std::deque m_deque; + + T do_pop_back() { + T item = std::move(m_deque.back()); + m_deque.pop_back(); + return item; + } }; } // realm diff --git a/src/rpc.cpp b/src/rpc.cpp index 32e693ed..896fad8a 100644 --- a/src/rpc.cpp +++ b/src/rpc.cpp @@ -77,17 +77,16 @@ json RPCWorker::pop_task_result() { } void RPCWorker::try_run_task() { - try { - // Use a 10 millisecond timeout to keep this thread unblocked. - auto task = m_tasks.pop_back(10); - task(); + // Use a 10 millisecond timeout to keep this thread unblocked. + auto task = m_tasks.try_pop_back(10); + if (!task) { + return; + } - // Since this can be called recursively, it must be pushed to the front of the queue *after* running the task. - m_futures.push_front(task.get_future()); - } - catch (ConcurrentDequeTimeout &) { - // We tried. - } + (*task)(); + + // Since this can be called recursively, it must be pushed to the front of the queue *after* running the task. + m_futures.push_front(task->get_future()); } void RPCWorker::stop() {