From 23b78703a7594d130a1095e5c587735163e2c1af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20B=C3=A9raud?= <adrien.beraud@savoirfairelinux.com> Date: Wed, 15 Aug 2018 14:34:23 -0400 Subject: [PATCH] eventLoop: run SIP and DHT out of the main thread Change-Id: I52a3151eb30c5151dab448cdab00732afb3d5d2d Reviewed-by: Sebastien Blin <sebastien.blin@savoirfairelinux.com> --- src/ringdht/ringaccount.cpp | 18 +++--------------- src/ringdht/ringaccount.h | 2 -- src/sip/sipvoiplink.cpp | 31 +++++++++++-------------------- src/sip/sipvoiplink.h | 4 ++++ 4 files changed, 18 insertions(+), 37 deletions(-) diff --git a/src/ringdht/ringaccount.cpp b/src/ringdht/ringaccount.cpp index fb6f168c7d..84306539ca 100644 --- a/src/ringdht/ringaccount.cpp +++ b/src/ringdht/ringaccount.cpp @@ -1626,16 +1626,6 @@ RingAccount::registerName(const std::string& /*password*/, const std::string& na } #endif -void -RingAccount::handleEvents() -{ - // Process DHT events - dht_.loop(); - - // Call msg in "callto:" - handlePendingCallList(); -} - void RingAccount::handlePendingCallList() { @@ -1648,11 +1638,9 @@ RingAccount::handlePendingCallList() pendingCalls_.clear(); } - static const dht::InfoHash invalid_hash; // Invariant - auto pc_iter = std::begin(pending_calls); while (pc_iter != std::end(pending_calls)) { - bool incoming = pc_iter->call_key == invalid_hash; // do it now, handlePendingCall may invalidate pc data + bool incoming = !pc_iter->call_key; // do it now, handlePendingCall may invalidate pc data bool handled; try { @@ -2101,7 +2089,7 @@ RingAccount::doRegister_() config.dht_config.id = identity_; config.proxy_server = proxyEnabled_ ? proxyServer_ : std::string(); config.push_node_id = getAccountID(); - config.threaded = false; + config.threaded = true; if (not config.proxy_server.empty()) RING_WARN("[Account %s] using proxy server %s", getAccountID().c_str(), config.proxy_server.c_str()); @@ -2152,7 +2140,7 @@ RingAccount::doRegister_() dht_.importValues(loadValues()); - Manager::instance().registerEventHandler((uintptr_t)this, [this]{ handleEvents(); }); + Manager::instance().registerEventHandler((uintptr_t)this, [this]{ handlePendingCallList(); }); setRegistrationState(RegistrationState::TRYING); dht_.bootstrap(loadNodes()); diff --git a/src/ringdht/ringaccount.h b/src/ringdht/ringaccount.h index b2b5ebb5c2..065d3cf4fe 100644 --- a/src/ringdht/ringaccount.h +++ b/src/ringdht/ringaccount.h @@ -439,8 +439,6 @@ class RingAccount : public SIPAccountBase { const dht::ValueType USER_PROFILE_TYPE = {9, "User profile", std::chrono::hours(24 * 7)}; - void handleEvents(); - void startOutgoingCall(const std::shared_ptr<SIPCall>& call, const std::string toUri); void onConnectedOutgoingCall(SIPCall& call, const std::string& to_id, IpAddr target); diff --git a/src/sip/sipvoiplink.cpp b/src/sip/sipvoiplink.cpp index c4c16fa49d..1e8926e990 100644 --- a/src/sip/sipvoiplink.cpp +++ b/src/sip/sipvoiplink.cpp @@ -597,11 +597,11 @@ SIPVoIPLink::SIPVoIPLink() : pool_(nullptr, pj_pool_release) TRY(pjsip_replaces_init_module(endpt_)); #undef TRY - // ready to handle events - // Implementation note: we don't use std::bind(xxx, this) here - // as handleEvents needs a valid instance to be called. - Manager::instance().registerEventHandler((uintptr_t)this, - [this]{ handleEvents(); }); + sipThread_ = std::thread([this]{ + sip_utils::register_thread(); + while (running_) + handleEvents(); + }); RING_DBG("SIPVoIPLink@%p", this); } @@ -610,6 +610,8 @@ SIPVoIPLink::~SIPVoIPLink() { RING_DBG("~SIPVoIPLink@%p", this); + running_ = false; + // Remaining calls should not happen as possible upper callbacks // may be called and another instance of SIPVoIPLink can be re-created! @@ -626,16 +628,13 @@ SIPVoIPLink::~SIPVoIPLink() std::this_thread::sleep_for(std::chrono::seconds(1)); pjsip_tpmgr_set_state_cb(pjsip_endpt_get_tpmgr(endpt_), nullptr); - Manager::instance().unregisterEventHandler((uintptr_t)this); - try { - handleEvents(); - } catch (...) {} sipTransportBroker.reset(); pjsip_endpt_destroy(endpt_); pool_.reset(); pj_caching_pool_destroy(&cp_); + sipThread_.join(); RING_DBG("destroying SIPVoIPLink@%p", this); } @@ -692,11 +691,8 @@ SIPVoIPLink::guessAccount(const std::string& userName, void SIPVoIPLink::handleEvents() { - sip_utils::register_thread(); - - static const pj_time_val timeout = {0, 0}; // polling - auto ret = pjsip_endpt_handle_events(endpt_, &timeout); - if (ret != PJ_SUCCESS) + const pj_time_val timeout = {10, 0}; + if (auto ret = pjsip_endpt_handle_events(endpt_, &timeout)) RING_ERR("pjsip_endpt_handle_events failed with error %s", sip_utils::sip_strerror(ret).c_str()); @@ -765,12 +761,7 @@ SIPVoIPLink::dequeKeyframeRequests() void SIPVoIPLink::requestKeyframe(const std::string &callID) { - std::shared_ptr<SIPCall> call; - const int tries = 10; - - for (int i = 0; !call and i < tries; ++i) - call = Manager::instance().callFactory.getCall<SIPCall>(callID); // fixme: need a try version - + auto call = Manager::instance().callFactory.getCall<SIPCall>(callID); if (!call) return; diff --git a/src/sip/sipvoiplink.h b/src/sip/sipvoiplink.h index 1dbcdce115..2e02dc7914 100644 --- a/src/sip/sipvoiplink.h +++ b/src/sip/sipvoiplink.h @@ -47,6 +47,8 @@ #include <mutex> #include <memory> #include <functional> +#include <thread> +#include <atomic> namespace ring { @@ -161,6 +163,8 @@ class SIPVoIPLink { mutable pj_caching_pool cp_; std::unique_ptr<pj_pool_t, decltype(pj_pool_release)&> pool_; + std::atomic_bool running_ {true}; + std::thread sipThread_; #ifdef RING_VIDEO void dequeKeyframeRequests(); -- GitLab