CB-6378 Use connection.disconnect() instead of stream.close() for thread-safety

This commit is contained in:
Andrew Grieve
2014-05-06 10:25:01 -04:00
parent 2ecc6859e2
commit 67ae8d8852
+24 -20
View File
@@ -81,8 +81,7 @@ public class FileTransfer extends CordovaPlugin {
String target; String target;
File targetFile; File targetFile;
CallbackContext callbackContext; CallbackContext callbackContext;
InputStream currentInputStream; HttpURLConnection connection;
OutputStream currentOutputStream;
boolean aborted; boolean aborted;
RequestContext(String source, String target, CallbackContext callbackContext) { RequestContext(String source, String target, CallbackContext callbackContext) {
this.source = source; this.source = source;
@@ -384,7 +383,7 @@ public class FileTransfer extends CordovaPlugin {
if (context.aborted) { if (context.aborted) {
return; return;
} }
context.currentOutputStream = sendStream; context.connection = conn;
} }
//We don't want to change encoding, we just want this to write for all Unicode. //We don't want to change encoding, we just want this to write for all Unicode.
sendStream.write(beforeDataBytes); sendStream.write(beforeDataBytes);
@@ -426,7 +425,9 @@ public class FileTransfer extends CordovaPlugin {
safeClose(readResult.inputStream); safeClose(readResult.inputStream);
safeClose(sendStream); safeClose(sendStream);
} }
context.currentOutputStream = null; synchronized (context) {
context.connection = null;
}
Log.d(LOG_TAG, "Sent " + totalBytes + " of " + fixedLength); Log.d(LOG_TAG, "Sent " + totalBytes + " of " + fixedLength);
//------------------ read the SERVER RESPONSE //------------------ read the SERVER RESPONSE
@@ -441,7 +442,7 @@ public class FileTransfer extends CordovaPlugin {
if (context.aborted) { if (context.aborted) {
return; return;
} }
context.currentInputStream = inStream; context.connection = conn;
} }
ByteArrayOutputStream out = new ByteArrayOutputStream(Math.max(1024, conn.getContentLength())); ByteArrayOutputStream out = new ByteArrayOutputStream(Math.max(1024, conn.getContentLength()));
@@ -453,7 +454,9 @@ public class FileTransfer extends CordovaPlugin {
} }
responseString = out.toString("UTF-8"); responseString = out.toString("UTF-8");
} finally { } finally {
context.currentInputStream = null; synchronized (context) {
context.connection = null;
}
safeClose(inStream); safeClose(inStream);
} }
@@ -767,7 +770,7 @@ public class FileTransfer extends CordovaPlugin {
if (context.aborted) { if (context.aborted) {
return; return;
} }
context.currentInputStream = inputStream; context.connection = connection;
} }
// write bytes to file // write bytes to file
@@ -782,7 +785,9 @@ public class FileTransfer extends CordovaPlugin {
context.sendPluginResult(progressResult); context.sendPluginResult(progressResult);
} }
} finally { } finally {
context.currentInputStream = null; synchronized (context) {
context.connection = null;
}
safeClose(inputStream); safeClose(inputStream);
safeClose(outputStream); safeClose(outputStream);
} }
@@ -857,22 +862,21 @@ public class FileTransfer extends CordovaPlugin {
context = activeRequests.remove(objectId); context = activeRequests.remove(objectId);
} }
if (context != null) { if (context != null) {
File file = context.targetFile;
if (file != null) {
file.delete();
}
// Trigger the abort callback immediately to minimize latency between it and abort() being called.
JSONObject error = createFileTransferError(ABORTED_ERR, context.source, context.target, null, -1);
synchronized (context) {
context.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, error));
context.aborted = true;
}
// Closing the streams can block, so execute on a background thread. // Closing the streams can block, so execute on a background thread.
cordova.getThreadPool().execute(new Runnable() { cordova.getThreadPool().execute(new Runnable() {
public void run() { public void run() {
synchronized (context) { synchronized (context) {
safeClose(context.currentInputStream); File file = context.targetFile;
safeClose(context.currentOutputStream); if (file != null) {
file.delete();
}
// Trigger the abort callback immediately to minimize latency between it and abort() being called.
JSONObject error = createFileTransferError(ABORTED_ERR, context.source, context.target, null, -1);
context.sendPluginResult(new PluginResult(PluginResult.Status.ERROR, error));
context.aborted = true;
if (context.connection != null) {
context.connection.disconnect();
}
} }
} }
}); });