#ifdef _WIN32 # include #else # ifdef __FreeBSD__ # include # endif # include # include # include #endif #include "ResolvService.hpp" ResolvService::ResolvService( uint16_t port ) : m_exit( false ) , m_port( port ) #ifndef __EMSCRIPTEN__ , m_thread( [this] { Worker(); } ) #endif { } ResolvService::~ResolvService() { #ifndef __EMSCRIPTEN__ m_exit.store( true, std::memory_order_relaxed ); m_cv.notify_one(); m_thread.join(); #endif } void ResolvService::Query( uint32_t ip, const std::function& callback ) { #ifndef __EMSCRIPTEN__ std::lock_guard lock( m_lock ); m_queue.emplace_back( QueueItem { ip, callback } ); m_cv.notify_one(); #endif } void ResolvService::Worker() { struct sockaddr_in addr = {}; addr.sin_family = AF_INET; addr.sin_port = htons( m_port ); char buf[128]; for(;;) { std::unique_lock lock( m_lock ); m_cv.wait( lock, [this] { return !m_queue.empty() || m_exit.load( std::memory_order_relaxed ); } ); if( m_exit.load( std::memory_order_relaxed ) ) return; auto query = m_queue.back(); m_queue.pop_back(); lock.unlock(); addr.sin_addr.s_addr = query.ip; if( getnameinfo( (const struct sockaddr*)&addr, sizeof( sockaddr_in ), buf, 128, nullptr, 0, NI_NOFQDN ) != 0 ) { inet_ntop( AF_INET, &query.ip, buf, 17 ); } query.callback( buf ); } }