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

Commit 894724be authored by Elliott Hughes's avatar Elliott Hughes
Browse files

Rewrite selectReadable JNI in Java.

Bug: 18719692
Change-Id: Id4fa95a31f112c720f7a3ac47a3b6c95c3028438
parent e9e1e0d2
Loading
Loading
Loading
Loading
+26 −31
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.internal.os;

import static android.system.OsConstants.POLLIN;
import static android.system.OsConstants.POLLOUT;
import static android.system.OsConstants.S_IRWXG;
import static android.system.OsConstants.S_IRWXO;

@@ -32,6 +34,7 @@ import android.os.Trace;
import android.system.ErrnoException;
import android.system.Os;
import android.system.OsConstants;
import android.system.StructPollfd;
import android.util.EventLog;
import android.util.Log;
import android.util.Slog;
@@ -699,34 +702,36 @@ public class ZygoteInit {
    private static void runSelectLoop(String abiList) throws MethodAndArgsCaller {
        ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
        ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
        FileDescriptor[] fdArray = new FileDescriptor[4];

        fds.add(sServerSocket.getFileDescriptor());
        peers.add(null);

        while (true) {
            int index;

            StructPollfd[] pollFds = new StructPollfd[fds.size()];
            for (int i = 0; i < pollFds.length; ++i) {
                pollFds[i] = new StructPollfd();
                pollFds[i].fd = fds.get(i);
                pollFds[i].events = (short) POLLIN;
            }
            try {
                fdArray = fds.toArray(fdArray);
                index = selectReadable(fdArray);
            } catch (IOException ex) {
                throw new RuntimeException("Error in select()", ex);
                Os.poll(pollFds, -1);
            } catch (ErrnoException ex) {
                throw new RuntimeException("poll failed", ex);
            }

            if (index < 0) {
                throw new RuntimeException("Error in select()");
            } else if (index == 0) {
            for (int i = pollFds.length - 1; i >= 0; --i) {
                if ((pollFds[i].revents & POLLIN) == 0) {
                    continue;
                }
                if (i == 0) {
                    ZygoteConnection newPeer = acceptCommandPeer(abiList);
                    peers.add(newPeer);
                    fds.add(newPeer.getFileDesciptor());
                } else {
                boolean done;
                done = peers.get(index).runOnce();

                    boolean done = peers.get(i).runOnce();
                    if (done) {
                    peers.remove(index);
                    fds.remove(index);
                        peers.remove(i);
                        fds.remove(i);
                    }
                }
            }
        }
@@ -766,16 +771,6 @@ public class ZygoteInit {
     */
    static native int getpgid(int pid) throws IOException;

    /**
     * Invokes select() on the provider array of file descriptors (selecting
     * for readability only). Array elements of null are ignored.
     *
     * @param fds non-null; array of readable file descriptors
     * @return index of descriptor that is now readable or -1 for empty array.
     * @throws IOException if an error occurs
     */
    static native int selectReadable(FileDescriptor[] fds) throws IOException;

    /**
     * Class not instantiable.
     */
+0 −69
Original line number Diff line number Diff line
@@ -88,73 +88,6 @@ static jint com_android_internal_os_ZygoteInit_getpgid(
    return ret;
}

static jint com_android_internal_os_ZygoteInit_selectReadable (
        JNIEnv *env, jobject clazz, jobjectArray fds)
{
    if (fds == NULL) {
        jniThrowNullPointerException(env, "fds == null");
        return -1;
    }

    jsize length = env->GetArrayLength(fds);
    fd_set fdset;

    if (env->ExceptionCheck()) {
        return -1;
    }

    FD_ZERO(&fdset);

    int nfds = 0;
    for (jsize i = 0; i < length; i++) {
        jobject fdObj = env->GetObjectArrayElement(fds, i);
        if  (env->ExceptionCheck()) {
            return -1;
        }
        if (fdObj == NULL) {
            continue;
        }
        int fd = jniGetFDFromFileDescriptor(env, fdObj);
        if  (env->ExceptionCheck()) {
            return -1;
        }

        FD_SET(fd, &fdset);

        if (fd >= nfds) {
            nfds = fd + 1;
        }
    }

    int err;
    do {
        err = select (nfds, &fdset, NULL, NULL, NULL);
    } while (err < 0 && errno == EINTR);

    if (err < 0) {
        jniThrowIOException(env, errno);
        return -1;
    }

    for (jsize i = 0; i < length; i++) {
        jobject fdObj = env->GetObjectArrayElement(fds, i);
        if  (env->ExceptionCheck()) {
            return -1;
        }
        if (fdObj == NULL) {
            continue;
        }
        int fd = jniGetFDFromFileDescriptor(env, fdObj);
        if  (env->ExceptionCheck()) {
            return -1;
        }
        if (FD_ISSET(fd, &fdset)) {
            return (jint)i;
        }
    }
    return -1;
}

/*
 * JNI registration.
 */
@@ -168,8 +101,6 @@ static JNINativeMethod gMethods[] = {
      (void *) com_android_internal_os_ZygoteInit_setpgid },
    { "getpgid", "(I)I",
      (void *) com_android_internal_os_ZygoteInit_getpgid },
    { "selectReadable", "([Ljava/io/FileDescriptor;)I",
        (void *) com_android_internal_os_ZygoteInit_selectReadable },
};
int register_com_android_internal_os_ZygoteInit(JNIEnv* env)
{