1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-05 08:05:24 +02:00

[192610] Fix thread safety for delete(), upload(), setReadOnly() operations

This commit is contained in:
Martin Oberhuber 2007-08-02 12:05:57 +00:00
parent 89d501fd49
commit 0bdec9ed01

View file

@ -55,6 +55,7 @@
* Javier Montalvo Orus (Symbian) - [195830] RSE performs unnecessary remote list commands
* Martin Oberhuber (Wind River) - [198638] Fix invalid caching
* Martin Oberhuber (Wind River) - [198645] Fix case sensitivity issues
* Martin Oberhuber (Wind River) - [192610] Fix thread safety for delete(), upload(), setReadOnly() operations
********************************************************************************/
package org.eclipse.rse.internal.services.files.ftp;
@ -359,6 +360,10 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
_userHome = '/'+_userHome.substring(0,_userHome.lastIndexOf(']'));
}
//Just to be safe
synchronized (_fCachePreviousFiles) {
_fCachePreviousFiles.clear();
}
}
public void disconnect()
@ -422,6 +427,9 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
/**
* Return FTPHostFile object for a given parent dir and file name.
* This is different than {@link #getFile(String, String, IProgressMonitor)}
* in order to ensure we always return proper FTPHostFile type.
*
* @see org.eclipse.rse.services.files.IFileService#getFile(String, String, IProgressMonitor)
*/
protected FTPHostFile getFileInternal(String remoteParent, String fileName, IProgressMonitor monitor) throws SystemMessageException
@ -720,7 +728,6 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
bos.close();
if(retValue == true){
setFileType(isBinary);
retValue = upload(tempFile, remoteParent, remoteFile, isBinary, "", hostEncoding, monitor); //$NON-NLS-1$
}
@ -859,49 +866,50 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
public boolean delete(String remoteParent, String fileName, IProgressMonitor monitor) throws SystemMessageException {
boolean hasSucceeded = false;
FTPClient ftpClient = getFTPClient();
MyProgressMonitor progressMonitor = new MyProgressMonitor(monitor);
progressMonitor.init(FTPServiceResources.FTP_File_Service_Deleting_Task+fileName, 1);
IHostFile file = getFile(remoteParent, fileName, monitor);
boolean isFile = file.isFile();
try {
hasSucceeded = FTPReply.isPositiveCompletion(ftpClient.cwd(remoteParent));
if(hasSucceeded)
{
if(isFile)
if(_commandMutex.waitForLock(monitor, Long.MAX_VALUE)) {
try {
FTPClient ftpClient = getFTPClient();
hasSucceeded = FTPReply.isPositiveCompletion(ftpClient.cwd(remoteParent));
if(hasSucceeded)
{
hasSucceeded = ftpClient.deleteFile(fileName);
if(isFile)
{
hasSucceeded = ftpClient.deleteFile(fileName);
}
else
{
hasSucceeded = ftpClient.removeDirectory(fileName);
}
}
if(!hasSucceeded){
throw new Exception(ftpClient.getReplyString()+" ("+fileName+")"); //$NON-NLS-1$ //$NON-NLS-2$
}
else
{
hasSucceeded = ftpClient.removeDirectory(fileName);
progressMonitor.worked(1);
}
}
if(!hasSucceeded){
throw new Exception(ftpClient.getReplyString()+" ("+fileName+")"); //$NON-NLS-1$ //$NON-NLS-2$
}
else
{
progressMonitor.worked(1);
}
}
catch (Exception e) {
if(isFile){
throw new RemoteFileIOException(e);
}
else{
throw new RemoteFolderNotEmptyException(e);
}
}
catch (Exception e) {
if(isFile){
throw new RemoteFileIOException(e);
}
else{
throw new RemoteFolderNotEmptyException(e);
}
} finally {
_commandMutex.release();
}
}
return hasSucceeded;
@ -1073,7 +1081,10 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
return true;
}
/**
* Internal method to list files.
* MUST ALWAYS be called from _commandMutex protected region.
*/
private boolean listFiles(IProgressMonitor monitor) throws Exception
{
boolean result = true;
@ -1254,40 +1265,36 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
}
permissions = userPermissions * 100 + groupPermissions * 10 + otherPermissions;
try {
result =_ftpClient.sendSiteCommand("CHMOD "+permissions+" "+file.getAbsolutePath()); //$NON-NLS-1$ //$NON-NLS-2$
} catch (IOException e) {
result = false;
}
if(_commandMutex.waitForLock(monitor, Long.MAX_VALUE)) {
try {
result =_ftpClient.sendSiteCommand("CHMOD "+permissions+" "+file.getAbsolutePath()); //$NON-NLS-1$ //$NON-NLS-2$
} catch (IOException e) {
result = false;
} finally {
_commandMutex.release();
}
}
return result;
}
/**
* Gets the input stream to access the contents of a remote file.
* @since 2.0
/*
* (non-Javadoc)
* @see org.eclipse.rse.services.files.AbstractFileService#getInputStream(java.lang.String, java.lang.String, boolean, org.eclipse.core.runtime.IProgressMonitor)
*/
public InputStream getInputStream(String remoteParent, String remoteFile, boolean isBinary, IProgressMonitor monitor) throws SystemMessageException {
if (monitor != null){
if (monitor.isCanceled()) {
return null;
}
if (monitor != null && monitor.isCanceled()){
throw new RemoteFileCancelledException();
}
InputStream stream = null;
if(_commandMutex.waitForLock(monitor, Long.MAX_VALUE))
{
FTPClient ftpClient = getFTPClient();
try {
ftpClient.changeWorkingDirectory(remoteParent);
setFileType(isBinary);
stream = new FTPBufferedInputStream(ftpClient.retrieveFileStream(remoteFile), ftpClient);
@ -1295,26 +1302,29 @@ public class FTPService extends AbstractFileService implements IFileService, IFT
catch (Exception e) {
throw new RemoteFileIOException(e);
}finally {
_commandMutex.release();
//TODO I am not 100% sure but I _think_ that the _commandMutex
//may only be released once reading the stream is complete,
//since in FTPBufferedInputStream.close() a pending command
//is being sent.
//After all, the safer solution would be to have a separate
//FTP client connection to the remote for the download, such
//that dir channel remains free. See bug #198636
_commandMutex.release();
}
} else {
throw new RemoteFileCancelledException();
}
return stream;
}
/**
* Gets the output stream to write to a remote file.
* @since 2.0
/*
* (non-Javadoc)
* @see org.eclipse.rse.services.files.AbstractFileService#getOutputStream(java.lang.String, java.lang.String, boolean, org.eclipse.core.runtime.IProgressMonitor)
*/
public OutputStream getOutputStream(String remoteParent, String remoteFile, boolean isBinary, IProgressMonitor monitor) throws SystemMessageException {
if (monitor != null){
if (monitor.isCanceled()) {
return null;
}
if (monitor != null && monitor.isCanceled()){
throw new RemoteFileCancelledException();
}
OutputStream stream = null;