mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-17 14:05:23 +02:00
Bug 300394 - [ftp] Deadlock due to NOOP command not receiving response on the main thread
This commit is contained in:
parent
823cdb89d3
commit
a2aca046c9
3 changed files with 61 additions and 21 deletions
|
@ -35,7 +35,7 @@ plugin@org.eclipse.rse.importexport=v201003010830,:pserver:anonymous:none@dev.ec
|
||||||
plugin@org.eclipse.rse.processes.ui=v201003010830,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/plugins/org.eclipse.rse.processes.ui
|
plugin@org.eclipse.rse.processes.ui=v201003010830,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/plugins/org.eclipse.rse.processes.ui
|
||||||
plugin@org.eclipse.rse.sdk=v201003151933,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/plugins/org.eclipse.rse.sdk
|
plugin@org.eclipse.rse.sdk=v201003151933,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/plugins/org.eclipse.rse.sdk
|
||||||
plugin@org.eclipse.rse.services.dstore=v201003151238,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/plugins/org.eclipse.rse.services.dstore
|
plugin@org.eclipse.rse.services.dstore=v201003151238,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/plugins/org.eclipse.rse.services.dstore
|
||||||
plugin@org.eclipse.rse.services.files.ftp=v201003151933,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/plugins/org.eclipse.rse.services.files.ftp
|
plugin@org.eclipse.rse.services.files.ftp=v201003152220,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/plugins/org.eclipse.rse.services.files.ftp
|
||||||
plugin@org.eclipse.rse.services.local=v201003010830,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/plugins/org.eclipse.rse.services.local
|
plugin@org.eclipse.rse.services.local=v201003010830,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/plugins/org.eclipse.rse.services.local
|
||||||
plugin@org.eclipse.rse.services.ssh=v200909160005,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/plugins/org.eclipse.rse.services.ssh
|
plugin@org.eclipse.rse.services.ssh=v200909160005,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/plugins/org.eclipse.rse.services.ssh
|
||||||
plugin@org.eclipse.rse.services.telnet=v200905272300,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/plugins/org.eclipse.rse.services.telnet
|
plugin@org.eclipse.rse.services.telnet=v200905272300,:pserver:anonymous:none@dev.eclipse.org:/cvsroot/dsdp,,org.eclipse.tm.rse/plugins/org.eclipse.rse.services.telnet
|
||||||
|
|
|
@ -42,6 +42,10 @@
|
||||||
<li>A regression in the Terminal widget was fixed, which made initial output after login
|
<li>A regression in the Terminal widget was fixed, which made initial output after login
|
||||||
invisible above the initial viewport
|
invisible above the initial viewport
|
||||||
[<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=294327">294327</a>].</li>
|
[<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=294327">294327</a>].</li>
|
||||||
|
<li>FTP performance was strongly improved and made more reliable, by eliminating
|
||||||
|
potential race conditions and lockups due to excessive sending of NOOP commands
|
||||||
|
[<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=269171">269171</a>]
|
||||||
|
[<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=300394">300394</a>].</li>
|
||||||
<li>EFS provider performance was improved, and multiple connections to a host can
|
<li>EFS provider performance was improved, and multiple connections to a host can
|
||||||
now be disambiguated by name
|
now be disambiguated by name
|
||||||
[<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=291738">291738</a>]
|
[<a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=291738">291738</a>]
|
||||||
|
|
|
@ -144,6 +144,8 @@ import org.eclipse.rse.services.files.RemoteFileSecurityException;
|
||||||
public class FTPService extends AbstractFileService implements IFTPService, IFilePermissionsService
|
public class FTPService extends AbstractFileService implements IFTPService, IFilePermissionsService
|
||||||
{
|
{
|
||||||
private FTPClient _ftpClient;
|
private FTPClient _ftpClient;
|
||||||
|
private long _ftpLastCheck;
|
||||||
|
private static long FTP_CONNECTION_CHECK_TIMEOUT = 30000; //msec before checking connection with NOOP
|
||||||
private FTPFile[] _ftpFiles;
|
private FTPFile[] _ftpFiles;
|
||||||
|
|
||||||
private Mutex _commandMutex = new Mutex();
|
private Mutex _commandMutex = new Mutex();
|
||||||
|
@ -335,7 +337,7 @@ public class FTPService extends AbstractFileService implements IFTPService, IFil
|
||||||
protected String checkEncoding(String s) throws SystemMessageException {
|
protected String checkEncoding(String s) throws SystemMessageException {
|
||||||
if (s == null || s.length() == 0)
|
if (s == null || s.length() == 0)
|
||||||
return s;
|
return s;
|
||||||
String encoding = _controlEncoding!=null ? _controlEncoding : getFTPClient().getControlEncoding();
|
String encoding = _controlEncoding!=null ? _controlEncoding : getFTPClient(false).getControlEncoding();
|
||||||
try {
|
try {
|
||||||
byte[] bytes = s.getBytes(encoding);
|
byte[] bytes = s.getBytes(encoding);
|
||||||
String decoded = new String(bytes, encoding);
|
String decoded = new String(bytes, encoding);
|
||||||
|
@ -383,7 +385,7 @@ public class FTPService extends AbstractFileService implements IFTPService, IFil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_ftpLoggingOutputStream!=null)
|
if(_ftpLoggingOutputStream!=null && _ftpProtocolCommandListener==null)
|
||||||
{
|
{
|
||||||
_ftpProtocolCommandListener = new ProtocolCommandListener() {
|
_ftpProtocolCommandListener = new ProtocolCommandListener() {
|
||||||
|
|
||||||
|
@ -497,14 +499,20 @@ public class FTPService extends AbstractFileService implements IFTPService, IFil
|
||||||
clearCache(null);
|
clearCache(null);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
getFTPClient().logout();
|
if (_ftpClient!=null) {
|
||||||
_ftpClient = null;
|
//no use connecting through NOOP as side-effect
|
||||||
|
//of getFtpClient() just to disconnect
|
||||||
|
_ftpClient.logout();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
_ftpClient = null;
|
_ftpClient = null;
|
||||||
|
//force checking connection with NOOP on reconnect
|
||||||
|
_ftpLastCheck = 0;
|
||||||
|
_ftpProtocolCommandListener = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -527,6 +535,7 @@ public class FTPService extends AbstractFileService implements IFTPService, IFil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the commons.net FTPClient for this session.
|
* Returns the commons.net FTPClient for this session.
|
||||||
*
|
*
|
||||||
|
@ -534,9 +543,30 @@ public class FTPService extends AbstractFileService implements IFTPService, IFil
|
||||||
* by sending a NOOP to the remote side, and initiates
|
* by sending a NOOP to the remote side, and initiates
|
||||||
* a connect in case the NOOP throws an exception.
|
* a connect in case the NOOP throws an exception.
|
||||||
*
|
*
|
||||||
|
* In order to avoid race conditions by this sending
|
||||||
|
* of NOOP and its related return code, this sending
|
||||||
|
* of NOOP must always be protected by a command mutex.
|
||||||
|
*
|
||||||
* @return The commons.net FTPClient.
|
* @return The commons.net FTPClient.
|
||||||
*/
|
*/
|
||||||
public FTPClient getFTPClient()
|
public FTPClient getFTPClient() {
|
||||||
|
return getFTPClient(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the commons.net FTPClient for this session.
|
||||||
|
*
|
||||||
|
* @param checkConnection <code>true</code> to request
|
||||||
|
* sending a NOOP command as a side-effect in order
|
||||||
|
* to check connection or re-connect.
|
||||||
|
* When this is done, the call must be protected
|
||||||
|
* by a command mutex in order to avoid race conditions
|
||||||
|
* between sending the NOOP command and awaiting its
|
||||||
|
* response.
|
||||||
|
*
|
||||||
|
* @return The commons.net FTPClient.
|
||||||
|
*/
|
||||||
|
public FTPClient getFTPClient(boolean checkConnection)
|
||||||
{
|
{
|
||||||
if (_ftpClient == null)
|
if (_ftpClient == null)
|
||||||
{
|
{
|
||||||
|
@ -547,14 +577,18 @@ public class FTPService extends AbstractFileService implements IFTPService, IFil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_hostName!=null)
|
if(_hostName!=null && checkConnection)
|
||||||
{
|
{
|
||||||
try{
|
long curTime = System.currentTimeMillis();
|
||||||
_ftpClient.sendNoOp();
|
if (curTime - _ftpLastCheck > FTP_CONNECTION_CHECK_TIMEOUT) {
|
||||||
}catch (IOException e){
|
_ftpLastCheck = curTime;
|
||||||
try {
|
try{
|
||||||
connect();
|
_ftpClient.sendNoOp();
|
||||||
} catch (Exception e1) {}
|
}catch (IOException e){
|
||||||
|
try {
|
||||||
|
connect();
|
||||||
|
} catch (Exception e1) {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -669,8 +703,8 @@ public class FTPService extends AbstractFileService implements IFTPService, IFil
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
//try to retrieve the file
|
//try to retrieve the file
|
||||||
_ftpClient = getFTPClient();
|
FTPClient ftpc = getFTPClient();
|
||||||
chdir(_ftpClient, remoteParent);
|
chdir(ftpc, remoteParent);
|
||||||
if(!listFiles(monitor))
|
if(!listFiles(monitor))
|
||||||
{
|
{
|
||||||
throw new SystemOperationCancelledException();
|
throw new SystemOperationCancelledException();
|
||||||
|
@ -762,8 +796,8 @@ public class FTPService extends AbstractFileService implements IFTPService, IFil
|
||||||
filematcher = new NamePatternMatcher(fileFilter, true, true);
|
filematcher = new NamePatternMatcher(fileFilter, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
_ftpClient = getFTPClient();
|
FTPClient ftpc = getFTPClient();
|
||||||
chdir(_ftpClient, parentPath);
|
chdir(ftpc, parentPath);
|
||||||
if(!listFiles(monitor))
|
if(!listFiles(monitor))
|
||||||
{
|
{
|
||||||
throw new SystemOperationCancelledException();
|
throw new SystemOperationCancelledException();
|
||||||
|
@ -1630,8 +1664,9 @@ public class FTPService extends AbstractFileService implements IFTPService, IFil
|
||||||
} else if(_commandMutex.waitForLock(monitor, Long.MAX_VALUE)) {
|
} else if(_commandMutex.waitForLock(monitor, Long.MAX_VALUE)) {
|
||||||
try {
|
try {
|
||||||
clearCache(parent);
|
clearCache(parent);
|
||||||
if (!_ftpClient.sendSiteCommand("CHMOD " + newPermissions + " " + file.getAbsolutePath())) { //$NON-NLS-1$ //$NON-NLS-2$
|
FTPClient ftpc = getFTPClient();
|
||||||
String lastMessage = _ftpClient.getReplyString();
|
if (!ftpc.sendSiteCommand("CHMOD " + newPermissions + " " + file.getAbsolutePath())) { //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
String lastMessage = ftpc.getReplyString();
|
||||||
throw new RemoteFileSecurityException(new Exception(lastMessage));
|
throw new RemoteFileSecurityException(new Exception(lastMessage));
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -1776,8 +1811,9 @@ public class FTPService extends AbstractFileService implements IFTPService, IFil
|
||||||
if (_commandMutex.waitForLock(monitor, Long.MAX_VALUE)) {
|
if (_commandMutex.waitForLock(monitor, Long.MAX_VALUE)) {
|
||||||
try {
|
try {
|
||||||
clearCache(inFile.getParentPath());
|
clearCache(inFile.getParentPath());
|
||||||
if (!_ftpClient.sendSiteCommand("CHMOD " + s + " " + inFile.getAbsolutePath())) { //$NON-NLS-1$ //$NON-NLS-2$
|
FTPClient ftpc = getFTPClient();
|
||||||
String lastMessage = _ftpClient.getReplyString();
|
if (!ftpc.sendSiteCommand("CHMOD " + s + " " + inFile.getAbsolutePath())) { //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
String lastMessage = ftpc.getReplyString();
|
||||||
throw new RemoteFileSecurityException(new Exception(lastMessage));
|
throw new RemoteFileSecurityException(new Exception(lastMessage));
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue