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:
Christopher Tate
2016-05-16 11:52:41 -07:00
committed by Chris Tate
parent 19397a4492
commit 3bed1c0ef8

View File

@@ -3528,6 +3528,7 @@ public class BackupManagerService {
private void routeSocketDataToOutput(ParcelFileDescriptor inPipe, OutputStream out)
throws IOException {
// We do not take close() responsibility for the pipe FD
FileInputStream raw = new FileInputStream(inPipe.getFileDescriptor());
DataInputStream in = new DataInputStream(raw);
@@ -4445,7 +4446,8 @@ public class BackupManagerService {
(new Thread(backupRunner, "package-backup-bridge")).start();
// 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(
enginePipes[0].getFileDescriptor());
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) {
mEngine = engine;
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() {
@@ -8598,6 +8603,8 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF
mEngine.restoreOneFile(mEngineStream, false);
}
} finally {
// Because mEngineStream adopted its underlying FD, this also
// closes this end of the pipe.
IoUtils.closeQuietly(mEngineStream);
}
}