// DragonX Wallet - ImGui Edition // Copyright 2024-2026 The Hush Developers // Released under the GPLv3 #pragma once #include #include #include #include #include #include namespace dragonx { namespace rpc { /** * @brief Background worker thread for RPC calls * * Provides a single-threaded task queue so that all RPC/HTTP work happens * off the UI thread. The caller submits a *work function* that runs on the * worker thread and returns a *result callback* that is queued for execution * on the main (UI) thread during drainResults(). * * Usage from the main thread: * * worker.post([&rpc]() -> RPCWorker::MainCb { * json r = rpc.call("getinfo"); // runs on worker thread * return [r]() { applyToState(r); }; // runs on main thread * }); * * // Each frame: * worker.drainResults(); */ class RPCWorker { public: /// Callback executed on the main thread after work completes. using MainCb = std::function; /// Work function executed on the background thread. /// Must return a MainCb (may return nullptr to skip main-thread step). using WorkFn = std::function; RPCWorker(); ~RPCWorker(); // Non-copyable RPCWorker(const RPCWorker&) = delete; RPCWorker& operator=(const RPCWorker&) = delete; /// Start the worker thread. Safe to call if already running. void start(); /// Stop the worker thread and join. Pending tasks are discarded. void stop(); /// Signal the worker thread to stop (non-blocking, no join). /// Call stop() later to join the thread. void requestStop(); /// Submit work to run on the background thread. /// @param work Function that performs blocking I/O and returns a MainCb. void post(WorkFn work); /// Drain completed result callbacks on the main thread. /// Call once per frame from update(). /// @return Number of callbacks executed. int drainResults(); /// True when there are completed results waiting for the main thread. bool hasPendingResults() const; /// True when the worker thread is running. bool isRunning() const { return running_.load(std::memory_order_relaxed); } private: void run(); // worker thread entry point std::thread thread_; std::atomic running_{false}; // ---- Task queue (produced by main thread, consumed by worker) ---- std::mutex taskMtx_; std::condition_variable taskCv_; std::deque tasks_; // ---- Result queue (produced by worker, consumed by main thread) ---- mutable std::mutex resultMtx_; std::deque results_; }; } // namespace rpc } // namespace dragonx