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

Commit 50d11ded authored by Neil Fuller's avatar Neil Fuller Committed by Gerrit Code Review
Browse files

Merge "Reimplement LocalSocket methods using android.system.Os"

parents 0254af6f d2df87eb
Loading
Loading
Loading
Loading
+25 −5
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.system.Os;
import android.system.OsConstants;
import android.system.StructLinger;
import android.system.StructTimeval;
import android.util.MutableInt;

/**
 * Socket implementation used for android.net.LocalSocket and
@@ -61,7 +62,13 @@ class LocalSocketImpl
            FileDescriptor myFd = fd;
            if (myFd == null) throw new IOException("socket closed");

            return available_native(myFd);
            MutableInt avail = new MutableInt(0);
            try {
                Os.ioctlInt(myFd, OsConstants.FIONREAD, avail);
            } catch (ErrnoException e) {
                throw e.rethrowAsIOException();
            }
            return avail.value;
        }

        /** {@inheritDoc} */
@@ -158,18 +165,31 @@ class LocalSocketImpl
        public void flush() throws IOException {
            FileDescriptor myFd = fd;
            if (myFd == null) throw new IOException("socket closed");
            while(pending_native(myFd) > 0) {

            // Loop until the output buffer is empty.
            MutableInt pending = new MutableInt(0);
            while (true) {
                try {
                    // See linux/net/unix/af_unix.c
                    Os.ioctlInt(myFd, OsConstants.TIOCOUTQ, pending);
                } catch (ErrnoException e) {
                    throw e.rethrowAsIOException();
                }

                if (pending.value <= 0) {
                    // The output buffer is empty.
                    break;
                }

                try {
                    Thread.sleep(10);
                } catch (InterruptedException ie) {
                    return;
                    break;
                }
            }
        }
    }

    private native int pending_native(FileDescriptor fd) throws IOException;
    private native int available_native(FileDescriptor fd) throws IOException;
    private native int read_native(FileDescriptor fd) throws IOException;
    private native int readba_native(byte[] b, int off, int len,
            FileDescriptor fd) throws IOException;
+0 −76
Original line number Diff line number Diff line
@@ -199,80 +199,6 @@ socket_shutdown (JNIEnv *env, jobject object, jobject fileDescriptor,
    }
}

static jint socket_pending (JNIEnv *env, jobject object,
        jobject fileDescriptor)
{
    int fd;

    fd = jniGetFDFromFileDescriptor(env, fileDescriptor);

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

    int pending;
    int ret = ioctl(fd, TIOCOUTQ, &pending);

    // If this were a non-socket fd, there would be other cases to worry
    // about...

    //ALOGD("socket_pending, ioctl ret:%d, pending:%d", ret, pending);
    if (ret < 0) {
        jniThrowIOException(env, errno);
        return (jint) 0;
    }

    return (jint)pending;
}
static jint socket_available (JNIEnv *env, jobject object,
        jobject fileDescriptor)
{
    int fd;

    fd = jniGetFDFromFileDescriptor(env, fileDescriptor);

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

#if 1
    int avail;
    int ret = ioctl(fd, FIONREAD, &avail);

    // If this were a non-socket fd, there would be other cases to worry
    // about...

    if (ret < 0) {
        jniThrowIOException(env, errno);
        return (jint) 0;
    }

    return (jint)avail;
#else
// there appears to be a bionic bug that prevents this version from working.

    ssize_t ret;
    struct msghdr msg;

    memset(&msg, 0, sizeof(msg));

    do {
        ret = recvmsg(fd, &msg, MSG_PEEK | MSG_DONTWAIT | MSG_NOSIGNAL);
    } while (ret < 0 && errno == EINTR);


    // MSG_PEEK returns 0 on EOF and EWOULDBLOCK on none available
    if (ret < 0 && errno == EWOULDBLOCK) {
        return 0;
    } if (ret < 0) {
        jniThrowIOException(env, errno);
        return -1;
    }

    return (jint)ret;
#endif
}

/**
 * Processes ancillary data, handling only
 * SCM_RIGHTS. Creates appropriate objects and sets appropriate
@@ -664,8 +590,6 @@ static JNINativeMethod gMethods[] = {
    {"listen_native", "(Ljava/io/FileDescriptor;I)V", (void*)socket_listen},
    {"accept", "(Ljava/io/FileDescriptor;Landroid/net/LocalSocketImpl;)Ljava/io/FileDescriptor;", (void*)socket_accept},
    {"shutdown", "(Ljava/io/FileDescriptor;Z)V", (void*)socket_shutdown},
    {"available_native", "(Ljava/io/FileDescriptor;)I", (void*) socket_available},
    {"pending_native", "(Ljava/io/FileDescriptor;)I", (void*) socket_pending},
    {"read_native", "(Ljava/io/FileDescriptor;)I", (void*) socket_read},
    {"readba_native", "([BIILjava/io/FileDescriptor;)I", (void*) socket_readba},
    {"writeba_native", "([BIILjava/io/FileDescriptor;)V", (void*) socket_writeba},