diff options
| author | Po Lu | 2023-03-18 11:59:17 +0800 |
|---|---|---|
| committer | Po Lu | 2023-03-18 11:59:17 +0800 |
| commit | 6d28b596a9f2da8ed02d71b6815ffc1bda61c11e (patch) | |
| tree | fbcbad9512bfcac5a07cad5eaafb39b50720ae72 /src | |
| parent | 634e3fcc20ea9fa5b1af59286f4b846a351f52c8 (diff) | |
| download | emacs-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.c | 27 |
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. */ |
| 305 | static int android_pselect_rc; | 305 | static int android_pselect_rc; |
| 306 | 306 | ||
| 307 | /* Whether or not pselect finished. */ | ||
| 308 | static volatile bool android_pselect_completed; | ||
| 309 | |||
| 310 | /* The global event queue. */ | 307 | /* The global event queue. */ |
| 311 | static struct android_event_queue event_queue; | 308 | static 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. */ |
| 319 | static int select_pipe[2]; | 316 | static int select_pipe[2]; |
| 320 | 317 | ||
| 318 | #else | ||
| 319 | |||
| 320 | /* Whether or not pselect has been interrupted. */ | ||
| 321 | static volatile sig_atomic_t android_pselect_interrupted; | ||
| 322 | |||
| 321 | #endif | 323 | #endif |
| 322 | 324 | ||
| 323 | static void * | 325 | static 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) | |||
| 460 | static void | 470 | static void |
| 461 | android_handle_sigusr1 (int sig, siginfo_t *siginfo, void *arg) | 471 | android_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; |