diff --git a/src/client.cpp b/src/client.cpp index 58fe56aeb..52c3810f9 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -28,6 +28,7 @@ namespace pvxs { namespace client { constexpr timeval bucketInterval{1,0}; +constexpr timeval initialSearchDelay{0, 10000}; // 10 ms constexpr size_t nBuckets = 30u; // try not to fragment with usual MTU==1500 @@ -498,6 +499,8 @@ ContextImpl::ContextImpl(const Config& conf, const evbase& tcp_loop) event_new(tcp_loop.base, searchTx6.sock, EV_READ|EV_PERSIST, &ContextImpl::onSearchS, this)) ,searchTimer(__FILE__, __LINE__, event_new(tcp_loop.base, -1, EV_TIMEOUT, &ContextImpl::tickSearchS, this)) + ,initialSearcher(__FILE__, __LINE__, + event_new(tcp_loop.base, -1, EV_TIMEOUT, &ContextImpl::initialSearchS, this)) ,manager(UDPManager::instance(effective.shareUDP())) ,beaconCleaner(__FILE__, __LINE__, event_new(manager.loop().base, -1, EV_TIMEOUT|EV_PERSIST, &ContextImpl::tickBeaconCleanS, this)) @@ -701,9 +704,8 @@ void ContextImpl::scheduleInitialSearch() log_debug_printf(setup, "scheduleInitialSearch()%s\n", ""); initialSearchScheduled = true; - tcp_loop.dispatch([this]() { - tickSearch(SearchKind::initial); - }); + if (event_add(initialSearcher.get(), &initialSearchDelay)) + throw std::runtime_error("Unable to schedule initialSearcher"); } } @@ -1186,6 +1188,15 @@ void ContextImpl::tickSearchS(evutil_socket_t fd, short evt, void *raw) } } +void ContextImpl::initialSearchS(evutil_socket_t fd, short evt, void *raw) +{ + try { + static_cast(raw)->tickSearch(SearchKind::initial); + }catch(std::exception& e){ + log_exc_printf(io, "Unhandled error in initial search callback: %s\n", e.what()); + } +} + void ContextImpl::tickBeaconClean() { epicsTimeStamp now; diff --git a/src/clientimpl.h b/src/clientimpl.h index 8a0506a28..c9aeed001 100644 --- a/src/clientimpl.h +++ b/src/clientimpl.h @@ -311,6 +311,7 @@ struct ContextImpl : public std::enable_shared_from_this evbase tcp_loop; const evevent searchRx4, searchRx6; const evevent searchTimer; + const evevent initialSearcher; // beacon handling done on UDP worker. // we keep a ref here as long as beaconCleaner is in use @@ -344,6 +345,7 @@ struct ContextImpl : public std::enable_shared_from_this enum class SearchKind { discover, initial, check }; void tickSearch(SearchKind kind); static void tickSearchS(evutil_socket_t fd, short evt, void *raw); + static void initialSearchS(evutil_socket_t fd, short evt, void *raw); void tickBeaconClean(); static void tickBeaconCleanS(evutil_socket_t fd, short evt, void *raw); void cacheClean(const std::string &name, Context::cacheAction force);