diff --git a/net/test/test.cpp b/net/test/test.cpp index a61d6f72..ad182a06 100644 --- a/net/test/test.cpp +++ b/net/test/test.cpp @@ -714,9 +714,9 @@ TEST(utils, resolver) { DEFER(delete resolver); net::IPAddr localhost("127.0.0.1"); net::IPAddr addr = resolver->resolve("localhost"); - EXPECT_EQ(localhost.to_nl(), addr.to_nl()); + if (addr.is_ipv4()) EXPECT_EQ(localhost.to_nl(), addr.to_nl()); auto func = [&](net::IPAddr addr_){ - EXPECT_EQ(localhost.to_nl(), addr_.to_nl()); + if (addr_.is_ipv4()) EXPECT_EQ(localhost.to_nl(), addr_.to_nl()); }; resolver->resolve("localhost", func); resolver->discard_cache("non-exist-host.com"); diff --git a/net/utils.cpp b/net/utils.cpp index efbe1bac..ad9209d8 100644 --- a/net/utils.cpp +++ b/net/utils.cpp @@ -260,7 +260,12 @@ class DefaultResolver : public Resolver { public: DefaultResolver(uint64_t cache_ttl, uint64_t resolve_timeout) : dnscache_(cache_ttl), resolve_timeout_(resolve_timeout) {} - ~DefaultResolver() { dnscache_.clear(); } + ~DefaultResolver() { + for (auto it : dnscache_) { + ((IPAddrList*)it->_obj)->delete_all(); + } + dnscache_.clear(); + } IPAddr resolve(const char *host) override { auto ctr = [&]() -> IPAddrList* { @@ -287,10 +292,7 @@ class DefaultResolver : public Resolver { auto ips = dnscache_.borrow(host, ctr); if (ips->empty()) LOG_ERRNO_RETURN(0, IPAddr(), "Domain resolution for ` failed", host); auto ret = ips->front(); - if (!ret->single()) { // access in round robin order - auto front = ips->pop_front(); - ips->push_back(front); - } + ips->node = ret->next(); // access in round robin order return ret->addr; } @@ -300,9 +302,9 @@ class DefaultResolver : public Resolver { auto ipaddr = dnscache_.borrow(host); if (ip.undefined() || ipaddr->empty()) ipaddr.recycle(true); else { - for (auto it : *ipaddr) { - if (it->addr == ip) { - ipaddr->erase(it); + for (auto itr = ipaddr->rbegin(); itr != ipaddr->rend(); itr++) { + if ((*itr)->addr == ip) { + ipaddr->erase(*itr); break; } } diff --git a/thread/list.h b/thread/list.h index 435f8aa8..3f42a8de 100644 --- a/thread/list.h +++ b/thread/list.h @@ -221,6 +221,48 @@ class intrusive_list_node : public __intrusive_list_node { return {nullptr, nullptr}; } + + struct reverse_iterator + { + __intrusive_list_node* ptr; + __intrusive_list_node* end; + T* operator*() + { + return static_cast(ptr); + } + reverse_iterator& operator++() + { + ptr = ptr->__prev_ptr; + if (ptr == end) + ptr = nullptr; + return *this; + } + reverse_iterator operator++(int) + { + auto rst = *this; + ptr = ptr->__prev_ptr; + if (ptr == end) + ptr = nullptr; + return rst; + } + bool operator == (const reverse_iterator& rhs) const + { + return ptr == rhs.ptr; + } + bool operator != (const reverse_iterator& rhs) const + { + return !(*this == rhs); + } + }; + + reverse_iterator rbegin() + { + return {this->__prev_ptr, this->__prev_ptr}; + } + reverse_iterator rend() + { + return {nullptr, nullptr}; + } }; @@ -321,6 +363,7 @@ class intrusive_list return node == nullptr; } typedef typename NodeType::iterator iterator; + typedef typename NodeType::reverse_iterator reverse_iterator; iterator begin() { return node ? node->begin() : end(); @@ -329,6 +372,14 @@ class intrusive_list { return {nullptr, nullptr}; } + reverse_iterator rbegin() + { + return node ? node->rbegin() : rend(); + } + reverse_iterator rend() + { + return {nullptr, nullptr}; + } intrusive_list split_front_inclusive(NodeType* ptr) { auto ret = node;