Merge "Zygote: Poll with timeout for pid" am: 89d119abe6
am: 6078facf1f
Change-Id: I360bf86dbd5ff0c0d3b0fd6bb207692fe1142bd1
This commit is contained in:
@@ -18,6 +18,7 @@ package com.android.internal.os;
|
||||
|
||||
import static android.system.OsConstants.F_SETFD;
|
||||
import static android.system.OsConstants.O_CLOEXEC;
|
||||
import static android.system.OsConstants.POLLIN;
|
||||
import static android.system.OsConstants.STDERR_FILENO;
|
||||
import static android.system.OsConstants.STDIN_FILENO;
|
||||
import static android.system.OsConstants.STDOUT_FILENO;
|
||||
@@ -31,13 +32,14 @@ import android.os.SystemProperties;
|
||||
import android.os.Trace;
|
||||
import android.system.ErrnoException;
|
||||
import android.system.Os;
|
||||
import android.system.StructPollfd;
|
||||
import android.util.Log;
|
||||
import dalvik.system.VMRuntime;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
@@ -852,17 +854,63 @@ class ZygoteConnection {
|
||||
|
||||
boolean usingWrapper = false;
|
||||
if (pipeFd != null && pid > 0) {
|
||||
DataInputStream is = new DataInputStream(new FileInputStream(pipeFd));
|
||||
int innerPid = -1;
|
||||
try {
|
||||
innerPid = is.readInt();
|
||||
} catch (IOException ex) {
|
||||
Log.w(TAG, "Error reading pid from wrapped process, child may have died", ex);
|
||||
} finally {
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException ex) {
|
||||
// Do a busy loop here. We can't guarantee that a failure (and thus an exception
|
||||
// bail) happens in a timely manner.
|
||||
//
|
||||
// We'll wait up to five seconds. This should give enough time for the fork to go
|
||||
// through, but not to trigger the watchdog in the system server.
|
||||
final int SLEEP_IN_MS = 5000;
|
||||
final int BYTES_REQUIRED = 4; // Bytes in an int.
|
||||
|
||||
StructPollfd fds[] = new StructPollfd[] {
|
||||
new StructPollfd()
|
||||
};
|
||||
|
||||
byte data[] = new byte[BYTES_REQUIRED];
|
||||
|
||||
int remainingSleepTime = SLEEP_IN_MS;
|
||||
int dataIndex = 0;
|
||||
long startTime = System.nanoTime();
|
||||
|
||||
while (dataIndex < data.length && remainingSleepTime > 0) {
|
||||
fds[0].fd = pipeFd;
|
||||
fds[0].events = (short) POLLIN;
|
||||
fds[0].revents = 0;
|
||||
fds[0].userData = null;
|
||||
|
||||
int res = android.system.Os.poll(fds, remainingSleepTime);
|
||||
long endTime = System.nanoTime();
|
||||
remainingSleepTime = SLEEP_IN_MS - (int)((endTime - startTime) / 1000000l);
|
||||
|
||||
if (res > 0) {
|
||||
if ((fds[0].revents & POLLIN) != 0) {
|
||||
// Only read one byte, so as not to block.
|
||||
int readBytes = android.system.Os.read(pipeFd, data, dataIndex, 1);
|
||||
if (readBytes < 0) {
|
||||
throw new RuntimeException("Some error");
|
||||
}
|
||||
dataIndex += readBytes;
|
||||
} else {
|
||||
// Error case. revents should contain one of the error bits.
|
||||
break;
|
||||
}
|
||||
} else if (res == 0) {
|
||||
Log.w(TAG, "Timed out waiting for child.");
|
||||
}
|
||||
}
|
||||
|
||||
if (dataIndex == data.length) {
|
||||
DataInputStream is = new DataInputStream(new ByteArrayInputStream(data));
|
||||
innerPid = is.readInt();
|
||||
}
|
||||
|
||||
if (innerPid == -1) {
|
||||
Log.w(TAG, "Error reading pid from wrapped process, child may have died");
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
Log.w(TAG, "Error reading pid from wrapped process, child may have died", ex);
|
||||
}
|
||||
|
||||
// Ensure that the pid reported by the wrapped process is either the
|
||||
|
||||
Reference in New Issue
Block a user