am 50d11ded: Merge "Reimplement LocalSocket methods using android.system.Os"
* commit '50d11ded0d219ea9b128557080e4ffd49ebea5ab': Reimplement LocalSocket methods using android.system.Os
This commit is contained in:
@@ -27,6 +27,7 @@ import android.system.Os;
|
|||||||
import android.system.OsConstants;
|
import android.system.OsConstants;
|
||||||
import android.system.StructLinger;
|
import android.system.StructLinger;
|
||||||
import android.system.StructTimeval;
|
import android.system.StructTimeval;
|
||||||
|
import android.util.MutableInt;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Socket implementation used for android.net.LocalSocket and
|
* Socket implementation used for android.net.LocalSocket and
|
||||||
@@ -61,7 +62,13 @@ class LocalSocketImpl
|
|||||||
FileDescriptor myFd = fd;
|
FileDescriptor myFd = fd;
|
||||||
if (myFd == null) throw new IOException("socket closed");
|
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} */
|
/** {@inheritDoc} */
|
||||||
@@ -158,18 +165,31 @@ class LocalSocketImpl
|
|||||||
public void flush() throws IOException {
|
public void flush() throws IOException {
|
||||||
FileDescriptor myFd = fd;
|
FileDescriptor myFd = fd;
|
||||||
if (myFd == null) throw new IOException("socket closed");
|
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 {
|
try {
|
||||||
Thread.sleep(10);
|
Thread.sleep(10);
|
||||||
} catch (InterruptedException ie) {
|
} 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 read_native(FileDescriptor fd) throws IOException;
|
||||||
private native int readba_native(byte[] b, int off, int len,
|
private native int readba_native(byte[] b, int off, int len,
|
||||||
FileDescriptor fd) throws IOException;
|
FileDescriptor fd) throws IOException;
|
||||||
|
|||||||
@@ -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
|
* Processes ancillary data, handling only
|
||||||
* SCM_RIGHTS. Creates appropriate objects and sets appropriate
|
* 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},
|
{"listen_native", "(Ljava/io/FileDescriptor;I)V", (void*)socket_listen},
|
||||||
{"accept", "(Ljava/io/FileDescriptor;Landroid/net/LocalSocketImpl;)Ljava/io/FileDescriptor;", (void*)socket_accept},
|
{"accept", "(Ljava/io/FileDescriptor;Landroid/net/LocalSocketImpl;)Ljava/io/FileDescriptor;", (void*)socket_accept},
|
||||||
{"shutdown", "(Ljava/io/FileDescriptor;Z)V", (void*)socket_shutdown},
|
{"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},
|
{"read_native", "(Ljava/io/FileDescriptor;)I", (void*) socket_read},
|
||||||
{"readba_native", "([BIILjava/io/FileDescriptor;)I", (void*) socket_readba},
|
{"readba_native", "([BIILjava/io/FileDescriptor;)I", (void*) socket_readba},
|
||||||
{"writeba_native", "([BIILjava/io/FileDescriptor;)V", (void*) socket_writeba},
|
{"writeba_native", "([BIILjava/io/FileDescriptor;)V", (void*) socket_writeba},
|
||||||
|
|||||||
Reference in New Issue
Block a user