@@ -266,36 +266,59 @@ class DefaultResolver : public Resolver {
266266 struct IPAddrList : public intrusive_list <IPAddrNode>, spinlock {
267267 ~IPAddrList () { delete_all (); }
268268 };
269+ struct ResolveCtx {
270+ std::string host;
271+ Delegate<bool , IPAddr> filter;
272+ spinlock lock;
273+ IPAddrList *addrs;
274+ photon::semaphore sem;
275+ };
269276 IPAddr do_resolve (std::string_view host, Delegate<bool , IPAddr> filter) {
270277 auto ctr = [&]() -> IPAddrList* {
271278 auto addrs = new IPAddrList ();
272- photon::semaphore sem;
273- std::thread ([&]() {
274- auto now = std::chrono::steady_clock::now ();
279+ std::shared_ptr<ResolveCtx> ctx = std::make_shared<ResolveCtx>();
280+ ctx->addrs = addrs;
281+ ctx->host = std::string (host);
282+ ctx->filter = filter;
283+ std::thread ([ctx]() {
275284 IPAddrList ret;
276285 auto cb = [&](IPAddr addr) -> int {
277- if (filter && !filter.fire (addr))
286+ SCOPED_LOCK (ctx->lock );
287+ if (ctx->filter && !ctx->filter .fire (addr))
278288 return 0 ;
279289 ret.push_back (new IPAddrNode (addr));
280290 return 0 ;
281291 };
282- _gethostbyname (host, cb);
283- auto time_elapsed = std::chrono::duration_cast<std::chrono::microseconds>(
284- std::chrono::steady_clock::now () - now).count ();
285- if ((uint64_t )time_elapsed <= resolve_timeout_) {
286- addrs->push_back (std::move (ret));
287- sem.signal (1 );
288- } else {
289- LOG_ERROR (" resolve timeout" );
290- while (!ret.empty ())
291- delete ret.pop_front ();
292+ _gethostbyname (ctx->host , cb);
293+ {
294+ SCOPED_LOCK (ctx->lock );
295+ if (ctx->addrs ) {
296+ ctx->addrs ->push_back (std::move (ret));
297+ ctx->sem .signal (1 );
298+ } else {
299+ LOG_ERROR (" resolve timeout" );
300+ while (!ret.empty ())
301+ delete ret.pop_front ();
302+ }
292303 }
293304 }).detach ();
294- sem.wait (1 , resolve_timeout_);
305+ ctx->sem .wait (1 , resolve_timeout_);
306+ {
307+ SCOPED_LOCK (ctx->lock );
308+ ctx->addrs = nullptr ;
309+ ctx->filter = {};
310+ }
311+ if (addrs->empty ()) {
312+ delete addrs;
313+ return nullptr ;
314+ }
295315 return addrs;
296316 };
297- auto ips = dnscache_.borrow (host, ctr);
298- if (ips->empty ()) LOG_ERRNO_RETURN (0 , IPAddr (), " Domain resolution for '`' failed" , host);
317+ auto ips = dnscache_.borrow (host, ctr, 1UL * 1000 );
318+ if (!ips || ips->empty ()) {
319+ ips.recycle (true );
320+ LOG_ERRNO_RETURN (0 , IPAddr (), " Domain resolution for '`' failed" , host);
321+ }
299322 SCOPED_LOCK (*ips);
300323 auto ret = ips->front ();
301324 ips->node = ret->next (); // access in round robin order
0 commit comments