[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
feature/android 8747568d698 1/5: Make android_select more robust
From: |
Po Lu |
Subject: |
feature/android 8747568d698 1/5: Make android_select more robust |
Date: |
Thu, 23 Feb 2023 08:58:11 -0500 (EST) |
branch: feature/android
commit 8747568d698575d61829358b456077ec3b0deabf
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>
Make android_select more robust
* src/android.c (android_run_select_thread): Lock select_mutex
before signalling condition variable.
(android_select): Unlock event queue mutex prior to waiting for
it.
---
src/android.c | 25 +++++++++++++++++--------
1 file changed, 17 insertions(+), 8 deletions(-)
diff --git a/src/android.c b/src/android.c
index 4639d84a2a1..ffeb4b659d9 100644
--- a/src/android.c
+++ b/src/android.c
@@ -387,12 +387,15 @@ android_run_select_thread (void *data)
android_pselect_rc = rc;
pthread_mutex_unlock (&event_queue.select_mutex);
- /* Signal the main thread that there is now data to read.
- It is ok to signal this condition variable without holding
- the event queue lock, because android_select will always
- wait for this to complete before returning. */
+ /* Signal the main thread that there is now data to read. Hold
+ the event queue lock during this process to make sure this
+ does not happen before the main thread begins to wait for the
+ condition variable. */
+
+ pthread_mutex_lock (&event_queue.select_mutex);
android_pselect_completed = true;
pthread_cond_broadcast (&event_queue.read_var);
+ pthread_mutex_unlock (&event_queue.select_mutex);
if (rc != -1 || errno != EINTR)
/* Now, wait for SIGUSR1, unless pselect was interrupted and
@@ -635,13 +638,22 @@ android_select (int nfds, fd_set *readfds, fd_set
*writefds,
"write: %s", strerror (errno));
#endif
- /* Wait for pselect to return in any case. */
+ /* Unlock the event queue mutex. */
+ pthread_mutex_unlock (&event_queue.mutex);
+
+ /* Wait for pselect to return in any case. This must be done with
+ the event queue mutex unlocked. Otherwise, the pselect thread
+ can hang if it tries to lock the event queue mutex to signal
+ read_var after the UI thread has already done so. */
while (sem_wait (&android_pselect_sem) < 0)
;;
/* If there are now events in the queue, return 1. */
+
+ pthread_mutex_lock (&event_queue.mutex);
if (event_queue.num_events)
nfds_return = 1;
+ pthread_mutex_unlock (&event_queue.mutex);
/* Add the return value of pselect. */
if (android_pselect_rc >= 0)
@@ -650,9 +662,6 @@ android_select (int nfds, fd_set *readfds, fd_set *writefds,
if (!nfds_return && android_pselect_rc < 0)
nfds_return = android_pselect_rc;
- /* Unlock the event queue mutex. */
- pthread_mutex_unlock (&event_queue.mutex);
-
/* This is to shut up process.c when pselect gets EINTR. */
if (nfds_return < 0)
errno = EINTR;