mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-19 22:25:52 +02:00
Use Mutex to avoid parallel FTP directory queries
This commit is contained in:
parent
ec66da7bf4
commit
003e578773
1 changed files with 163 additions and 100 deletions
|
@ -36,6 +36,7 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.core.runtime.IProgressMonitor;
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
|
import org.eclipse.rse.services.Mutex;
|
||||||
import org.eclipse.rse.services.clientserver.NamePatternMatcher;
|
import org.eclipse.rse.services.clientserver.NamePatternMatcher;
|
||||||
import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
|
import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
|
||||||
import org.eclipse.rse.services.files.AbstractFileService;
|
import org.eclipse.rse.services.files.AbstractFileService;
|
||||||
|
@ -50,6 +51,9 @@ import sun.net.ftp.FtpClient;
|
||||||
public class FTPService extends AbstractFileService implements IFileService, IFTPService
|
public class FTPService extends AbstractFileService implements IFileService, IFTPService
|
||||||
{
|
{
|
||||||
private FTPClientService _ftpClient;
|
private FTPClientService _ftpClient;
|
||||||
|
private Mutex _mutex = new Mutex();
|
||||||
|
private long _mutexTimeout = 5000; //max.5 seconds to obtain dir channel
|
||||||
|
|
||||||
private String _userHome;
|
private String _userHome;
|
||||||
private IFTPDirectoryListingParser _ftpPropertiesUtil;
|
private IFTPDirectoryListingParser _ftpPropertiesUtil;
|
||||||
|
|
||||||
|
@ -151,6 +155,7 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
|
||||||
|
|
||||||
public IHostFile getFile(IProgressMonitor monitor, String remoteParent, String fileName)
|
public IHostFile getFile(IProgressMonitor monitor, String remoteParent, String fileName)
|
||||||
{
|
{
|
||||||
|
//No Mutex lock needed here because internalFetch() does the lock
|
||||||
IHostFile[] matches = internalFetch(monitor, remoteParent, fileName, FILE_TYPE_FILES_AND_FOLDERS);
|
IHostFile[] matches = internalFetch(monitor, remoteParent, fileName, FILE_TYPE_FILES_AND_FOLDERS);
|
||||||
if (matches != null && matches.length > 0)
|
if (matches != null && matches.length > 0)
|
||||||
{
|
{
|
||||||
|
@ -174,44 +179,51 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
|
||||||
}
|
}
|
||||||
NamePatternMatcher filematcher = new NamePatternMatcher(fileFilter, true, true);
|
NamePatternMatcher filematcher = new NamePatternMatcher(fileFilter, true, true);
|
||||||
List results = new ArrayList();
|
List results = new ArrayList();
|
||||||
try
|
if (_mutex.waitForLock(monitor, _mutexTimeout))
|
||||||
{
|
{
|
||||||
FtpClient ftp = getFTPClient();
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ftp.noop();
|
FtpClient ftp = getFTPClient();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ftp.noop();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
//e.printStackTrace();
|
||||||
|
disconnect();
|
||||||
|
|
||||||
|
// probably timed out
|
||||||
|
reconnect();
|
||||||
|
ftp = getFTPClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
ftp.cd(parentPath);
|
||||||
|
TelnetInputStream stream = ftp.list();
|
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
|
||||||
|
String line = reader.readLine();
|
||||||
|
while (line != null)
|
||||||
|
{
|
||||||
|
FTPHostFile node = getDirListingParser().getFTPHostFile(line, parentPath);
|
||||||
|
if (node != null && filematcher.matches(node.getName()))
|
||||||
|
{
|
||||||
|
if (isRightType(fileType, node))
|
||||||
|
{
|
||||||
|
results.add(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
line = reader.readLine();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
//e.printStackTrace();
|
e.printStackTrace();
|
||||||
disconnect();
|
|
||||||
|
|
||||||
// probably timed out
|
|
||||||
reconnect();
|
|
||||||
ftp = getFTPClient();
|
|
||||||
}
|
}
|
||||||
|
finally
|
||||||
ftp.cd(parentPath);
|
|
||||||
TelnetInputStream stream = ftp.list();
|
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
|
|
||||||
String line = reader.readLine();
|
|
||||||
while (line != null)
|
|
||||||
{
|
{
|
||||||
FTPHostFile node = getDirListingParser().getFTPHostFile(line, parentPath);
|
_mutex.release();
|
||||||
if (node != null && filematcher.matches(node.getName()))
|
|
||||||
{
|
|
||||||
if (isRightType(fileType, node))
|
|
||||||
{
|
|
||||||
results.add(node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
line = reader.readLine();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return (IHostFile[])results.toArray(new IHostFile[results.size()]);
|
return (IHostFile[])results.toArray(new IHostFile[results.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,50 +283,57 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
|
||||||
|
|
||||||
public boolean download(IProgressMonitor monitor, String remoteParent, String remoteFile, File localFile, boolean isBinary, String hostEncoding)
|
public boolean download(IProgressMonitor monitor, String remoteParent, String remoteFile, File localFile, boolean isBinary, String hostEncoding)
|
||||||
{
|
{
|
||||||
FtpClient ftp = getFTPClient();
|
if (_mutex.waitForLock(monitor, _mutexTimeout))
|
||||||
try
|
|
||||||
{
|
{
|
||||||
ftp.cd(remoteParent);
|
try
|
||||||
/*
|
|
||||||
if (isBinary)
|
|
||||||
ftp.binary();
|
|
||||||
else
|
|
||||||
ftp.ascii();
|
|
||||||
*/
|
|
||||||
// for now only binary seems to work
|
|
||||||
ftp.binary();
|
|
||||||
|
|
||||||
InputStream is = ftp.get(remoteFile);
|
|
||||||
BufferedInputStream bis = new BufferedInputStream(is);
|
|
||||||
|
|
||||||
if (!localFile.exists())
|
|
||||||
{
|
{
|
||||||
File localParentFile = localFile.getParentFile();
|
FtpClient ftp = getFTPClient();
|
||||||
if (!localParentFile.exists())
|
ftp.cd(remoteParent);
|
||||||
|
/*
|
||||||
|
if (isBinary)
|
||||||
|
ftp.binary();
|
||||||
|
else
|
||||||
|
ftp.ascii();
|
||||||
|
*/
|
||||||
|
// for now only binary seems to work
|
||||||
|
ftp.binary();
|
||||||
|
|
||||||
|
InputStream is = ftp.get(remoteFile);
|
||||||
|
BufferedInputStream bis = new BufferedInputStream(is);
|
||||||
|
|
||||||
|
if (!localFile.exists())
|
||||||
{
|
{
|
||||||
localParentFile.mkdirs();
|
File localParentFile = localFile.getParentFile();
|
||||||
|
if (!localParentFile.exists())
|
||||||
|
{
|
||||||
|
localParentFile.mkdirs();
|
||||||
|
}
|
||||||
|
localFile.createNewFile();
|
||||||
}
|
}
|
||||||
localFile.createNewFile();
|
OutputStream os = new FileOutputStream(localFile);
|
||||||
|
BufferedOutputStream bos = new BufferedOutputStream(os);
|
||||||
|
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
int totalWrote = 0;
|
||||||
|
int readCount;
|
||||||
|
while( (readCount = bis.read(buffer)) > 0)
|
||||||
|
{
|
||||||
|
bos.write(buffer, 0, readCount);
|
||||||
|
totalWrote += readCount;
|
||||||
|
}
|
||||||
|
bos.close();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_mutex.release();
|
||||||
}
|
}
|
||||||
OutputStream os = new FileOutputStream(localFile);
|
|
||||||
BufferedOutputStream bos = new BufferedOutputStream(os);
|
|
||||||
|
|
||||||
byte[] buffer = new byte[1024];
|
|
||||||
int totalWrote = 0;
|
|
||||||
int readCount;
|
|
||||||
while( (readCount = bis.read(buffer)) > 0)
|
|
||||||
{
|
|
||||||
bos.write(buffer, 0, readCount);
|
|
||||||
totalWrote += readCount;
|
|
||||||
}
|
|
||||||
bos.close();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
return false;
|
||||||
{
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IHostFile getUserHome()
|
public IHostFile getUserHome()
|
||||||
|
@ -336,13 +355,19 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
|
||||||
*/
|
*/
|
||||||
public boolean delete(IProgressMonitor monitor, String remoteParent, String fileName) {
|
public boolean delete(IProgressMonitor monitor, String remoteParent, String fileName) {
|
||||||
boolean hasSucceeded = false;
|
boolean hasSucceeded = false;
|
||||||
try {
|
if (_mutex.waitForLock(monitor, _mutexTimeout)) {
|
||||||
getFTPClient().cd(remoteParent);
|
try {
|
||||||
int returnedValue = getFTPClient().sendCommand("DELE " + fileName);
|
getFTPClient().cd(remoteParent);
|
||||||
hasSucceeded = (returnedValue > 0);
|
int returnedValue = getFTPClient().sendCommand("DELE " + fileName);
|
||||||
} catch (IOException e) {
|
hasSucceeded = (returnedValue > 0);
|
||||||
// Changing folder raised an exception
|
}
|
||||||
hasSucceeded = false;
|
catch (IOException e) {
|
||||||
|
// Changing folder raised an exception
|
||||||
|
hasSucceeded = false;
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
_mutex.release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return hasSucceeded;
|
return hasSucceeded;
|
||||||
}
|
}
|
||||||
|
@ -352,10 +377,17 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
|
||||||
*/
|
*/
|
||||||
public boolean rename(IProgressMonitor monitor, String remoteParent, String oldName, String newName) {
|
public boolean rename(IProgressMonitor monitor, String remoteParent, String oldName, String newName) {
|
||||||
boolean hasSucceeded = false;
|
boolean hasSucceeded = false;
|
||||||
int returnedValue = getFTPClient().sendCommand("RNFR " + remoteParent + getSeparator() + oldName);
|
if (_mutex.waitForLock(monitor, _mutexTimeout)) {
|
||||||
if (returnedValue > 0) {
|
try {
|
||||||
returnedValue = getFTPClient().sendCommand("RNTO " + remoteParent + getSeparator() + newName);
|
int returnedValue = getFTPClient().sendCommand("RNFR " + remoteParent + getSeparator() + oldName);
|
||||||
hasSucceeded = (returnedValue > 0);
|
if (returnedValue > 0) {
|
||||||
|
returnedValue = getFTPClient().sendCommand("RNTO " + remoteParent + getSeparator() + newName);
|
||||||
|
hasSucceeded = (returnedValue > 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
_mutex.release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return hasSucceeded;
|
return hasSucceeded;
|
||||||
}
|
}
|
||||||
|
@ -365,10 +397,17 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
|
||||||
*/
|
*/
|
||||||
public boolean rename(IProgressMonitor monitor, String remoteParent, String oldName, String newName, IHostFile oldFile) {
|
public boolean rename(IProgressMonitor monitor, String remoteParent, String oldName, String newName, IHostFile oldFile) {
|
||||||
boolean hasSucceeded = false;
|
boolean hasSucceeded = false;
|
||||||
int returnedValue = getFTPClient().sendCommand("RNFR " + remoteParent + getSeparator() + oldName);
|
if (_mutex.waitForLock(monitor, _mutexTimeout)) {
|
||||||
if (returnedValue > 0) {
|
try {
|
||||||
returnedValue = getFTPClient().sendCommand("RNTO " + remoteParent + getSeparator() + newName);
|
int returnedValue = getFTPClient().sendCommand("RNFR " + remoteParent + getSeparator() + oldName);
|
||||||
hasSucceeded = (returnedValue > 0);
|
if (returnedValue > 0) {
|
||||||
|
returnedValue = getFTPClient().sendCommand("RNTO " + remoteParent + getSeparator() + newName);
|
||||||
|
hasSucceeded = (returnedValue > 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
_mutex.release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return hasSucceeded;
|
return hasSucceeded;
|
||||||
}
|
}
|
||||||
|
@ -378,10 +417,17 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
|
||||||
*/
|
*/
|
||||||
public boolean move(IProgressMonitor monitor, String srcParent, String srcName, String tgtParent, String tgtName) {
|
public boolean move(IProgressMonitor monitor, String srcParent, String srcName, String tgtParent, String tgtName) {
|
||||||
boolean hasSucceeded = false;
|
boolean hasSucceeded = false;
|
||||||
int returnedValue = getFTPClient().sendCommand("RNFR " + srcParent + getSeparator() + srcName);
|
if (_mutex.waitForLock(monitor, _mutexTimeout)) {
|
||||||
if (returnedValue > 0) {
|
try {
|
||||||
returnedValue = getFTPClient().sendCommand("RNTO " + tgtParent + getSeparator() + tgtName);
|
int returnedValue = getFTPClient().sendCommand("RNFR " + srcParent + getSeparator() + srcName);
|
||||||
hasSucceeded = (returnedValue > 0);
|
if (returnedValue > 0) {
|
||||||
|
returnedValue = getFTPClient().sendCommand("RNTO " + tgtParent + getSeparator() + tgtName);
|
||||||
|
hasSucceeded = (returnedValue > 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
_mutex.release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return hasSucceeded;
|
return hasSucceeded;
|
||||||
}
|
}
|
||||||
|
@ -391,16 +437,27 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
|
||||||
*/
|
*/
|
||||||
public IHostFile createFolder(IProgressMonitor monitor, String remoteParent, String folderName)
|
public IHostFile createFolder(IProgressMonitor monitor, String remoteParent, String folderName)
|
||||||
{
|
{
|
||||||
try
|
if (_mutex.waitForLock(monitor, _mutexTimeout))
|
||||||
{
|
{
|
||||||
FTPClientService ftp = getFTPClient();
|
try
|
||||||
ftp.cd(remoteParent);
|
{
|
||||||
ftp.sendCommand("MKD " + folderName);
|
FTPClientService ftp = getFTPClient();
|
||||||
}
|
ftp.cd(remoteParent);
|
||||||
catch (Exception e)
|
ftp.sendCommand("MKD " + folderName);
|
||||||
{
|
}
|
||||||
e.printStackTrace();
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_mutex.release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
//TODO getFile() will acquire the lock again after having released it
|
||||||
|
//For optimization, Mutex should notice when the _same_ thread tries
|
||||||
|
//to acquire a lock that it already holds again. To do so, the current
|
||||||
|
//locking thread would need to be remembered.
|
||||||
return getFile(monitor, remoteParent, folderName);
|
return getFile(monitor, remoteParent, folderName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -408,12 +465,18 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
|
||||||
* @see org.eclipse.rse.services.files.IFileService#createFile(org.eclipse.core.runtime.IProgressMonitor, java.lang.String, java.lang.String)
|
* @see org.eclipse.rse.services.files.IFileService#createFile(org.eclipse.core.runtime.IProgressMonitor, java.lang.String, java.lang.String)
|
||||||
*/
|
*/
|
||||||
public IHostFile createFile(IProgressMonitor monitor, String remoteParent, String fileName) {
|
public IHostFile createFile(IProgressMonitor monitor, String remoteParent, String fileName) {
|
||||||
try {
|
if (_mutex.waitForLock(monitor, _mutexTimeout)) {
|
||||||
File tempFile = File.createTempFile("ftp", "temp");
|
try {
|
||||||
tempFile.deleteOnExit();
|
File tempFile = File.createTempFile("ftp", "temp");
|
||||||
upload(monitor, tempFile, remoteParent, fileName, true, null, null);
|
tempFile.deleteOnExit();
|
||||||
} catch (Exception e) {
|
upload(monitor, tempFile, remoteParent, fileName, true, null, null);
|
||||||
e.printStackTrace();
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
_mutex.release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return getFile(monitor, remoteParent, fileName);
|
return getFile(monitor, remoteParent, fileName);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue