Loading core/java/com/android/internal/os/ZygoteConnection.java +57 −9 Original line number Original line Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.internal.os; import static android.system.OsConstants.F_SETFD; import static android.system.OsConstants.F_SETFD; import static android.system.OsConstants.O_CLOEXEC; 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.STDERR_FILENO; import static android.system.OsConstants.STDIN_FILENO; import static android.system.OsConstants.STDIN_FILENO; import static android.system.OsConstants.STDOUT_FILENO; import static android.system.OsConstants.STDOUT_FILENO; Loading @@ -31,13 +32,14 @@ import android.os.SystemProperties; import android.os.Trace; import android.os.Trace; import android.system.ErrnoException; import android.system.ErrnoException; import android.system.Os; import android.system.Os; import android.system.StructPollfd; import android.util.Log; import android.util.Log; import dalvik.system.VMRuntime; import dalvik.system.VMRuntime; import java.io.BufferedReader; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.DataOutputStream; import java.io.FileDescriptor; import java.io.FileDescriptor; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.IOException; import java.io.InputStreamReader; import java.io.InputStreamReader; Loading Loading @@ -807,17 +809,63 @@ class ZygoteConnection { boolean usingWrapper = false; boolean usingWrapper = false; if (pipeFd != null && pid > 0) { if (pipeFd != null && pid > 0) { DataInputStream is = new DataInputStream(new FileInputStream(pipeFd)); int innerPid = -1; int innerPid = -1; try { try { // 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(); 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) { } } 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 // Ensure that the pid reported by the wrapped process is either the Loading Loading
core/java/com/android/internal/os/ZygoteConnection.java +57 −9 Original line number Original line Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.internal.os; import static android.system.OsConstants.F_SETFD; import static android.system.OsConstants.F_SETFD; import static android.system.OsConstants.O_CLOEXEC; 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.STDERR_FILENO; import static android.system.OsConstants.STDIN_FILENO; import static android.system.OsConstants.STDIN_FILENO; import static android.system.OsConstants.STDOUT_FILENO; import static android.system.OsConstants.STDOUT_FILENO; Loading @@ -31,13 +32,14 @@ import android.os.SystemProperties; import android.os.Trace; import android.os.Trace; import android.system.ErrnoException; import android.system.ErrnoException; import android.system.Os; import android.system.Os; import android.system.StructPollfd; import android.util.Log; import android.util.Log; import dalvik.system.VMRuntime; import dalvik.system.VMRuntime; import java.io.BufferedReader; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.DataOutputStream; import java.io.FileDescriptor; import java.io.FileDescriptor; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.IOException; import java.io.InputStreamReader; import java.io.InputStreamReader; Loading Loading @@ -807,17 +809,63 @@ class ZygoteConnection { boolean usingWrapper = false; boolean usingWrapper = false; if (pipeFd != null && pid > 0) { if (pipeFd != null && pid > 0) { DataInputStream is = new DataInputStream(new FileInputStream(pipeFd)); int innerPid = -1; int innerPid = -1; try { try { // 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(); 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) { } } 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 // Ensure that the pid reported by the wrapped process is either the Loading