aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2023-03-18 11:59:17 +0800
committerPo Lu2023-03-18 11:59:17 +0800
commit6d28b596a9f2da8ed02d71b6815ffc1bda61c11e (patch)
treefbcbad9512bfcac5a07cad5eaafb39b50720ae72 /src
parent634e3fcc20ea9fa5b1af59286f4b846a351f52c8 (diff)
downloademacs-6d28b596a9f2da8ed02d71b6815ffc1bda61c11e.tar.gz
emacs-6d28b596a9f2da8ed02d71b6815ffc1bda61c11e.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/android.c27
1 files changed, 18 insertions, 9 deletions
diff --git a/src/android.c b/src/android.c
index efbf8fc95cc..1da8bec316e 100644
--- a/src/android.c
+++ b/src/android.c
@@ -304,9 +304,6 @@ static struct timespec *volatile android_pselect_timeout;
304/* Value of pselect. */ 304/* Value of pselect. */
305static int android_pselect_rc; 305static int android_pselect_rc;
306 306
307/* Whether or not pselect finished. */
308static volatile bool android_pselect_completed;
309
310/* The global event queue. */ 307/* The global event queue. */
311static struct android_event_queue event_queue; 308static struct android_event_queue event_queue;
312 309
@@ -318,6 +315,11 @@ static sem_t android_pselect_sem, android_pselect_start_sem;
318/* Select self-pipe. */ 315/* Select self-pipe. */
319static int select_pipe[2]; 316static int select_pipe[2];
320 317
318#else
319
320/* Whether or not pselect has been interrupted. */
321static volatile sig_atomic_t android_pselect_interrupted;
322
321#endif 323#endif
322 324
323static void * 325static void *
@@ -388,7 +390,6 @@ android_run_select_thread (void *data)
388 condition variable. */ 390 condition variable. */
389 391
390 pthread_mutex_lock (&event_queue.mutex); 392 pthread_mutex_lock (&event_queue.mutex);
391 android_pselect_completed = true;
392 pthread_cond_broadcast (&event_queue.read_var); 393 pthread_cond_broadcast (&event_queue.read_var);
393 pthread_mutex_unlock (&event_queue.mutex); 394 pthread_mutex_unlock (&event_queue.mutex);
394 395
@@ -417,6 +418,10 @@ android_run_select_thread (void *data)
417 while (sem_wait (&android_pselect_start_sem) < 0) 418 while (sem_wait (&android_pselect_start_sem) < 0)
418 ;; 419 ;;
419 420
421 /* Clear the ``pselect interrupted'' flag. This is safe because
422 right now, SIGUSR1 is blocked. */
423 android_pselect_interrupted = 0;
424
420 /* Get the select lock and call pselect. */ 425 /* Get the select lock and call pselect. */
421 pthread_mutex_lock (&event_queue.select_mutex); 426 pthread_mutex_lock (&event_queue.select_mutex);
422 rc = pselect (android_pselect_nfds, 427 rc = pselect (android_pselect_nfds,
@@ -434,11 +439,16 @@ android_run_select_thread (void *data)
434 condition variable. */ 439 condition variable. */
435 440
436 pthread_mutex_lock (&event_queue.mutex); 441 pthread_mutex_lock (&event_queue.mutex);
437 android_pselect_completed = true;
438 pthread_cond_broadcast (&event_queue.read_var); 442 pthread_cond_broadcast (&event_queue.read_var);
439 pthread_mutex_unlock (&event_queue.mutex); 443 pthread_mutex_unlock (&event_queue.mutex);
440 444
441 if (rc != -1 || errno != EINTR) 445 /* Check `android_pselect_interrupted' instead of rc and errno.
446
447 This is because `pselect' does not return an rc of -1 upon
448 being interrupted in some versions of Android, but does set
449 signal masks correctly. */
450
451 if (!android_pselect_interrupted)
442 /* Now, wait for SIGUSR1, unless pselect was interrupted and 452 /* Now, wait for SIGUSR1, unless pselect was interrupted and
443 the signal was already delivered. The Emacs thread will 453 the signal was already delivered. The Emacs thread will
444 always send this signal after read_var is triggered or the 454 always send this signal after read_var is triggered or the
@@ -460,8 +470,8 @@ android_run_select_thread (void *data)
460static void 470static void
461android_handle_sigusr1 (int sig, siginfo_t *siginfo, void *arg) 471android_handle_sigusr1 (int sig, siginfo_t *siginfo, void *arg)
462{ 472{
463 /* Nothing to do here, this signal handler is only installed to make 473 /* Notice that pselect has been interrupted. */
464 sure the disposition of SIGUSR1 is enough. */ 474 android_pselect_interrupted = 1;
465} 475}
466 476
467#endif 477#endif
@@ -686,7 +696,6 @@ android_select (int nfds, fd_set *readfds, fd_set *writefds,
686 } 696 }
687 697
688 nfds_return = 0; 698 nfds_return = 0;
689 android_pselect_completed = false;
690 699
691 pthread_mutex_lock (&event_queue.select_mutex); 700 pthread_mutex_lock (&event_queue.select_mutex);
692 android_pselect_nfds = nfds; 701 android_pselect_nfds = nfds;