emacs-diffs
[Top][All Lists]
Advanced

[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;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]