mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-14 20:45:22 +02:00
[236039][dstore][efs] DStoreInputStream can report EOF too early - clean up how it waits for the local temp file to be created
This commit is contained in:
parent
c7e316b19e
commit
c37fa4ad7e
2 changed files with 85 additions and 64 deletions
|
@ -46,6 +46,7 @@
|
||||||
* David McKnight (IBM) - [221211] [api][breaking][files] need batch operations to indicate which operations were successful
|
* David McKnight (IBM) - [221211] [api][breaking][files] need batch operations to indicate which operations were successful
|
||||||
* Radoslav Gerganov (ProSyst) - [230919] IFileService.delete() should not return a boolean
|
* Radoslav Gerganov (ProSyst) - [230919] IFileService.delete() should not return a boolean
|
||||||
* Martin Oberhuber (Wind River) - [235463][ftp][dstore] Incorrect case sensitivity reported on windows-remote
|
* Martin Oberhuber (Wind River) - [235463][ftp][dstore] Incorrect case sensitivity reported on windows-remote
|
||||||
|
* David McKnight (IBM) - [236039][dstore][efs] DStoreInputStream can report EOF too early - clean up how it waits for the local temp file to be created
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
package org.eclipse.rse.internal.services.dstore.files;
|
package org.eclipse.rse.internal.services.dstore.files;
|
||||||
|
@ -2129,7 +2130,7 @@ public class DStoreFileService extends AbstractDStoreService implements IFileSer
|
||||||
{
|
{
|
||||||
mode = IUniversalDataStoreConstants.TEXT_MODE;
|
mode = IUniversalDataStoreConstants.TEXT_MODE;
|
||||||
}
|
}
|
||||||
DStoreInputStream inputStream = new DStoreInputStream(getDataStore(), remotePath, getMinerElement(), getEncoding(monitor), mode);
|
DStoreInputStream inputStream = new DStoreInputStream(getDataStore(), remotePath, getMinerElement(), getEncoding(monitor), mode, getBufferDownloadSize());
|
||||||
return inputStream;
|
return inputStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Copyright (c) 2007, 2008 IBM Corporation and others. All rights reserved.
|
* Copyright (c) 2007, 2008 IBM Corporation and others. All rights reserved.
|
||||||
* This program and the accompanying materials are made available under the terms
|
* 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
|
* of the Eclipse Public License v1.0 which accompanies this distribution, and is
|
||||||
* available at http://www.eclipse.org/legal/epl-v10.html
|
* available at http://www.eclipse.org/legal/epl-v10.html
|
||||||
*
|
*
|
||||||
* Initial Contributors:
|
* Initial Contributors:
|
||||||
* The following IBM employees contributed to the Remote System Explorer
|
* The following IBM employees contributed to the Remote System Explorer
|
||||||
* component that contains this file: David McKnight.
|
* component that contains this file: David McKnight.
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Martin Oberhuber (Wind River) - [199561][efs][dstore] Eclipse hangs when manipulating empty file
|
* Martin Oberhuber (Wind River) - [199561][efs][dstore] Eclipse hangs when manipulating empty file
|
||||||
* David McKnight (IBM) - [234637] [dstore][efs] RSE EFS provider seems to truncate files
|
* David McKnight (IBM) - [234637] [dstore][efs] RSE EFS provider seems to truncate files
|
||||||
|
* David McKnight (IBM) - [236039][dstore][efs] DStoreInputStream can report EOF too early - clean up how it waits for the local temp file to be created
|
||||||
********************************************************************************/
|
********************************************************************************/
|
||||||
package org.eclipse.rse.internal.services.dstore.files;
|
package org.eclipse.rse.internal.services.dstore.files;
|
||||||
|
|
||||||
|
@ -24,7 +25,7 @@ import org.eclipse.dstore.core.model.DataElement;
|
||||||
import org.eclipse.dstore.core.model.DataStore;
|
import org.eclipse.dstore.core.model.DataStore;
|
||||||
import org.eclipse.rse.dstore.universal.miners.IUniversalDataStoreConstants;
|
import org.eclipse.rse.dstore.universal.miners.IUniversalDataStoreConstants;
|
||||||
|
|
||||||
public class DStoreInputStream extends InputStream
|
public class DStoreInputStream extends InputStream
|
||||||
{
|
{
|
||||||
private DataStore _dataStore;
|
private DataStore _dataStore;
|
||||||
private String _remotePath;
|
private String _remotePath;
|
||||||
|
@ -34,125 +35,164 @@ public class DStoreInputStream extends InputStream
|
||||||
private DataElement _cmdStatus; // leaving this, in case of need for error checking
|
private DataElement _cmdStatus; // leaving this, in case of need for error checking
|
||||||
private File _localFile;
|
private File _localFile;
|
||||||
private InputStream _localFileInputStream;
|
private InputStream _localFileInputStream;
|
||||||
|
private int _bufferSize;
|
||||||
public DStoreInputStream(DataStore dataStore, String remotePath, DataElement minerElement, String encoding, int mode)
|
private long _bytesRead = 0;
|
||||||
|
|
||||||
|
public DStoreInputStream(DataStore dataStore, String remotePath, DataElement minerElement, String encoding, int mode, int bufferSize)
|
||||||
{
|
{
|
||||||
_dataStore = dataStore;
|
_dataStore = dataStore;
|
||||||
_remotePath = remotePath;
|
_remotePath = remotePath;
|
||||||
_minerElement = minerElement;
|
_minerElement = minerElement;
|
||||||
_encoding = encoding;
|
_encoding = encoding;
|
||||||
_mode = mode;
|
_mode = mode;
|
||||||
|
_bufferSize = bufferSize;
|
||||||
initDownload();
|
initDownload();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void initDownload()
|
protected void initDownload()
|
||||||
{
|
{
|
||||||
DataStore ds = _dataStore;
|
DataStore ds = _dataStore;
|
||||||
DataElement universaltemp = _minerElement;
|
DataElement universaltemp = _minerElement;
|
||||||
DataElement de = _dataStore.createObject(universaltemp, IUniversalDataStoreConstants.UNIVERSAL_FILE_DESCRIPTOR, _remotePath, _remotePath, "", false); //$NON-NLS-1$
|
DataElement de = _dataStore.createObject(universaltemp, IUniversalDataStoreConstants.UNIVERSAL_FILE_DESCRIPTOR, _remotePath, _remotePath, "", false); //$NON-NLS-1$
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_localFile = File.createTempFile("download", "rse"); //$NON-NLS-1$//$NON-NLS-2$
|
_localFile = File.createTempFile("download", "rse"); //$NON-NLS-1$//$NON-NLS-2$
|
||||||
DataElement remoteElement = ds.createObject(universaltemp, de.getType(), _remotePath, String.valueOf(_mode));
|
DataElement remoteElement = ds.createObject(universaltemp, de.getType(), _remotePath, String.valueOf(_mode));
|
||||||
DataElement localElement = ds.createObject(universaltemp, de.getType(), _localFile.getAbsolutePath(), _encoding);
|
DataElement localElement = ds.createObject(universaltemp, de.getType(), _localFile.getAbsolutePath(), _encoding);
|
||||||
|
|
||||||
DataElement bufferSizeElement = ds.createObject(universaltemp, "buffer_size", "" + IUniversalDataStoreConstants.BUFFER_SIZE, ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
DataElement bufferSizeElement = ds.createObject(universaltemp, "buffer_size", "" + _bufferSize, ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||||
DataElement queryCmd = getCommandDescriptor(de, IUniversalDataStoreConstants.C_DOWNLOAD_FILE);
|
DataElement queryCmd = getCommandDescriptor(de, IUniversalDataStoreConstants.C_DOWNLOAD_FILE);
|
||||||
|
|
||||||
ArrayList argList = new ArrayList();
|
ArrayList argList = new ArrayList();
|
||||||
argList.add(remoteElement);
|
argList.add(remoteElement);
|
||||||
argList.add(localElement);
|
argList.add(localElement);
|
||||||
argList.add(bufferSizeElement);
|
argList.add(bufferSizeElement);
|
||||||
|
|
||||||
DataElement subject = ds.createObject(universaltemp, de.getType(), _remotePath, String.valueOf(_mode));
|
DataElement subject = ds.createObject(universaltemp, de.getType(), _remotePath, String.valueOf(_mode));
|
||||||
|
|
||||||
_cmdStatus = ds.command(queryCmd, argList, subject);
|
_cmdStatus = ds.command(queryCmd, argList, subject);
|
||||||
waitForTempFile();
|
waitForTempFile();
|
||||||
_localFileInputStream = new FileInputStream(_localFile);
|
_localFileInputStream = new FileInputStream(_localFile);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected DataStore getDataStore()
|
protected DataStore getDataStore()
|
||||||
{
|
{
|
||||||
return _dataStore;
|
return _dataStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected DataElement getCommandDescriptor(DataElement subject, String command)
|
protected DataElement getCommandDescriptor(DataElement subject, String command)
|
||||||
{
|
{
|
||||||
DataElement cmd = _dataStore.localDescriptorQuery(subject.getDescriptor(), command);
|
DataElement cmd = _dataStore.localDescriptorQuery(subject.getDescriptor(), command);
|
||||||
return cmd;
|
return cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close() throws IOException
|
public void close() throws IOException
|
||||||
{
|
{
|
||||||
if (_localFileInputStream != null)
|
if (_localFileInputStream != null)
|
||||||
{
|
{
|
||||||
_localFileInputStream.close();
|
_localFileInputStream.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wait for the temp file to be created
|
||||||
|
*/
|
||||||
protected void waitForTempFile()
|
protected void waitForTempFile()
|
||||||
{
|
{
|
||||||
if (_localFile != null)
|
if (_localFile != null)
|
||||||
{
|
{
|
||||||
long lastLength = 0;
|
|
||||||
|
|
||||||
// TODO cleanup how we wait for the temp file creation
|
// TODO cleanup how we wait for the temp file creation
|
||||||
// keep waiting until temp file is populated and no new bytes appear to
|
// keep waiting until temp file is populated and no new bytes appear to
|
||||||
// be coming in
|
// be coming in
|
||||||
while (((_localFile.length() == 0) || (_localFile.length() > lastLength)) &&
|
while ((_localFile.length() == 0) &&
|
||||||
!_cmdStatus.getValue().equals("done")) //$NON-NLS-1$)
|
!isTransferCommandDone())
|
||||||
{
|
{
|
||||||
lastLength = _localFile.length();
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Thread.sleep(100);
|
Thread.sleep(100);
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int read() throws IOException
|
private boolean isTransferCommandDone()
|
||||||
{
|
{
|
||||||
if (_localFileInputStream != null)
|
boolean done = _cmdStatus.getValue().equals("done"); //$NON-NLS-1$
|
||||||
{
|
return done;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int read() throws IOException
|
||||||
|
{
|
||||||
|
if (_localFileInputStream != null) {
|
||||||
|
waitUntilAvailable(_bytesRead + 1);
|
||||||
int result = _localFileInputStream.read();
|
int result = _localFileInputStream.read();
|
||||||
|
if (result > 0){
|
||||||
|
_bytesRead++;
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int read(byte[] b, int off, int len) throws IOException
|
public int read(byte[] b, int off, int len) throws IOException
|
||||||
{
|
{
|
||||||
if (_localFileInputStream != null)
|
if (_localFileInputStream != null)
|
||||||
{
|
{
|
||||||
|
waitUntilAvailable(_bytesRead + len);
|
||||||
int result = _localFileInputStream.read(b, off, len);
|
int result = _localFileInputStream.read(b, off, len);
|
||||||
|
if (result > 0){
|
||||||
|
_bytesRead += result;
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int read(byte[] b) throws IOException
|
public int read(byte[] b) throws IOException
|
||||||
{
|
{
|
||||||
if (_localFileInputStream != null)
|
if (_localFileInputStream != null)
|
||||||
{
|
{
|
||||||
|
waitUntilAvailable(_bytesRead + b.length);
|
||||||
int result = _localFileInputStream.read(b);
|
int result = _localFileInputStream.read(b);
|
||||||
|
if (result > 0){
|
||||||
|
_bytesRead += result;
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int available() throws IOException
|
|
||||||
|
private void waitUntilAvailable(long desiredAvailable)
|
||||||
|
{
|
||||||
|
// desiredAvailable will be the total bytes read so far + the desired extra amount
|
||||||
|
while(_localFile.length() < desiredAvailable &&
|
||||||
|
!isTransferCommandDone()) {
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Thread.sleep(100);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int available() throws IOException
|
||||||
{
|
{
|
||||||
if (_localFileInputStream != null)
|
if (_localFileInputStream != null)
|
||||||
{
|
{
|
||||||
|
@ -161,36 +201,16 @@ public class DStoreInputStream extends InputStream
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void mark(int readlimit)
|
public long skip(long n) throws IOException
|
||||||
{
|
{
|
||||||
if (_localFileInputStream != null)
|
if (_localFileInputStream != null)
|
||||||
{
|
{
|
||||||
_localFileInputStream.mark(readlimit);
|
waitUntilAvailable(_bytesRead + n);
|
||||||
}
|
long bytesSkipped = _localFileInputStream.skip(n);
|
||||||
}
|
if (bytesSkipped > 0) {
|
||||||
|
_bytesRead += bytesSkipped;
|
||||||
public boolean markSupported()
|
}
|
||||||
{
|
return bytesSkipped;
|
||||||
if (_localFileInputStream != null)
|
|
||||||
{
|
|
||||||
return _localFileInputStream.markSupported();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void reset() throws IOException
|
|
||||||
{
|
|
||||||
if (_localFileInputStream != null)
|
|
||||||
{
|
|
||||||
_localFileInputStream.reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public long skip(long n) throws IOException
|
|
||||||
{
|
|
||||||
if (_localFileInputStream != null)
|
|
||||||
{
|
|
||||||
return _localFileInputStream.skip(n);
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue