diff options
author | bohu <bohu@google.com> | 2015-09-17 18:13:40 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2015-09-17 18:13:40 +0000 |
commit | f20cca78fc06398de0701d0c5bba589c0fe2f738 (patch) | |
tree | 867d51e276d1bcb1ca7f8c0954453cb6bc4e6898 | |
parent | a36a210bcb07e7a84fe2a454ef5fdc05f1990616 (diff) | |
parent | 948dfb6e500f11106f68671d77f85bb633e678ce (diff) | |
download | goldfish-marshmallow-mr2-release.tar.gz |
am 948dfb6e: emulator-fingerprint: Exit listener thread on HAL closeandroid-6.0.1_r9android-6.0.1_r81android-6.0.1_r80android-6.0.1_r8android-6.0.1_r79android-6.0.1_r78android-6.0.1_r77android-6.0.1_r74android-6.0.1_r73android-6.0.1_r72android-6.0.1_r70android-6.0.1_r7android-6.0.1_r69android-6.0.1_r68android-6.0.1_r67android-6.0.1_r66android-6.0.1_r65android-6.0.1_r63android-6.0.1_r62android-6.0.1_r61android-6.0.1_r60android-6.0.1_r59android-6.0.1_r58android-6.0.1_r57android-6.0.1_r56android-6.0.1_r55android-6.0.1_r54android-6.0.1_r53android-6.0.1_r52android-6.0.1_r51android-6.0.1_r50android-6.0.1_r5android-6.0.1_r49android-6.0.1_r48android-6.0.1_r47android-6.0.1_r46android-6.0.1_r45android-6.0.1_r43android-6.0.1_r42android-6.0.1_r41android-6.0.1_r40android-6.0.1_r4android-6.0.1_r33android-6.0.1_r32android-6.0.1_r31android-6.0.1_r30android-6.0.1_r3android-6.0.1_r28android-6.0.1_r27android-6.0.1_r26android-6.0.1_r25android-6.0.1_r24android-6.0.1_r22android-6.0.1_r21android-6.0.1_r20android-6.0.1_r18android-6.0.1_r17android-6.0.1_r16android-6.0.1_r13android-6.0.1_r12android-6.0.1_r11android-6.0.1_r10android-6.0.1_r1android-6.0.0_r41android-6.0.0_r26android-6.0.0_r25android-6.0.0_r24android-6.0.0_r23android-6.0.0_r13android-6.0.0_r12android-6.0.0_r11marshmallow-mr3-releasemarshmallow-mr2-releasemarshmallow-mr1-releasemarshmallow-mr1-devmarshmallow-dr1.6-releasemarshmallow-dr1.5-releasemarshmallow-dr1.5-devmarshmallow-dr-releasemarshmallow-dr-dragon-releasemarshmallow-dr-dev
* commit '948dfb6e500f11106f68671d77f85bb633e678ce':
emulator-fingerprint: Exit listener thread on HAL close
-rw-r--r-- | fingerprint/fingerprint.c | 66 |
1 files changed, 60 insertions, 6 deletions
diff --git a/fingerprint/fingerprint.c b/fingerprint/fingerprint.c index 0b4ca7f8..baa7ad6c 100644 --- a/fingerprint/fingerprint.c +++ b/fingerprint/fingerprint.c @@ -37,6 +37,8 @@ #include <hardware/fingerprint.h> #include <hardware/qemud.h> +#include <poll.h> + #define FINGERPRINT_LISTEN_SERVICE_NAME "fingerprintlisten" #define FINGERPRINT_FILENAME \ "/data/system/users/0/fpdata/emulator_fingerprint_storage.bin" @@ -509,7 +511,7 @@ static void send_enroll_notice(qemu_fingerprint_device_t* qdev, int fid) { } static worker_state_t getListenerState(qemu_fingerprint_device_t* dev) { - ALOGD("----------------> %s ----------------->", __FUNCTION__); + ALOGV("----------------> %s ----------------->", __FUNCTION__); worker_state_t state = STATE_IDLE; pthread_mutex_lock(&dev->lock); @@ -559,14 +561,59 @@ static void* listenerFunction(void* data) { const char* cmd = "listen"; if (qemud_channel_send(qdev->qchanfd, cmd, strlen(cmd)) < 0) { ALOGE("cannot write fingerprint 'listen' to host"); - return NULL; + goto done_quiet; } + int comm_errors = 0; - while (getListenerState(qdev) != STATE_EXIT) { + struct pollfd pfd = { + .fd = qdev->qchanfd, + .events = POLLIN, + }; + while (1) { int size = 0; int fid = 0; char buffer[MAX_COMM_CHARS] = {0}; - // will block until a new event happens + bool disconnected = false; + while (1) { + if (getListenerState(qdev) == STATE_EXIT) { + ALOGD("Received request to exit listener thread"); + goto done; + } + + // Reset revents before poll() (just to be safe) + pfd.revents = 0; + + // Poll qemud channel for 5 seconds + // TODO: Eliminate the timeout so that polling can be interrupted + // instantly. One possible solution is to follow the example of + // android::Looper ($AOSP/system/core/include/utils/Looper.h and + // $AOSP/system/core/libutils/Looper.cpp), which makes use of an + // additional file descriptor ("wake event fd"). + int nfds = poll(&pfd, 1, 5000); + if (nfds < 0) { + ALOGE("Could not poll qemud channel: %s", strerror(errno)); + goto done; + } + + if (!nfds) { + // poll() timed out - try again + continue; + } + + // assert(nfds == 1) + if (pfd.revents & POLLIN) { + // Input data being available doesn't rule out a disconnection + disconnected = pfd.revents & (POLLERR | POLLHUP); + break; // Exit inner while loop + } else { + // Some event(s) other than "input data available" occurred, + // i.e. POLLERR or POLLHUP, indicating a disconnection + ALOGW("Lost connection to qemud channel"); + goto done; + } + } + + // Shouldn't block since we were just notified of a POLLIN event if ((size = qemud_channel_recv(qdev->qchanfd, buffer, sizeof(buffer) - 1)) > 0) { buffer[size] = '\0'; @@ -597,6 +644,11 @@ static void* listenerFunction(void* data) { } else { ALOGE("Invalid command '%s' to fingerprint listener", buffer); } + + if (disconnected) { + ALOGW("Connection to qemud channel has been lost"); + break; + } } else { ALOGE("fingerprint listener receive failure"); if (comm_errors > MAX_COMM_ERRORS) @@ -604,7 +656,10 @@ static void* listenerFunction(void* data) { } } +done: ALOGD("Listener exit with %d receive errors", comm_errors); +done_quiet: + close(qdev->qchanfd); return NULL; } @@ -617,8 +672,7 @@ static int fingerprint_close(hw_device_t* device) { qemu_fingerprint_device_t* qdev = (qemu_fingerprint_device_t*)device; pthread_mutex_lock(&qdev->lock); - if (qdev->qchanfd != 0) - close(qdev->qchanfd); // unblock listener + // Ask listener thread to exit qdev->listener.state = STATE_EXIT; pthread_mutex_unlock(&qdev->lock); |