Author: rgoers Date: Tue Nov 23 00:27:35 2010 New Revision: 1037953 URL: http://svn.apache.org/viewvc?rev=1037953&view=rev Log: Fix VFS-293 by converting the idle client to an AtomicReference. Make atomic objects final
Modified: commons/proper/vfs/trunk/core/src/main/java/org/apache/commons/vfs2/provider/AbstractFileSystem.java commons/proper/vfs/trunk/core/src/main/java/org/apache/commons/vfs2/provider/ftp/FtpFileSystem.java Modified: commons/proper/vfs/trunk/core/src/main/java/org/apache/commons/vfs2/provider/AbstractFileSystem.java URL: http://svn.apache.org/viewvc/commons/proper/vfs/trunk/core/src/main/java/org/apache/commons/vfs2/provider/AbstractFileSystem.java?rev=1037953&r1=1037952&r2=1037953&view=diff ============================================================================== --- commons/proper/vfs/trunk/core/src/main/java/org/apache/commons/vfs2/provider/AbstractFileSystem.java (original) +++ commons/proper/vfs/trunk/core/src/main/java/org/apache/commons/vfs2/provider/AbstractFileSystem.java Tue Nov 23 00:27:35 2010 @@ -95,7 +95,7 @@ public abstract class AbstractFileSystem /** * How many fileObjects are handed out */ - private AtomicLong useCount = new AtomicLong(0); + private final AtomicLong useCount = new AtomicLong(0); private FileSystemKey cacheKey; @@ -103,7 +103,7 @@ public abstract class AbstractFileSystem /** * open streams counter for this filesystem */ - private AtomicInteger openStreams = new AtomicInteger(0); + private final AtomicInteger openStreams = new AtomicInteger(0); protected AbstractFileSystem(final FileName rootName, final FileObject parentLayer, Modified: commons/proper/vfs/trunk/core/src/main/java/org/apache/commons/vfs2/provider/ftp/FtpFileSystem.java URL: http://svn.apache.org/viewvc/commons/proper/vfs/trunk/core/src/main/java/org/apache/commons/vfs2/provider/ftp/FtpFileSystem.java?rev=1037953&r1=1037952&r2=1037953&view=diff ============================================================================== --- commons/proper/vfs/trunk/core/src/main/java/org/apache/commons/vfs2/provider/ftp/FtpFileSystem.java (original) +++ commons/proper/vfs/trunk/core/src/main/java/org/apache/commons/vfs2/provider/ftp/FtpFileSystem.java Tue Nov 23 00:27:35 2010 @@ -29,6 +29,7 @@ import org.apache.commons.vfs2.provider. import java.io.IOException; import java.util.Collection; +import java.util.concurrent.atomic.AtomicReference; /** * An FTP file system. @@ -46,7 +47,7 @@ public class FtpFileSystem extends Abstr // private final String password; // An idle client - private FtpClient idleClient; + private final AtomicReference<FtpClient> idleClient = new AtomicReference<FtpClient>(); /** * @param rootName The root of the file system. @@ -61,17 +62,17 @@ public class FtpFileSystem extends Abstr // hostname = rootName.getHostName(); // port = rootName.getPort(); - idleClient = ftpClient; + idleClient.set(ftpClient); } @Override protected void doCloseCommunicationLink() { + FtpClient idle = idleClient.getAndSet(null); // Clean up the connection - if (idleClient != null) + if (idle != null) { - closeConnection(idleClient); - idleClient = null; + closeConnection(idle); } } @@ -112,21 +113,14 @@ public class FtpFileSystem extends Abstr */ public FtpClient getClient() throws FileSystemException { - synchronized (this) - { - if (idleClient == null || !idleClient.isConnected()) - { - idleClient = null; - - return new FTPClientWrapper((GenericFileName) getRoot().getName(), getFileSystemOptions()); - } - else - { - final FtpClient client = idleClient; - idleClient = null; - return client; - } - } + FtpClient client = idleClient.getAndSet(null); + + if (client == null || !client.isConnected()) + { + client = new FTPClientWrapper((GenericFileName) getRoot().getName(), getFileSystemOptions()); + } + + return client; } /** @@ -135,21 +129,15 @@ public class FtpFileSystem extends Abstr */ public void putClient(final FtpClient client) { - synchronized (this) - { - if (idleClient == null) - { - // Hang on to client for later - idleClient = client; - } - else - { - // Close the client - closeConnection(client); - } - } + // Save client for reuse if none is idle. + if (!idleClient.compareAndSet(null, client)) + { + // An idle client is already present so close the connection. + closeConnection(client); + } } + /** * Creates a file object. */