Work around pselect lossage on Android

* src/android.c (android_run_select_thread): New flag.  Use it
rather than the rc of pselect and errno to determine whether or
not it has been interrupted.
(android_handle_sigusr1): Set said flag.
This commit is contained in:
Po Lu 2023-03-18 11:59:17 +08:00
parent 634e3fcc20
commit 6d28b596a9

View file

@ -304,9 +304,6 @@ static struct timespec *volatile android_pselect_timeout;
/* Value of pselect. */
static int android_pselect_rc;
/* Whether or not pselect finished. */
static volatile bool android_pselect_completed;
/* The global event queue. */
static struct android_event_queue event_queue;
@ -318,6 +315,11 @@ static sem_t android_pselect_sem, android_pselect_start_sem;
/* Select self-pipe. */
static int select_pipe[2];
#else
/* Whether or not pselect has been interrupted. */
static volatile sig_atomic_t android_pselect_interrupted;
#endif
static void *
@ -388,7 +390,6 @@ android_run_select_thread (void *data)
condition variable. */
pthread_mutex_lock (&event_queue.mutex);
android_pselect_completed = true;
pthread_cond_broadcast (&event_queue.read_var);
pthread_mutex_unlock (&event_queue.mutex);
@ -417,6 +418,10 @@ android_run_select_thread (void *data)
while (sem_wait (&android_pselect_start_sem) < 0)
;;
/* Clear the ``pselect interrupted'' flag. This is safe because
right now, SIGUSR1 is blocked. */
android_pselect_interrupted = 0;
/* Get the select lock and call pselect. */
pthread_mutex_lock (&event_queue.select_mutex);
rc = pselect (android_pselect_nfds,
@ -434,11 +439,16 @@ android_run_select_thread (void *data)
condition variable. */
pthread_mutex_lock (&event_queue.mutex);
android_pselect_completed = true;
pthread_cond_broadcast (&event_queue.read_var);
pthread_mutex_unlock (&event_queue.mutex);
if (rc != -1 || errno != EINTR)
/* Check `android_pselect_interrupted' instead of rc and errno.
This is because `pselect' does not return an rc of -1 upon
being interrupted in some versions of Android, but does set
signal masks correctly. */
if (!android_pselect_interrupted)
/* Now, wait for SIGUSR1, unless pselect was interrupted and
the signal was already delivered. The Emacs thread will
always send this signal after read_var is triggered or the
@ -460,8 +470,8 @@ android_run_select_thread (void *data)
static void
android_handle_sigusr1 (int sig, siginfo_t *siginfo, void *arg)
{
/* Nothing to do here, this signal handler is only installed to make
sure the disposition of SIGUSR1 is enough. */
/* Notice that pselect has been interrupted. */
android_pselect_interrupted = 1;
}
#endif
@ -686,7 +696,6 @@ android_select (int nfds, fd_set *readfds, fd_set *writefds,
}
nfds_return = 0;
android_pselect_completed = false;
pthread_mutex_lock (&event_queue.select_mutex);
android_pselect_nfds = nfds;