From 3f7ddbf313aaabbfba4650cb2036cb41e51a9bde Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Thu, 18 Apr 2013 11:37:28 +0000
Subject: [PATCH] Fix OPENDJ-838: Add ConnectionFactory.close() method to facilitate resource cleanup after application exit
---
opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPConnectionFactoryImpl.java | 53 ++++++++++++++++++++++++++++++++++-------------------
1 files changed, 34 insertions(+), 19 deletions(-)
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPConnectionFactoryImpl.java b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPConnectionFactoryImpl.java
index 706e9b3..9a60962 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPConnectionFactoryImpl.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/com/forgerock/opendj/ldap/LDAPConnectionFactoryImpl.java
@@ -27,11 +27,14 @@
package com.forgerock.opendj.ldap;
+import static com.forgerock.opendj.ldap.DefaultTCPNIOTransport.DEFAULT_TRANSPORT;
+import static com.forgerock.opendj.ldap.TimeoutChecker.TIMEOUT_CHECKER;
import static org.forgerock.opendj.ldap.ErrorResultException.*;
import java.io.IOException;
import java.net.SocketAddress;
import java.util.concurrent.ExecutionException;
+import java.util.concurrent.atomic.AtomicBoolean;
import javax.net.ssl.SSLEngine;
@@ -55,6 +58,7 @@
import org.glassfish.grizzly.nio.transport.TCPNIOTransport;
import com.forgerock.opendj.util.AsynchronousFutureResult;
+import com.forgerock.opendj.util.ReferenceCountedObject;
/**
* LDAP connection factory implementation.
@@ -154,10 +158,14 @@
}
private LDAPConnection adaptConnection(final org.glassfish.grizzly.Connection<?> connection) {
- // Test shows that its much faster with non block writes but risk
- // running out of memory if the server is slow.
+ /*
+ * Test shows that its much faster with non block writes but risk
+ * running out of memory if the server is slow.
+ */
connection.configureBlocking(true);
- final LDAPConnection ldapConnection = new LDAPConnection(connection, options);
+ final LDAPConnection ldapConnection =
+ new LDAPConnection(connection, LDAPConnectionFactoryImpl.this);
+ timeoutChecker.get().addConnection(ldapConnection);
clientFilter.registerConnection(connection, ldapConnection);
return ldapConnection;
}
@@ -194,7 +202,10 @@
private final FilterChain defaultFilterChain;
private final LDAPOptions options;
private final SocketAddress socketAddress;
- private final TCPNIOTransport transport;
+ private final ReferenceCountedObject<TCPNIOTransport>.Reference transport;
+ private final AtomicBoolean isClosed = new AtomicBoolean();
+ private final ReferenceCountedObject<TimeoutChecker>.Reference timeoutChecker = TIMEOUT_CHECKER
+ .acquire();
/**
* Creates a new LDAP connection factory implementation which can be used to
@@ -207,11 +218,7 @@
* The LDAP connection options to use when creating connections.
*/
public LDAPConnectionFactoryImpl(final SocketAddress address, final LDAPOptions options) {
- if (options.getTCPNIOTransport() == null) {
- this.transport = DefaultTCPNIOTransport.getInstance();
- } else {
- this.transport = options.getTCPNIOTransport();
- }
+ this.transport = DEFAULT_TRANSPORT.acquireIfNull(options.getTCPNIOTransport());
this.socketAddress = address;
this.options = new LDAPOptions(options);
this.clientFilter =
@@ -220,9 +227,14 @@
FilterChainBuilder.stateless().add(new TransportFilter()).add(clientFilter).build();
}
- /**
- * {@inheritDoc}
- */
+ @Override
+ public void close() {
+ if (isClosed.compareAndSet(false, true)) {
+ transport.release();
+ timeoutChecker.release();
+ }
+ }
+
@Override
public Connection getConnection() throws ErrorResultException {
try {
@@ -232,14 +244,12 @@
}
}
- /**
- * {@inheritDoc}
- */
@Override
public FutureResult<Connection> getConnectionAsync(
final ResultHandler<? super Connection> handler) {
final SocketConnectorHandler connectorHandler =
- TCPNIOConnectorHandler.builder(transport).processor(defaultFilterChain).build();
+ TCPNIOConnectorHandler.builder(transport.get()).processor(defaultFilterChain)
+ .build();
final AsynchronousFutureResult<Connection, ResultHandler<? super Connection>> future =
new AsynchronousFutureResult<Connection, ResultHandler<? super Connection>>(handler);
final CompletionHandlerAdapter cha = new CompletionHandlerAdapter(future);
@@ -256,9 +266,14 @@
return socketAddress;
}
- /**
- * {@inheritDoc}
- */
+ TimeoutChecker getTimeoutChecker() {
+ return timeoutChecker.get();
+ }
+
+ LDAPOptions getLDAPOptions() {
+ return options;
+ }
+
@Override
public String toString() {
final StringBuilder builder = new StringBuilder();
--
Gitblit v1.10.0