mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-08 17:45:24 +02:00
Fix bug 149179 - use Mutex to serialize parallel sftp requests where necessary
This commit is contained in:
parent
fb30c9539c
commit
ac3e1dfd90
2 changed files with 275 additions and 100 deletions
|
@ -0,0 +1,148 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2006 Wind River Systems, Inc.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Martin Oberhuber (Wind River) - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package org.eclipse.rse.services.ssh.files;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
|
|
||||||
|
import org.eclipse.rse.services.ssh.Activator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Mutual Exclusion Lock for Threads that need to access a resource
|
||||||
|
* in a serialized manner.
|
||||||
|
*
|
||||||
|
* Usage Example:
|
||||||
|
* <code>
|
||||||
|
* private Mutex fooMutex;
|
||||||
|
* boolean doFooSerialized()(IProgressMonitor monitor) {
|
||||||
|
* if (fooMutex.waitForLock(monitor, 1000)) {
|
||||||
|
* try {
|
||||||
|
* return doFoo();
|
||||||
|
* } finally {
|
||||||
|
* fooMutex.release();
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* return false;
|
||||||
|
* }
|
||||||
|
* </code>
|
||||||
|
*/
|
||||||
|
public class Mutex {
|
||||||
|
|
||||||
|
private boolean fLocked = false;
|
||||||
|
private List fWaitQueue = new LinkedList();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to acquire the lock maintained by this mutex.
|
||||||
|
*
|
||||||
|
* If the thread needs to wait before it can acquire the mutex, it
|
||||||
|
* will wait in a first-come-first-serve fashion. In case a progress
|
||||||
|
* monitor was given, it will be updated and checked for cancel every
|
||||||
|
* second.
|
||||||
|
*
|
||||||
|
* @param monitor Eclipse Progress Monitor. May be <code>null</code>.
|
||||||
|
* @param timeout Maximum wait time given in milliseconds.
|
||||||
|
* @return <code>true</code> if the lock was obtained successfully.
|
||||||
|
*/
|
||||||
|
public synchronized boolean waitForLock(IProgressMonitor monitor, long timeout) {
|
||||||
|
if (Thread.interrupted()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (fLocked) {
|
||||||
|
//need to wait for the lock.
|
||||||
|
boolean canceled = false;
|
||||||
|
final Thread myself = Thread.currentThread();
|
||||||
|
try {
|
||||||
|
fWaitQueue.add(myself);
|
||||||
|
Activator.trace("Mutex: added "+myself+", size="+fWaitQueue.size()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
long timeLeft = timeout;
|
||||||
|
long pollTime = (monitor!=null) ? 1000 : timeLeft;
|
||||||
|
long nextProgressUpdate = start+500;
|
||||||
|
while (timeLeft>0 && !canceled) {
|
||||||
|
try {
|
||||||
|
wait(timeLeft > pollTime ? pollTime : timeLeft);
|
||||||
|
Activator.trace("Mutex: wakeup "+myself+" ?"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
//I'm still in the list, nobody is allowed to take me out!
|
||||||
|
assert !fWaitQueue.isEmpty();
|
||||||
|
if (!fLocked && fWaitQueue.get(0) == myself) {
|
||||||
|
break; //gee it's my turn!
|
||||||
|
}
|
||||||
|
long curTime = System.currentTimeMillis();
|
||||||
|
timeLeft = start + timeout - curTime;
|
||||||
|
if (monitor!=null) {
|
||||||
|
canceled = monitor.isCanceled();
|
||||||
|
if (!canceled && (curTime>nextProgressUpdate)) {
|
||||||
|
monitor.worked(1);
|
||||||
|
nextProgressUpdate+=1000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(InterruptedException e) {
|
||||||
|
canceled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
fWaitQueue.remove(myself);
|
||||||
|
Activator.trace("Mutex: removed "+myself+", size="+fWaitQueue.size()); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
}
|
||||||
|
if (fLocked || canceled) {
|
||||||
|
//we were not able to acquire the lock due to an exception,
|
||||||
|
//or because the wait was canceled.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//acquire the lock myself now.
|
||||||
|
fLocked = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Release this mutex's lock.
|
||||||
|
*
|
||||||
|
* May only be called by the same thread that originally acquired
|
||||||
|
* the Mutex.
|
||||||
|
*/
|
||||||
|
public synchronized void release() {
|
||||||
|
fLocked=false;
|
||||||
|
if (!fWaitQueue.isEmpty()) {
|
||||||
|
Object nextOneInQueue = fWaitQueue.get(0);
|
||||||
|
Activator.trace("Mutex: releasing "+nextOneInQueue); //$NON-NLS-1$
|
||||||
|
notifyAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return this Mutex's lock status.
|
||||||
|
* @return <code>true</code> if this mutex is currently acquired by a thread.
|
||||||
|
*/
|
||||||
|
public synchronized boolean isLocked() {
|
||||||
|
return fLocked;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interrupt all threads waiting for the Lock, causing their
|
||||||
|
* {@link #waitForLock(IProgressMonitor, long)} method to return
|
||||||
|
* <code>false</code>.
|
||||||
|
* This should be called if the resource that the Threads are
|
||||||
|
* contending for, becomes unavailable for some other reason.
|
||||||
|
*/
|
||||||
|
public void interruptAll() {
|
||||||
|
Iterator it = fWaitQueue.iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
Thread aThread = (Thread)it.next();
|
||||||
|
aThread.interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -49,6 +49,8 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
private ISshSessionProvider fSessionProvider;
|
private ISshSessionProvider fSessionProvider;
|
||||||
private ChannelSftp fChannelSftp;
|
private ChannelSftp fChannelSftp;
|
||||||
private String fUserHome;
|
private String fUserHome;
|
||||||
|
private Mutex fDirChannelMutex = new Mutex();
|
||||||
|
private long fDirChannelTimeout = 5000; //max.5 seconds to obtain dir channel
|
||||||
|
|
||||||
// public SftpFileService(SshConnectorService conn) {
|
// public SftpFileService(SshConnectorService conn) {
|
||||||
// fConnector = conn;
|
// fConnector = conn;
|
||||||
|
@ -130,6 +132,7 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
if (fChannelSftp!=null && fChannelSftp.isConnected()) {
|
if (fChannelSftp!=null && fChannelSftp.isConnected()) {
|
||||||
fChannelSftp.disconnect();
|
fChannelSftp.disconnect();
|
||||||
}
|
}
|
||||||
|
fDirChannelMutex.interruptAll();
|
||||||
fChannelSftp = null;
|
fChannelSftp = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,11 +143,15 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
//the API docs.
|
//the API docs.
|
||||||
SftpHostFile node = null;
|
SftpHostFile node = null;
|
||||||
SftpATTRS attrs = null;
|
SftpATTRS attrs = null;
|
||||||
try {
|
if (fDirChannelMutex.waitForLock(monitor, fDirChannelTimeout)) {
|
||||||
attrs = getChannel("SftpFileService.getFile").stat(remoteParent+'/'+fileName); //$NON-NLS-1$
|
try {
|
||||||
Activator.trace("SftpFileService.getFile done"); //$NON-NLS-1$
|
attrs = getChannel("SftpFileService.getFile").stat(remoteParent+'/'+fileName); //$NON-NLS-1$
|
||||||
} catch(Exception e) {
|
Activator.trace("SftpFileService.getFile done"); //$NON-NLS-1$
|
||||||
Activator.trace("SftpFileService.getFile failed: "+e.toString()); //$NON-NLS-1$
|
} catch(Exception e) {
|
||||||
|
Activator.trace("SftpFileService.getFile failed: "+e.toString()); //$NON-NLS-1$
|
||||||
|
} finally {
|
||||||
|
fDirChannelMutex.release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (attrs!=null) {
|
if (attrs!=null) {
|
||||||
node = makeHostFile(remoteParent, fileName, attrs);
|
node = makeHostFile(remoteParent, fileName, attrs);
|
||||||
|
@ -171,48 +178,52 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
}
|
}
|
||||||
NamePatternMatcher filematcher = new NamePatternMatcher(fileFilter, true, true);
|
NamePatternMatcher filematcher = new NamePatternMatcher(fileFilter, true, true);
|
||||||
List results = new ArrayList();
|
List results = new ArrayList();
|
||||||
try {
|
if (fDirChannelMutex.waitForLock(monitor, fDirChannelTimeout)) {
|
||||||
java.util.Vector vv=getChannel("SftpFileService.internalFetch").ls(parentPath); //$NON-NLS-1$
|
try {
|
||||||
for(int ii=0; ii<vv.size(); ii++) {
|
java.util.Vector vv=getChannel("SftpFileService.internalFetch").ls(parentPath); //$NON-NLS-1$
|
||||||
Object obj=vv.elementAt(ii);
|
for(int ii=0; ii<vv.size(); ii++) {
|
||||||
if(obj instanceof ChannelSftp.LsEntry){
|
Object obj=vv.elementAt(ii);
|
||||||
ChannelSftp.LsEntry lsEntry = (ChannelSftp.LsEntry)obj;
|
if(obj instanceof ChannelSftp.LsEntry){
|
||||||
String fileName = lsEntry.getFilename();
|
ChannelSftp.LsEntry lsEntry = (ChannelSftp.LsEntry)obj;
|
||||||
if (".".equals(fileName) || "..".equals(fileName)) { //$NON-NLS-1$ //$NON-NLS-2$
|
String fileName = lsEntry.getFilename();
|
||||||
//don't show the trivial names
|
if (".".equals(fileName) || "..".equals(fileName)) { //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
continue;
|
//don't show the trivial names
|
||||||
}
|
continue;
|
||||||
if (filematcher.matches(fileName)) {
|
}
|
||||||
SftpHostFile node = makeHostFile(parentPath, fileName, lsEntry.getAttrs());
|
if (filematcher.matches(fileName)) {
|
||||||
if (isRightType(fileType, node)) {
|
SftpHostFile node = makeHostFile(parentPath, fileName, lsEntry.getAttrs());
|
||||||
results.add(node);
|
if (isRightType(fileType, node)) {
|
||||||
}
|
results.add(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Activator.trace("SftpFileService.internalFetch ok"); //$NON-NLS-1$
|
}
|
||||||
} catch(Exception e) {
|
Activator.trace("SftpFileService.internalFetch ok"); //$NON-NLS-1$
|
||||||
//TODO throw new SystemMessageException.
|
} catch(Exception e) {
|
||||||
//We get a "2: No such file" exception when we try to get contents
|
//TODO throw new SystemMessageException.
|
||||||
//of a symbolic link that turns out to point to a file rather than
|
//We get a "2: No such file" exception when we try to get contents
|
||||||
//a directory. In this case, the result is probably expected.
|
//of a symbolic link that turns out to point to a file rather than
|
||||||
//We should try to classify symbolic links as "file" or "dir" correctly.
|
//a directory. In this case, the result is probably expected.
|
||||||
if (checkSessionConnected()) {
|
//We should try to classify symbolic links as "file" or "dir" correctly.
|
||||||
//TODO not quite sure who should really check for session conneced,
|
if (checkSessionConnected()) {
|
||||||
//perhaps this should be done in the caller? - If we eventually
|
//TODO not quite sure who should really check for session conneced,
|
||||||
//want to support re-connect and re-doing the failed operation
|
//perhaps this should be done in the caller? - If we eventually
|
||||||
//after reconnect this might be necessary.
|
//want to support re-connect and re-doing the failed operation
|
||||||
Activator.trace("SftpFileService.internalFetch failed: "+e.toString()); //$NON-NLS-1$
|
//after reconnect this might be necessary.
|
||||||
//TODO bug 149181: In case of errors like "4:permission denied", throw an
|
Activator.trace("SftpFileService.internalFetch failed: "+e.toString()); //$NON-NLS-1$
|
||||||
//exception to show an error dialog to the user.
|
//TODO bug 149181: In case of errors like "4:permission denied", throw an
|
||||||
e.printStackTrace();
|
//exception to show an error dialog to the user.
|
||||||
//TODO bug 149155: since channelSftp is totally single-threaded, multiple
|
e.printStackTrace();
|
||||||
//parallel access to the channel may break it, typically resulting in
|
//TODO bug 149155: since channelSftp is totally single-threaded, multiple
|
||||||
//SftpException here. I'm not sure how to safely avoid this yet.
|
//parallel access to the channel may break it, typically resulting in
|
||||||
//So here's a little workaround to get the system into a "usable" state again:
|
//SftpException here. I'm not sure how to safely avoid this yet.
|
||||||
//disconnect our channel, it will be reconnected on the next operation.
|
//So here's a little workaround to get the system into a "usable" state again:
|
||||||
//Session handling needs to be re-thought...
|
//disconnect our channel, it will be reconnected on the next operation.
|
||||||
fChannelSftp.disconnect();
|
//Session handling needs to be re-thought...
|
||||||
|
fChannelSftp.disconnect();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
fDirChannelMutex.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (IHostFile[])results.toArray(new IHostFile[results.size()]);
|
return (IHostFile[])results.toArray(new IHostFile[results.size()]);
|
||||||
|
@ -429,21 +440,25 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
public IHostFile createFile(IProgressMonitor monitor, String remoteParent, String fileName) throws SystemMessageException
|
public IHostFile createFile(IProgressMonitor monitor, String remoteParent, String fileName) throws SystemMessageException
|
||||||
{
|
{
|
||||||
IHostFile result = null;
|
IHostFile result = null;
|
||||||
try {
|
if (fDirChannelMutex.waitForLock(monitor, fDirChannelTimeout)) {
|
||||||
String fullPath = remoteParent + '/' + fileName;
|
try {
|
||||||
OutputStream os = getChannel("SftpFileService.createFile").put(fullPath); //$NON-NLS-1$
|
String fullPath = remoteParent + '/' + fileName;
|
||||||
//TODO workaround bug 153118: write a single space
|
OutputStream os = getChannel("SftpFileService.createFile").put(fullPath); //$NON-NLS-1$
|
||||||
//since jsch hangs when trying to close the stream without writing
|
//TODO workaround bug 153118: write a single space
|
||||||
os.write(32);
|
//since jsch hangs when trying to close the stream without writing
|
||||||
os.close();
|
os.write(32);
|
||||||
SftpATTRS attrs = getChannel("SftpFileService.createFile.stat").stat(fullPath); //$NON-NLS-1$
|
os.close();
|
||||||
result = makeHostFile(remoteParent, fileName, attrs);
|
SftpATTRS attrs = getChannel("SftpFileService.createFile.stat").stat(fullPath); //$NON-NLS-1$
|
||||||
Activator.trace("SftpFileService.createFile ok"); //$NON-NLS-1$
|
result = makeHostFile(remoteParent, fileName, attrs);
|
||||||
} catch (Exception e) {
|
Activator.trace("SftpFileService.createFile ok"); //$NON-NLS-1$
|
||||||
Activator.trace("SftpFileService.createFile failed: "+e.toString()); //$NON-NLS-1$
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
Activator.trace("SftpFileService.createFile failed: "+e.toString()); //$NON-NLS-1$
|
||||||
// DKM commenting out because services don't know about this class
|
e.printStackTrace();
|
||||||
// throw new RemoteFileIOException(e);
|
// DKM commenting out because services don't know about this class
|
||||||
|
// throw new RemoteFileIOException(e);
|
||||||
|
} finally {
|
||||||
|
fDirChannelMutex.release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -451,17 +466,21 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
public IHostFile createFolder(IProgressMonitor monitor, String remoteParent, String folderName) throws SystemMessageException
|
public IHostFile createFolder(IProgressMonitor monitor, String remoteParent, String folderName) throws SystemMessageException
|
||||||
{
|
{
|
||||||
IHostFile result = null;
|
IHostFile result = null;
|
||||||
try {
|
if (fDirChannelMutex.waitForLock(monitor, fDirChannelTimeout)) {
|
||||||
String fullPath = remoteParent + '/' + folderName;
|
try {
|
||||||
getChannel("SftpFileService.createFolder").mkdir(fullPath); //$NON-NLS-1$
|
String fullPath = remoteParent + '/' + folderName;
|
||||||
SftpATTRS attrs = getChannel("SftpFileService.createFolder.stat").stat(fullPath); //$NON-NLS-1$
|
getChannel("SftpFileService.createFolder").mkdir(fullPath); //$NON-NLS-1$
|
||||||
result = makeHostFile(remoteParent, folderName, attrs);
|
SftpATTRS attrs = getChannel("SftpFileService.createFolder.stat").stat(fullPath); //$NON-NLS-1$
|
||||||
Activator.trace("SftpFileService.createFolder ok"); //$NON-NLS-1$
|
result = makeHostFile(remoteParent, folderName, attrs);
|
||||||
} catch (Exception e) {
|
Activator.trace("SftpFileService.createFolder ok"); //$NON-NLS-1$
|
||||||
Activator.trace("SftpFileService.createFolder failed: "+e.toString()); //$NON-NLS-1$
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
Activator.trace("SftpFileService.createFolder failed: "+e.toString()); //$NON-NLS-1$
|
||||||
// DKM commenting out because services don't know about this class
|
e.printStackTrace();
|
||||||
//throw new RemoteFileIOException(e);
|
// DKM commenting out because services don't know about this class
|
||||||
|
//throw new RemoteFileIOException(e);
|
||||||
|
} finally {
|
||||||
|
fDirChannelMutex.release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -469,23 +488,27 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
public boolean delete(IProgressMonitor monitor, String remoteParent, String fileName) throws SystemMessageException
|
public boolean delete(IProgressMonitor monitor, String remoteParent, String fileName) throws SystemMessageException
|
||||||
{
|
{
|
||||||
boolean ok=false;
|
boolean ok=false;
|
||||||
try {
|
if (fDirChannelMutex.waitForLock(monitor, fDirChannelTimeout)) {
|
||||||
String fullPath = remoteParent + '/' + fileName;
|
try {
|
||||||
SftpATTRS attrs = getChannel("SftpFileService.delete").stat(fullPath); //$NON-NLS-1$
|
String fullPath = remoteParent + '/' + fileName;
|
||||||
if (attrs==null) {
|
SftpATTRS attrs = getChannel("SftpFileService.delete").stat(fullPath); //$NON-NLS-1$
|
||||||
//doesn't exist, nothing to do
|
if (attrs==null) {
|
||||||
} else if (attrs.isDir()) {
|
//doesn't exist, nothing to do
|
||||||
getChannel("SftpFileService.delete.rmdir").rmdir(fullPath); //$NON-NLS-1$
|
} else if (attrs.isDir()) {
|
||||||
} else {
|
getChannel("SftpFileService.delete.rmdir").rmdir(fullPath); //$NON-NLS-1$
|
||||||
getChannel("SftpFileService.delete.rm").rm(fullPath); //$NON-NLS-1$
|
} else {
|
||||||
|
getChannel("SftpFileService.delete.rm").rm(fullPath); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
ok=true;
|
||||||
|
Activator.trace("SftpFileService.delete ok"); //$NON-NLS-1$
|
||||||
|
} catch (Exception e) {
|
||||||
|
Activator.trace("SftpFileService.delete: "+e.toString()); //$NON-NLS-1$
|
||||||
|
e.printStackTrace();
|
||||||
|
// DKM commenting out because services don't know about this class
|
||||||
|
//throw new RemoteFileIOException(e);
|
||||||
|
} finally {
|
||||||
|
fDirChannelMutex.release();
|
||||||
}
|
}
|
||||||
ok=true;
|
|
||||||
Activator.trace("SftpFileService.delete ok"); //$NON-NLS-1$
|
|
||||||
} catch (Exception e) {
|
|
||||||
Activator.trace("SftpFileService.delete: "+e.toString()); //$NON-NLS-1$
|
|
||||||
e.printStackTrace();
|
|
||||||
// DKM commenting out because services don't know about this class
|
|
||||||
//throw new RemoteFileIOException(e);
|
|
||||||
}
|
}
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
@ -493,17 +516,21 @@ public class SftpFileService extends AbstractFileService implements IFileService
|
||||||
public boolean rename(IProgressMonitor monitor, String remoteParent, String oldName, String newName) throws SystemMessageException
|
public boolean rename(IProgressMonitor monitor, String remoteParent, String oldName, String newName) throws SystemMessageException
|
||||||
{
|
{
|
||||||
boolean ok=false;
|
boolean ok=false;
|
||||||
try {
|
if (fDirChannelMutex.waitForLock(monitor, fDirChannelTimeout)) {
|
||||||
String fullPathOld = remoteParent + '/' + oldName;
|
try {
|
||||||
String fullPathNew = remoteParent + '/' + newName;
|
String fullPathOld = remoteParent + '/' + oldName;
|
||||||
getChannel("SftpFileService.rename").rename(fullPathOld, fullPathNew); //$NON-NLS-1$
|
String fullPathNew = remoteParent + '/' + newName;
|
||||||
ok=true;
|
getChannel("SftpFileService.rename").rename(fullPathOld, fullPathNew); //$NON-NLS-1$
|
||||||
Activator.trace("SftpFileService.rename ok"); //$NON-NLS-1$
|
ok=true;
|
||||||
} catch (Exception e) {
|
Activator.trace("SftpFileService.rename ok"); //$NON-NLS-1$
|
||||||
Activator.trace("SftpFileService.rename failed: "+e.toString()); //$NON-NLS-1$
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
Activator.trace("SftpFileService.rename failed: "+e.toString()); //$NON-NLS-1$
|
||||||
// DKM commenting out because services don't know about this class
|
e.printStackTrace();
|
||||||
//throw new RemoteFileIOException(e);
|
// DKM commenting out because services don't know about this class
|
||||||
|
//throw new RemoteFileIOException(e);
|
||||||
|
} finally {
|
||||||
|
fDirChannelMutex.release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue