Explicitly close pipe end when we cease operations...
...because the other in-VM reference to that FD means that it won't get GC'd after we release our local reference to the containing object, and we wind up with the feeder end blocking on write to a still-fully- open pipe rather than being made aware that the read end has needed to shut down. Bug 28756668 Change-Id: I90b6aaeaabe7d912d96d7ef57c24f68d87d9d0ab
This commit is contained in:
committed by
Chris Tate
parent
19397a4492
commit
3bed1c0ef8
@@ -3528,6 +3528,7 @@ public class BackupManagerService {
|
|||||||
|
|
||||||
private void routeSocketDataToOutput(ParcelFileDescriptor inPipe, OutputStream out)
|
private void routeSocketDataToOutput(ParcelFileDescriptor inPipe, OutputStream out)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
|
// We do not take close() responsibility for the pipe FD
|
||||||
FileInputStream raw = new FileInputStream(inPipe.getFileDescriptor());
|
FileInputStream raw = new FileInputStream(inPipe.getFileDescriptor());
|
||||||
DataInputStream in = new DataInputStream(raw);
|
DataInputStream in = new DataInputStream(raw);
|
||||||
|
|
||||||
@@ -4445,7 +4446,8 @@ public class BackupManagerService {
|
|||||||
(new Thread(backupRunner, "package-backup-bridge")).start();
|
(new Thread(backupRunner, "package-backup-bridge")).start();
|
||||||
|
|
||||||
// Read data off the engine pipe and pass it to the transport
|
// Read data off the engine pipe and pass it to the transport
|
||||||
// pipe until we hit EOD on the input stream.
|
// pipe until we hit EOD on the input stream. We do not take
|
||||||
|
// close() responsibility for these FDs into these stream wrappers.
|
||||||
FileInputStream in = new FileInputStream(
|
FileInputStream in = new FileInputStream(
|
||||||
enginePipes[0].getFileDescriptor());
|
enginePipes[0].getFileDescriptor());
|
||||||
FileOutputStream out = new FileOutputStream(
|
FileOutputStream out = new FileOutputStream(
|
||||||
@@ -8579,7 +8581,10 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF
|
|||||||
EngineThread(FullRestoreEngine engine, ParcelFileDescriptor engineSocket) {
|
EngineThread(FullRestoreEngine engine, ParcelFileDescriptor engineSocket) {
|
||||||
mEngine = engine;
|
mEngine = engine;
|
||||||
engine.setRunning(true);
|
engine.setRunning(true);
|
||||||
mEngineStream = new FileInputStream(engineSocket.getFileDescriptor());
|
// We *do* want this FileInputStream to own the underlying fd, so that
|
||||||
|
// when we are finished with it, it closes this end of the pipe in a way
|
||||||
|
// that signals its other end.
|
||||||
|
mEngineStream = new FileInputStream(engineSocket.getFileDescriptor(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isRunning() {
|
public boolean isRunning() {
|
||||||
@@ -8598,6 +8603,8 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF
|
|||||||
mEngine.restoreOneFile(mEngineStream, false);
|
mEngine.restoreOneFile(mEngineStream, false);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
// Because mEngineStream adopted its underlying FD, this also
|
||||||
|
// closes this end of the pipe.
|
||||||
IoUtils.closeQuietly(mEngineStream);
|
IoUtils.closeQuietly(mEngineStream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user