diff --git a/CMakeLists.txt b/CMakeLists.txt index c186c5905..202767c92 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -276,17 +276,9 @@ if(SUBMODULE_CHECK) endif() endif() -# We only actually need pybind11 with WITH_HIVE, but if we don't load it here then something further -# down loads a broken PythonInterp that loads Python2, but Python2 headers are not C++17 compatible. -# So load this here universally so that pybind's more intelligent python finder finds python3.x -# (which the crappier loader invoked below then respects). -# however! travis is FUBAR right now so disable it in travis builds -if(TRAVIS_CI_SUCKS OR NOT WITH_HIVE) - message(WARNING "you're on travis (which is broken garbage) or are compiling without routerhive, we have disabled pybind11, THANKS!") -else() +if(WITH_HIVE) add_subdirectory(external/pybind11 EXCLUDE_FROM_ALL) endif() - if(WITH_TESTS) add_subdirectory(external/googletest EXCLUDE_FROM_ALL) endif() diff --git a/cmake/unix.cmake b/cmake/unix.cmake index 41513e1df..1c8d19022 100644 --- a/cmake/unix.cmake +++ b/cmake/unix.cmake @@ -64,7 +64,10 @@ elseif(DOWNLOAD_UV) endif() include_directories(${LIBUV_INCLUDE_DIRS}) -find_package(LokiMQ 1.2 QUIET) +option(FORCE_LOKIMQ_SUBMODULE "force using lokimq submodule" OFF) +if(NOT FORCE_LOKIMQ_SUBMODULE) + find_package(LokiMQ 1.2) +endif() if(LokiMQ_FOUND) message(STATUS "using system lokimq") else() diff --git a/llarp/ev/ev_libuv.cpp b/llarp/ev/ev_libuv.cpp index 09133c798..fcb5456e4 100644 --- a/llarp/ev/ev_libuv.cpp +++ b/llarp/ev/ev_libuv.cpp @@ -368,7 +368,9 @@ namespace libuv OnTick(uv_check_t* t) { ticker_glue* ticker = static_cast(t->data); - LoopCall(t, ticker->func); + ticker->func(); + Loop* loop = static_cast(t->loop->data); + loop->FlushLogic(); } bool @@ -841,11 +843,7 @@ namespace libuv int Loop::run() { - uv_timer_start( - m_TickTimer, - [](uv_timer_t* t) { static_cast(t->loop->data)->FlushLogic(); }, - 1000, - 1000); + m_EventLoopThreadID = std::this_thread::get_id(); return uv_run(&m_Impl, UV_RUN_DEFAULT); } @@ -988,7 +986,6 @@ namespace libuv void Loop::stopped() { - tick(50); llarp::LogInfo("we have stopped"); } @@ -1072,7 +1069,27 @@ namespace libuv void Loop::call_soon(std::function f) { - m_LogicCalls.tryPushBack(f); + if (not m_EventLoopThreadID.has_value()) + { + m_LogicCalls.tryPushBack(f); + uv_async_send(&m_WakeUp); + return; + } + const auto inEventLoop = *m_EventLoopThreadID == std::this_thread::get_id(); + + while (m_LogicCalls.full() and inEventLoop) + { + FlushLogic(); + } + if (inEventLoop) + { + if (m_LogicCalls.tryPushBack(f) != llarp::thread::QueueReturn::Success) + { + f(); + } + } + else + m_LogicCalls.pushBack(f); uv_async_send(&m_WakeUp); } diff --git a/llarp/ev/ev_libuv.hpp b/llarp/ev/ev_libuv.hpp index 6d4cd5bb0..6b458d6a2 100644 --- a/llarp/ev/ev_libuv.hpp +++ b/llarp/ev/ev_libuv.hpp @@ -154,6 +154,7 @@ namespace libuv llarp::thread::Queue m_timerQueue; llarp::thread::Queue m_timerCancelQueue; + std::optional m_EventLoopThreadID; }; } // namespace libuv diff --git a/llarp/router/abstractrouter.hpp b/llarp/router/abstractrouter.hpp index c6ace036c..f64acc2dd 100644 --- a/llarp/router/abstractrouter.hpp +++ b/llarp/router/abstractrouter.hpp @@ -176,6 +176,10 @@ namespace llarp virtual void Stop() = 0; + /// non gracefully stop the router + virtual void + Die() = 0; + /// pump low level links virtual void PumpLL() = 0; diff --git a/llarp/router/router.cpp b/llarp/router/router.cpp index 47b23e1e6..0113b14af 100644 --- a/llarp/router/router.cpp +++ b/llarp/router/router.cpp @@ -1021,6 +1021,26 @@ namespace llarp _linkManager.Stop(); } + void + Router::Die() + { + if (!_running) + return; + if (_stopping) + return; + + _stopping.store(true); + LogContext::Instance().RevertRuntimeLevel(); + LogWarn("stopping router hard"); +#if defined(WITH_SYSTEMD) + sd_notify(0, "STOPPING=1\nSTATUS=Shutting down HARD"); +#endif + hiddenServiceContext().StopAll(); + _exitContext.Stop(); + StopLinks(); + Close(); + } + void Router::Stop() { diff --git a/llarp/router/router.hpp b/llarp/router/router.hpp index 5c18717a1..fbcf96fd5 100644 --- a/llarp/router/router.hpp +++ b/llarp/router/router.hpp @@ -352,6 +352,10 @@ namespace llarp void Stop() override; + /// non graceful stop router + void + Die() override; + /// close all sessions and shutdown all links void StopLinks(); diff --git a/llarp/util/thread/logic.cpp b/llarp/util/thread/logic.cpp index 1aded0fd9..e370a490a 100644 --- a/llarp/util/thread/logic.cpp +++ b/llarp/util/thread/logic.cpp @@ -15,21 +15,13 @@ namespace llarp void Logic::Call(std::function func) { - if (can_flush()) - { - func(); - } - else - { - m_Queue(std::move(func)); - } + m_Queue(std::move(func)); } void Logic::SetQueuer(std::function)> q) { m_Queue = std::move(q); - m_Queue([self = this]() { self->m_ID = std::this_thread::get_id(); }); } uint32_t @@ -63,16 +55,11 @@ namespace llarp } } - bool - Logic::can_flush() const - { - return *m_ID == std::this_thread::get_id(); - } - void Logic::set_event_loop(llarp_ev_loop* loop) { m_Loop = loop; + SetQueuer([loop](std::function work) { loop->call_soon(work); }); } void diff --git a/llarp/util/thread/logic.hpp b/llarp/util/thread/logic.hpp index 4faf2f730..d7e26bf64 100644 --- a/llarp/util/thread/logic.hpp +++ b/llarp/util/thread/logic.hpp @@ -3,7 +3,6 @@ #include #include -#include namespace llarp { @@ -26,9 +25,6 @@ namespace llarp void remove_call(uint32_t id); - bool - can_flush() const; - void SetQueuer(std::function)> q); @@ -39,9 +35,7 @@ namespace llarp clear_event_loop(); private: - using ID_t = std::thread::id; llarp_ev_loop* m_Loop = nullptr; - std::optional m_ID; std::function)> m_Queue; }; } // namespace llarp diff --git a/test/regress/2020-06-08-key-backup-bug.cpp b/test/regress/2020-06-08-key-backup-bug.cpp index 693a55436..d10f47da0 100644 --- a/test/regress/2020-06-08-key-backup-bug.cpp +++ b/test/regress/2020-06-08-key-backup-bug.cpp @@ -64,8 +64,8 @@ TEST_CASE("key backup bug regression test", "[regress]") REQUIRE(endpointAddress != ep->GetIdentity().pub.Addr()); } } - // close the router "later" so llarp_main_run exits - ctx->CloseAsync(); + // close the router right away + ctx->router->Die(); }); REQUIRE(ctx->Run({}) == 0); ctx.reset();