Fix another resource leak in DnsNameResolver

- Fix a bug in cache expiration task; wrong object was being released
- Added more sanity checks when caching an entry
This commit is contained in:
Trustin Lee 2014-10-17 11:38:43 +09:00
parent e809f97136
commit 29a847587f
2 changed files with 18 additions and 11 deletions

View File

@ -726,14 +726,17 @@ public class DnsNameResolver extends SimpleNameResolver<InetSocketAddress> {
} }
void cache(final DnsQuestion question, DnsCacheEntry entry, long delaySeconds) { void cache(final DnsQuestion question, DnsCacheEntry entry, long delaySeconds) {
queryCache.put(question, entry); DnsCacheEntry oldEntry = queryCache.put(question, entry);
if (oldEntry != null) {
oldEntry.release();
}
boolean scheduled = false; boolean scheduled = false;
try { try {
entry.expirationFuture = ch.eventLoop().schedule(new OneTimeTask() { entry.expirationFuture = ch.eventLoop().schedule(new OneTimeTask() {
@Override @Override
public void run() { public void run() {
Object response = queryCache.remove(question); clearCache(question);
ReferenceCountUtil.safeRelease(response);
} }
}, delaySeconds, TimeUnit.SECONDS); }, delaySeconds, TimeUnit.SECONDS);
@ -742,7 +745,7 @@ public class DnsNameResolver extends SimpleNameResolver<InetSocketAddress> {
if (!scheduled) { if (!scheduled) {
// If failed to schedule the expiration task, // If failed to schedule the expiration task,
// remove the entry from the cache so that it does not leak. // remove the entry from the cache so that it does not leak.
queryCache.remove(question); clearCache(question);
entry.release(); entry.release();
} }
} }
@ -789,12 +792,16 @@ public class DnsNameResolver extends SimpleNameResolver<InetSocketAddress> {
if (res.header().responseCode() == DnsResponseCode.NOERROR) { if (res.header().responseCode() == DnsResponseCode.NOERROR) {
cache(q, res); cache(q, res);
promises.set(queryId, null); promises.set(queryId, null);
qCtx.promise().trySuccess(res.retain());
Promise<DnsResponse> qPromise = qCtx.promise();
if (qPromise.setUncancellable()) {
qPromise.setSuccess(res.retain());
}
} else { } else {
qCtx.retry(res.sender(), qCtx.retry(res.sender(),
"response code: " + res.header().responseCode() + "response code: " + res.header().responseCode() +
" with " + res.answers().size() + " answer(s) and " + " with " + res.answers().size() + " answer(s) and " +
res.authorityResources().size() + " authority resource(s)"); res.authorityResources().size() + " authority resource(s)");
} }
} finally { } finally {
ReferenceCountUtil.safeRelease(msg); ReferenceCountUtil.safeRelease(msg);

View File

@ -30,8 +30,8 @@ import io.netty.util.internal.StringUtil;
import io.netty.util.internal.ThreadLocalRandom; import io.netty.util.internal.ThreadLocalRandom;
import io.netty.util.internal.logging.InternalLogger; import io.netty.util.internal.logging.InternalLogger;
import io.netty.util.internal.logging.InternalLoggerFactory; import io.netty.util.internal.logging.InternalLoggerFactory;
import org.junit.After;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import java.net.Inet4Address; import java.net.Inet4Address;
@ -253,8 +253,8 @@ public class DnsNameResolverTest {
group.shutdownGracefully(); group.shutdownGracefully();
} }
@Before @After
public void reset() { public void reset() throws Exception {
resolver.clearCache(); resolver.clearCache();
} }