aboutsummaryrefslogtreecommitdiffstats
path: root/src/android.c
diff options
context:
space:
mode:
authorPo Lu2023-02-23 18:05:57 +0800
committerPo Lu2023-02-23 18:05:57 +0800
commit8747568d698575d61829358b456077ec3b0deabf (patch)
tree389f8238f60f014ee7f8477ac46da6919aa16682 /src/android.c
parent1d84465236f82a3791cc40bc53ecac30c93e489d (diff)
downloademacs-8747568d698575d61829358b456077ec3b0deabf.tar.gz
emacs-8747568d698575d61829358b456077ec3b0deabf.zip
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.
Diffstat (limited to 'src/android.c')
-rw-r--r--src/android.c25
1 files 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)
387 android_pselect_rc = rc; 387 android_pselect_rc = rc;
388 pthread_mutex_unlock (&event_queue.select_mutex); 388 pthread_mutex_unlock (&event_queue.select_mutex);
389 389
390 /* Signal the main thread that there is now data to read. 390 /* Signal the main thread that there is now data to read. Hold
391 It is ok to signal this condition variable without holding 391 the event queue lock during this process to make sure this
392 the event queue lock, because android_select will always 392 does not happen before the main thread begins to wait for the
393 wait for this to complete before returning. */ 393 condition variable. */
394
395 pthread_mutex_lock (&event_queue.select_mutex);
394 android_pselect_completed = true; 396 android_pselect_completed = true;
395 pthread_cond_broadcast (&event_queue.read_var); 397 pthread_cond_broadcast (&event_queue.read_var);
398 pthread_mutex_unlock (&event_queue.select_mutex);
396 399
397 if (rc != -1 || errno != EINTR) 400 if (rc != -1 || errno != EINTR)
398 /* Now, wait for SIGUSR1, unless pselect was interrupted and 401 /* Now, wait for SIGUSR1, unless pselect was interrupted and
@@ -635,13 +638,22 @@ android_select (int nfds, fd_set *readfds, fd_set *writefds,
635 "write: %s", strerror (errno)); 638 "write: %s", strerror (errno));
636#endif 639#endif
637 640
638 /* Wait for pselect to return in any case. */ 641 /* Unlock the event queue mutex. */
642 pthread_mutex_unlock (&event_queue.mutex);
643
644 /* Wait for pselect to return in any case. This must be done with
645 the event queue mutex unlocked. Otherwise, the pselect thread
646 can hang if it tries to lock the event queue mutex to signal
647 read_var after the UI thread has already done so. */
639 while (sem_wait (&android_pselect_sem) < 0) 648 while (sem_wait (&android_pselect_sem) < 0)
640 ;; 649 ;;
641 650
642 /* If there are now events in the queue, return 1. */ 651 /* If there are now events in the queue, return 1. */
652
653 pthread_mutex_lock (&event_queue.mutex);
643 if (event_queue.num_events) 654 if (event_queue.num_events)
644 nfds_return = 1; 655 nfds_return = 1;
656 pthread_mutex_unlock (&event_queue.mutex);
645 657
646 /* Add the return value of pselect. */ 658 /* Add the return value of pselect. */
647 if (android_pselect_rc >= 0) 659 if (android_pselect_rc >= 0)
@@ -650,9 +662,6 @@ android_select (int nfds, fd_set *readfds, fd_set *writefds,
650 if (!nfds_return && android_pselect_rc < 0) 662 if (!nfds_return && android_pselect_rc < 0)
651 nfds_return = android_pselect_rc; 663 nfds_return = android_pselect_rc;
652 664
653 /* Unlock the event queue mutex. */
654 pthread_mutex_unlock (&event_queue.mutex);
655
656 /* This is to shut up process.c when pselect gets EINTR. */ 665 /* This is to shut up process.c when pselect gets EINTR. */
657 if (nfds_return < 0) 666 if (nfds_return < 0)
658 errno = EINTR; 667 errno = EINTR;