Use poll() to avoid an infinite blocking read() that causes ANRs during cleanup

This commit is contained in:
Cameron Gutman 2014-09-10 02:35:55 -07:00
parent 82f79c466a
commit b4c3f9678a
6 changed files with 24 additions and 2 deletions

View File

@ -6,6 +6,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <linux/input.h> #include <linux/input.h>
#include <unistd.h> #include <unistd.h>
#include <poll.h>
JNIEXPORT jint JNICALL JNIEXPORT jint JNICALL
Java_com_limelight_binding_input_evdev_EvdevReader_open(JNIEnv *env, jobject this, jstring absolutePath) { Java_com_limelight_binding_input_evdev_EvdevReader_open(JNIEnv *env, jobject this, jstring absolutePath) {
@ -60,12 +61,33 @@ Java_com_limelight_binding_input_evdev_EvdevReader_hasKey(JNIEnv *env, jobject t
JNIEXPORT jint JNICALL JNIEXPORT jint JNICALL
Java_com_limelight_binding_input_evdev_EvdevReader_read(JNIEnv *env, jobject this, jint fd, jbyteArray buffer) { Java_com_limelight_binding_input_evdev_EvdevReader_read(JNIEnv *env, jobject this, jint fd, jbyteArray buffer) {
jint ret; jint ret;
jbyte *data = (*env)->GetByteArrayElements(env, buffer, NULL); jbyte *data;
int pollres;
struct pollfd pollinfo;
data = (*env)->GetByteArrayElements(env, buffer, NULL);
if (data == NULL) { if (data == NULL) {
return -1; return -1;
} }
ret = read(fd, data, sizeof(struct input_event)); do
{
// Unwait every 250 ms to return to caller if the fd is closed
pollinfo.fd = fd;
pollinfo.events = POLLIN;
pollinfo.revents = 0;
pollres = poll(&pollinfo, 1, 250);
}
while (pollres == 0);
if (pollres > 0 && (pollinfo.revents & POLLIN)) {
// We'll have data available now
ret = read(fd, data, sizeof(struct input_event));
}
else {
// There must have been a failure
ret = -1;
}
(*env)->ReleaseByteArrayElements(env, buffer, data, 0); (*env)->ReleaseByteArrayElements(env, buffer, data, 0);

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.