Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 89d119ab authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Zygote: Poll with timeout for pid"

parents d27a6d62 3fbde346
Loading
Loading
Loading
Loading
+57 −9
Original line number Original line Diff line number Diff line
@@ -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;
@@ -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;
@@ -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