aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2025-02-28 19:49:34 +0800
committerPo Lu2025-02-28 19:54:46 +0800
commit8df582a46836e312ef3bfc36c8038b5f4a2c0d9b (patch)
tree752e9136202a8bfaa81000078a5a15e14d919d3e /src
parent8b9194ae03214dd5169bd84f7d83bbe660dd9f90 (diff)
downloademacs-8df582a46836e312ef3bfc36c8038b5f4a2c0d9b.tar.gz
emacs-8df582a46836e312ef3bfc36c8038b5f4a2c0d9b.zip
Fully support Lisp threads on Android
* src/android.c (struct android_thread_event_queue): New structure. Move global pselect arguments, mutexes, and semaphores, and pipes here. (struct android_event_queue) <select_mutex, select_thread>: Remove to the above-named struct. (android_init_thread_events, android_finalize_thread_events) (android_get_poll_thread): New functions. (android_run_select_thread): Accept a set of mutexes and thread-local data as the first argument, and operate with them rather than globals. (android_handle_sigusr1): Rename to `android_handle_poll_signal'. Set thread-specific cancellation indicator. (android_init_events): Properly abort after a fatal condition. Enable interruptible polling on Android 5.1 and later, not 4.2. (android_select): Never check for queries here, but in thread_select, if threads are enabled. Adapt to per-thread polling threads and only enable interruptible polling on Android 5.1 and later. (android_before_select): New function. * src/android.h (android_before_select): New declaration. * src/thread.c (thread_select): Call `android_before_select' before the global lock is released.
Diffstat (limited to 'src')
-rw-r--r--src/android.c524
-rw-r--r--src/android.h1
-rw-r--r--src/thread.c3
3 files changed, 343 insertions, 185 deletions
diff --git a/src/android.c b/src/android.c
index 05b593f0f31..15edca94fdf 100644
--- a/src/android.c
+++ b/src/android.c
@@ -266,57 +266,191 @@ struct android_event_container
266 union android_event event; 266 union android_event event;
267}; 267};
268 268
269struct android_event_queue 269/* Thread-specific component of the Android event queue. */
270{
271 /* Mutex protecting the event queue. */
272 pthread_mutex_t mutex;
273 270
271struct android_thread_event_queue
272{
274 /* Mutex protecting the select data. */ 273 /* Mutex protecting the select data. */
275 pthread_mutex_t select_mutex; 274 pthread_mutex_t select_mutex;
276 275
277 /* The thread used to run select. */ 276 /* The thread used to run select. */
278 pthread_t select_thread; 277 pthread_t select_thread;
279 278
279 /* Arguments to pselect used by the select thread. */
280 fd_set *select_readfds;
281 fd_set *select_writefds;
282 fd_set *select_exceptfds;
283 struct timespec *select_timeout;
284 int select_nfds;
285
286 /* Semaphores posted around invocations of pselect. */
287 sem_t start_sem;
288 sem_t select_sem;
289
290 /* Value of pselect. */
291 int select_rc;
292
293#if __ANDROID_API__ < 21
294 /* Select self-pipe. */
295 int select_pipe[2];
296#else /* __ANDROID_API__ >= 21 */
297 /* Whether a signal has been received to cancel pselect in this
298 thread. */
299 volatile sig_atomic_t cancel_signal_received;
300#endif /* __ANDROID_API__ >= 21 */
301
302 /* Whether this thread must exit. */
303 int canceled;
304};
305
306#if __ANDROID_API__ >= 21
307#define SELECT_SIGNAL SIGUSR1
308#endif /* __ANDROID_API__ >= 21 */
309
310struct android_event_queue
311{
312 /* Mutex protecting the event queue. */
313 pthread_mutex_t mutex;
314
280 /* Condition variables for the reading side. */ 315 /* Condition variables for the reading side. */
281 pthread_cond_t read_var; 316 pthread_cond_t read_var;
282 317
283 /* The number of events in the queue. If this is greater than 1024,
284 writing will block. */
285 int num_events;
286
287 /* Circular queue of events. */ 318 /* Circular queue of events. */
288 struct android_event_container events; 319 struct android_event_container events;
289};
290 320
291/* Arguments to pselect used by the select thread. */ 321#ifndef THREADS_ENABLED
292static int android_pselect_nfds; 322 /* If threads are disabled, the thread-specific component of the main
293static fd_set *android_pselect_readfds; 323 and only thread. */
294static fd_set *android_pselect_writefds; 324 struct android_thread_event_queue thread;
295static fd_set *android_pselect_exceptfds; 325#endif /* !THREADS_ENABLED */
296static struct timespec *android_pselect_timeout;
297 326
298/* Value of pselect. */ 327 /* The number of events in the queue. */
299static int android_pselect_rc; 328 int num_events;
329};
300 330
301/* The global event queue. */ 331/* The global event queue. */
302static struct android_event_queue event_queue; 332static struct android_event_queue event_queue;
303 333
304/* Semaphores used to signal select completion and start. */ 334/* Main select loop of select threads. */
305static sem_t android_pselect_sem, android_pselect_start_sem; 335static void *android_run_select_thread (void *);
306 336
307#if __ANDROID_API__ < 16 337/* Initialize a thread-local component of the Android event queue
338 THREAD. Create and initialize a thread whose purpose is to execute
339 `select' in an interruptible manner, and initialize variables or file
340 descriptors with which to communicate with it. */
308 341
309/* Select self-pipe. */ 342static void
310static int select_pipe[2]; 343android_init_thread_events (struct android_thread_event_queue *thread)
344{
345 thread->canceled = false;
346 thread->select_readfds = NULL;
347 thread->select_writefds = NULL;
348 thread->select_exceptfds = NULL;
349 thread->select_timeout = NULL;
350 thread->select_nfds = 0;
311 351
312#else 352 if (pthread_mutex_init (&thread->select_mutex, NULL))
353 {
354 __android_log_print (ANDROID_LOG_FATAL, __func__,
355 "pthread_mutex_init: %s",
356 strerror (errno));
357 emacs_abort ();
358 }
313 359
314/* Whether or not pselect has been interrupted. */ 360 sem_init (&thread->select_sem, 0, 0);
315static volatile sig_atomic_t android_pselect_interrupted; 361 sem_init (&thread->start_sem, 0, 0);
316 362
317#endif 363#if __ANDROID_API__ < 21
364 /* Set up the file descriptor used to wake up pselect. */
365 if (pipe2 (thread->select_pipe, O_CLOEXEC) < 0)
366 {
367 __android_log_print (ANDROID_LOG_FATAL, __func__,
368 "pipe2: %s", strerror (errno));
369 emacs_abort ();
370 }
371
372 /* Make sure the read end will fit in fd_set. */
373 if (thread->select_pipe[0] >= FD_SETSIZE)
374 {
375 __android_log_print (ANDROID_LOG_FATAL, __func__,
376 "read end of select pipe"
377 " exceeds FD_SETSIZE!");
378 emacs_abort ();
379 }
380#endif /* __ANDROID_API__ < 21 */
381
382 /* Start the select thread. */
383 if (pthread_create (&thread->select_thread, NULL,
384 android_run_select_thread, thread))
385 {
386 __android_log_print (ANDROID_LOG_FATAL, __func__,
387 "pthread_create: %s",
388 strerror (errno));
389 emacs_abort ();
390 }
391}
392
393#ifdef THREADS_ENABLED
394
395/* Destroy a thread-local component of the Android event queue provided
396 as DATA, and release DATA's storage itself. Must be invoked at a
397 time when the select thread is idle, i.e., awaiting
398 DATA->start_sem. */
399
400static void
401android_finalize_thread_events (void *data)
402{
403 int rc;
404 struct android_thread_event_queue *thread;
405
406 /* Cancel the thread and pause till it exits. */
407 thread = data;
408 thread->canceled = 1;
409 sem_post (&thread->start_sem);
410 rc = pthread_join (thread->select_thread, NULL);
411 if (rc)
412 emacs_abort ();
413
414 /* Release the select thread, semaphores, etc. */
415 pthread_mutex_destroy (&thread->select_mutex);
416 sem_close (&thread->select_sem);
417 sem_close (&thread->start_sem);
418#if __ANDROID_API__ < 21
419 close (thread->select_pipe[0]);
420 close (thread->select_pipe[1]);
421#endif /* __ANDROID_API__ < 21 */
422 xfree (thread);
423}
424
425/* TLS keys associating polling threads with Emacs threads. */
426static pthread_key_t poll_thread, poll_thread_internal;
427
428#endif /* THREADS_ENABLED */
429
430/* Return the thread-specific component of the event queue appertaining
431 to this thread, or create it as well as a polling thread if
432 absent. */
318 433
319/* Set the task name of the current task to NAME, a string at most 16 434static struct android_thread_event_queue *
435android_get_poll_thread (void)
436{
437#ifndef THREADS_ENABLED
438 return &event_queue.thread;
439#else /* THREADS_ENABLED */
440 struct android_thread_event_queue *queue;
441
442 queue = pthread_getspecific (poll_thread);
443 if (!queue)
444 {
445 queue = xmalloc (sizeof *queue);
446 android_init_thread_events (queue);
447 pthread_setspecific (poll_thread, queue);
448 }
449 return queue;
450#endif /* !THREADS_ENABLED */
451}
452
453/* Set the task name of the current task to NAME, a string at most 21
320 characters in length. 454 characters in length.
321 455
322 This name is displayed as that of the task (LWP)'s pthread in 456 This name is displayed as that of the task (LWP)'s pthread in
@@ -357,67 +491,73 @@ android_set_task_name (const char *name)
357} 491}
358 492
359static void * 493static void *
360android_run_select_thread (void *data) 494android_run_select_thread (void *thread_data)
361{ 495{
362 /* Apparently this is required too. */ 496 /* Apparently this is required too. */
363 JNI_STACK_ALIGNMENT_PROLOGUE; 497 JNI_STACK_ALIGNMENT_PROLOGUE;
364 498
365 int rc; 499 int rc;
366#if __ANDROID_API__ < 16 500 struct android_thread_event_queue *data;
501#if __ANDROID_API__ < 21
367 int nfds; 502 int nfds;
368 fd_set readfds; 503 fd_set readfds;
369 char byte; 504 char byte;
370#else 505#else /* __ANDROID_API__ >= 21 */
371 sigset_t signals, waitset; 506 sigset_t signals, waitset;
372 int sig; 507 int sig;
373#endif 508#endif /* __ANDROID_API__ >= 21 */
374 509
375 /* Set the name of this thread's LWP for debugging purposes. */ 510 /* Set the name of this thread's LWP for debugging purposes. */
376 android_set_task_name ("`android_select'"); 511 android_set_task_name ("Emacs polling thread");
512 data = thread_data;
377 513
378#if __ANDROID_API__ < 16 514#if __ANDROID_API__ < 21
379 /* A completely different implementation is used when building for 515 /* A completely different implementation is used when building for
380 Android versions earlier than 16, because pselect with a signal 516 Android versions earlier than 21, because pselect with a signal
381 mask does not work there. Instead of blocking SIGUSR1 and 517 mask does not work properly: the signal mask is truncated on APIs
382 unblocking it inside pselect, a file descriptor is used instead. 518 <= 16, and elsewhere, the signal mask is applied in userspace
383 Something is written to the file descriptor every time select is 519 before issuing a select system call, between which SELECT_SIGNAL
384 supposed to return. */ 520 may arrive. Instead of blocking SELECT_SIGNAL and unblocking it
521 inside pselect, a file descriptor is selected. Data is written to
522 the file descriptor whenever select is supposed to return. */
385 523
386 while (true) 524 while (true)
387 { 525 {
388 /* Wait for the thread to be released. */ 526 /* Wait for the thread to be released. */
389 while (sem_wait (&android_pselect_start_sem) < 0) 527 while (sem_wait (&data->start_sem) < 0)
390 ;; 528 ;;
529 if (data->canceled)
530 return NULL;
391 531
392 /* Get the select lock and call pselect. API 8 does not have 532 /* Get the select lock and call pselect. API 8 does not have
393 working pselect in any sense. Instead, pselect wakes up on 533 working pselect in any sense. Instead, pselect wakes up on
394 select_pipe[0]. */ 534 select_pipe[0]. */
395 535
396 pthread_mutex_lock (&event_queue.select_mutex); 536 pthread_mutex_lock (&data->select_mutex);
397 nfds = android_pselect_nfds; 537 nfds = data->select_nfds;
398 538
399 if (android_pselect_readfds) 539 if (data->select_readfds)
400 readfds = *android_pselect_readfds; 540 readfds = *data->select_readfds;
401 else 541 else
402 FD_ZERO (&readfds); 542 FD_ZERO (&readfds);
403 543
404 if (nfds < select_pipe[0] + 1) 544 if (nfds < data->select_pipe[0] + 1)
405 nfds = select_pipe[0] + 1; 545 nfds = data->select_pipe[0] + 1;
406 FD_SET (select_pipe[0], &readfds); 546 FD_SET (data->select_pipe[0], &readfds);
407 547
408 rc = pselect (nfds, &readfds, 548 rc = pselect (nfds, &readfds,
409 android_pselect_writefds, 549 data->select_writefds,
410 android_pselect_exceptfds, 550 data->select_exceptfds,
411 android_pselect_timeout, 551 data->select_timeout,
412 NULL); 552 NULL);
413 553
414 /* Subtract 1 from rc if readfds contains the select pipe, and 554 /* Subtract 1 from rc if readfds contains the select pipe, and
415 also remove it from that set. */ 555 also remove it from that set. */
416 556
417 if (rc != -1 && FD_ISSET (select_pipe[0], &readfds)) 557 if (rc != -1 && FD_ISSET (data->select_pipe[0], &readfds))
418 { 558 {
419 rc -= 1; 559 rc -= 1;
420 FD_CLR (select_pipe[0], &readfds); 560 FD_CLR (data->select_pipe[0], &readfds);
421 561
422 /* If no file descriptors aside from the select pipe are 562 /* If no file descriptors aside from the select pipe are
423 ready, then pretend that an error has occurred. */ 563 ready, then pretend that an error has occurred. */
@@ -427,11 +567,11 @@ android_run_select_thread (void *data)
427 567
428 /* Save the read file descriptor set back again. */ 568 /* Save the read file descriptor set back again. */
429 569
430 if (android_pselect_readfds) 570 if (data->select_readfds)
431 *android_pselect_readfds = readfds; 571 *data->select_readfds = readfds;
432 572
433 android_pselect_rc = rc; 573 data->select_rc = rc;
434 pthread_mutex_unlock (&event_queue.select_mutex); 574 pthread_mutex_unlock (&data->select_mutex);
435 575
436 /* Signal the main thread that there is now data to read. Hold 576 /* Signal the main thread that there is now data to read. Hold
437 the event queue lock during this process to make sure this 577 the event queue lock during this process to make sure this
@@ -443,44 +583,46 @@ android_run_select_thread (void *data)
443 pthread_mutex_unlock (&event_queue.mutex); 583 pthread_mutex_unlock (&event_queue.mutex);
444 584
445 /* Read a single byte from the select pipe. */ 585 /* Read a single byte from the select pipe. */
446 read (select_pipe[0], &byte, 1); 586 read (data->select_pipe[0], &byte, 1);
447 587
448 /* Signal the Emacs thread that pselect is done. If read_var 588 /* Signal the Emacs thread that pselect is done. If read_var
449 was signaled by android_write_event, event_queue.mutex could 589 was signaled by android_write_event, event_queue.mutex could
450 still be locked, so this must come before. */ 590 still be locked, so this must come before. */
451 sem_post (&android_pselect_sem); 591 sem_post (&data->select_sem);
452 } 592 }
453#else 593#else /* __ANDROID_API__ >= 21 */
594 sigfillset (&signals);
454 if (pthread_sigmask (SIG_BLOCK, &signals, NULL)) 595 if (pthread_sigmask (SIG_BLOCK, &signals, NULL))
455 __android_log_print (ANDROID_LOG_FATAL, __func__, 596 __android_log_print (ANDROID_LOG_FATAL, __func__,
456 "pthread_sigmask: %s", 597 "pthread_sigmask: %s",
457 strerror (errno)); 598 strerror (errno));
458 599
459 sigfillset (&signals); 600 sigdelset (&signals, SELECT_SIGNAL);
460 sigdelset (&signals, SIGUSR1);
461 sigemptyset (&waitset); 601 sigemptyset (&waitset);
462 sigaddset (&waitset, SIGUSR1); 602 sigaddset (&waitset, SELECT_SIGNAL);
603#ifdef THREADS_ENABLED
604 pthread_setspecific (poll_thread_internal, thread_data);
605#endif /* THREADS_ENABLED */
463 606
464 while (true) 607 while (true)
465 { 608 {
466 /* Wait for the thread to be released. */ 609 /* Wait for the thread to be released. */
467 while (sem_wait (&android_pselect_start_sem) < 0) 610 while (sem_wait (&data->start_sem) < 0)
468 ;; 611 ;;
469 612 if (data->canceled)
470 /* Clear the ``pselect interrupted'' flag. This is safe because 613 return NULL;
471 right now, SIGUSR1 is blocked. */
472 android_pselect_interrupted = 0;
473 614
474 /* Get the select lock and call pselect. */ 615 /* Get the select lock and call pselect. */
475 pthread_mutex_lock (&event_queue.select_mutex); 616 data->cancel_signal_received = 0;
476 rc = pselect (android_pselect_nfds, 617 pthread_mutex_lock (&data->select_mutex);
477 android_pselect_readfds, 618 rc = pselect (data->select_nfds,
478 android_pselect_writefds, 619 data->select_readfds,
479 android_pselect_exceptfds, 620 data->select_writefds,
480 android_pselect_timeout, 621 data->select_exceptfds,
622 data->select_timeout,
481 &signals); 623 &signals);
482 android_pselect_rc = rc; 624 data->select_rc = rc;
483 pthread_mutex_unlock (&event_queue.select_mutex); 625 pthread_mutex_unlock (&data->select_mutex);
484 626
485 /* Signal the main thread that there is now data to read. Hold 627 /* Signal the main thread that there is now data to read. Hold
486 the event queue lock during this process to make sure this 628 the event queue lock during this process to make sure this
@@ -491,39 +633,51 @@ android_run_select_thread (void *data)
491 pthread_cond_broadcast (&event_queue.read_var); 633 pthread_cond_broadcast (&event_queue.read_var);
492 pthread_mutex_unlock (&event_queue.mutex); 634 pthread_mutex_unlock (&event_queue.mutex);
493 635
494 /* Check `android_pselect_interrupted' instead of rc and errno. 636 /* Test a separate flag `data->cancel_signal_received' rather than
637 rc and errno.
495 638
496 This is because `pselect' does not return an rc of -1 upon 639 This is because `pselect' does not return an rc of -1 upon
497 being interrupted in some versions of Android, but does set 640 being interrupted in some versions of Android, but does set
498 signal masks correctly. */ 641 signal masks correctly. */
499 642 if (!data->cancel_signal_received)
500 if (!android_pselect_interrupted) 643 /* Now, wait for SELECT_SIGNAL, unless pselect was interrupted
501 /* Now, wait for SIGUSR1, unless pselect was interrupted and 644 and the signal has already been delivered. The Emacs thread
502 the signal was already delivered. The Emacs thread will 645 will always send this signal after read_var is triggered or
503 always send this signal after read_var is triggered or the 646 the UI thread has sent an event. */
504 UI thread has sent an event. */
505 sigwait (&waitset, &sig); 647 sigwait (&waitset, &sig);
506 648
507 /* Signal the Emacs thread that pselect is done. If read_var 649 /* Signal the Emacs thread that pselect is done. If read_var
508 was signaled by android_write_event, event_queue.mutex could 650 was signaled by android_write_event, event_queue.mutex could
509 still be locked, so this must come before. */ 651 still be locked, so this must come before. */
510 sem_post (&android_pselect_sem); 652 sem_post (&data->select_sem);
511 } 653 }
512#endif 654#endif /* __ANDROID_API__ >= 21 */
513 655
514 return NULL; 656 return NULL;
515} 657}
516 658
517#if __ANDROID_API__ >= 16 659#if __ANDROID_API__ >= 21
518 660
519static void 661static void
520android_handle_sigusr1 (int sig, siginfo_t *siginfo, void *arg) 662android_handle_poll_signal (int sig, siginfo_t *siginfo, void *arg)
521{ 663{
522 /* Notice that pselect has been interrupted. */ 664 struct android_thread_event_queue *queue;
523 android_pselect_interrupted = 1; 665
666 /* Although pthread_getspecific is not AS-safe, its implementation has
667 been verified to be safe to invoke from a single handler called
668 within pselect in a controlled manner, and this is the only means
669 of retrieving thread-specific data from a signal handler, as the
670 POSIX real-time signal system calls are unavailable to Android
671 applications. */
672#ifdef THREADS_ENABLED
673 queue = pthread_getspecific (poll_thread_internal);
674#else /* !THREADS_ENABLED */
675 queue = &event_queue.thread;
676#endif /* !THREADS_ENABLED */
677 queue->cancel_signal_received = 1;
524} 678}
525 679
526#endif 680#endif /* __ANDROID_API__ >= 21 */
527 681
528/* Semaphore used to indicate completion of a query. 682/* Semaphore used to indicate completion of a query.
529 This should ideally be defined further down. */ 683 This should ideally be defined further down. */
@@ -543,66 +697,57 @@ static pthread_t main_thread_id;
543static void 697static void
544android_init_events (void) 698android_init_events (void)
545{ 699{
700#if __ANDROID_API__ >= 21
546 struct sigaction sa; 701 struct sigaction sa;
702#endif /* __ANDROID_API__ >= 21 */
547 703
548 if (pthread_mutex_init (&event_queue.mutex, NULL)) 704 if (pthread_mutex_init (&event_queue.mutex, NULL))
549 __android_log_print (ANDROID_LOG_FATAL, __func__, 705 {
550 "pthread_mutex_init: %s", 706 __android_log_print (ANDROID_LOG_FATAL, __func__,
551 strerror (errno)); 707 "pthread_mutex_init: %s",
552 708 strerror (errno));
553 if (pthread_mutex_init (&event_queue.select_mutex, NULL)) 709 emacs_abort ();
554 __android_log_print (ANDROID_LOG_FATAL, __func__, 710 }
555 "pthread_mutex_init: %s",
556 strerror (errno));
557 711
558 if (pthread_cond_init (&event_queue.read_var, NULL)) 712 if (pthread_cond_init (&event_queue.read_var, NULL))
559 __android_log_print (ANDROID_LOG_FATAL, __func__, 713 {
560 "pthread_cond_init: %s", 714 __android_log_print (ANDROID_LOG_FATAL, __func__,
561 strerror (errno)); 715 "pthread_cond_init: %s",
562 716 strerror (errno));
563 sem_init (&android_pselect_sem, 0, 0); 717 emacs_abort ();
564 sem_init (&android_pselect_start_sem, 0, 0); 718 }
565 sem_init (&android_query_sem, 0, 0);
566 719
567 event_queue.events.next = &event_queue.events; 720 event_queue.events.next = &event_queue.events;
568 event_queue.events.last = &event_queue.events; 721 event_queue.events.last = &event_queue.events;
569 722
570 main_thread_id = pthread_self (); 723 main_thread_id = pthread_self ();
571 724
572#if __ANDROID_API__ >= 16 725#if __ANDROID_API__ >= 21
573 726 /* Before any event threads are initialized, guarantee that the
574 /* Before starting the select thread, make sure the disposition for 727 disposition of SELECT_SIGNAL is correct. */
575 SIGUSR1 is correct. */
576 sigfillset (&sa.sa_mask); 728 sigfillset (&sa.sa_mask);
577 sa.sa_sigaction = android_handle_sigusr1; 729 sa.sa_sigaction = android_handle_poll_signal;
578 sa.sa_flags = SA_SIGINFO; 730 sa.sa_flags = SA_SIGINFO;
579 731 if (sigaction (SELECT_SIGNAL, &sa, NULL))
580#else 732 {
581 733 __android_log_print (ANDROID_LOG_FATAL, __func__,
582 /* Set up the file descriptor used to wake up pselect. */ 734 "sigaction: %s",
583 if (pipe2 (select_pipe, O_CLOEXEC) < 0) 735 strerror (errno));
584 __android_log_print (ANDROID_LOG_FATAL, __func__, 736 emacs_abort ();
585 "pipe2: %s", strerror (errno)); 737 }
586 738#endif /* __ANDROID_API__ >= 21 */
587 /* Make sure the read end will fit in fd_set. */ 739#ifndef THREADS_ENABLED
588 if (select_pipe[0] >= FD_SETSIZE) 740 android_init_thread_events (&event_queue.thread);
589 __android_log_print (ANDROID_LOG_FATAL, __func__, 741#else /* THREADS_ENABLED */
590 "read end of select pipe" 742 if (pthread_key_create (&poll_thread, android_finalize_thread_events)
591 " lies outside FD_SETSIZE!"); 743 || pthread_key_create (&poll_thread_internal, NULL))
592 744 {
593#endif 745 __android_log_print (ANDROID_LOG_FATAL, __func__,
594 746 "pthread_key_create: %s",
595 if (sigaction (SIGUSR1, &sa, NULL)) 747 strerror (errno));
596 __android_log_print (ANDROID_LOG_FATAL, __func__, 748 emacs_abort ();
597 "sigaction: %s", 749 }
598 strerror (errno)); 750#endif /* THREADS_ENABLED */
599
600 /* Start the select thread. */
601 if (pthread_create (&event_queue.select_thread, NULL,
602 android_run_select_thread, NULL))
603 __android_log_print (ANDROID_LOG_FATAL, __func__,
604 "pthread_create: %s",
605 strerror (errno));
606} 751}
607 752
608int 753int
@@ -761,25 +906,17 @@ int
761android_select (int nfds, fd_set *readfds, fd_set *writefds, 906android_select (int nfds, fd_set *readfds, fd_set *writefds,
762 fd_set *exceptfds, struct timespec *timeout) 907 fd_set *exceptfds, struct timespec *timeout)
763{ 908{
764 int nfds_return; 909 int nfds_return, nevents;
765#if __ANDROID_API__ < 16 910#if __ANDROID_API__ < 21
766 static char byte; 911 static char byte;
767#endif 912#endif
913 struct android_thread_event_queue *data;
768 914
769#ifdef THREADS_ENABLED 915 /* When threads are enabled, the following is executed before the
770 if (!pthread_equal (pthread_self (), main_thread_id)) 916 global lock is released. */
771 return pselect (nfds, readfds, writefds, exceptfds, timeout, 917#ifndef THREADS_ENABLED
772 NULL); 918 android_before_select ();
773#endif /* THREADS_ENABLED */ 919#endif /* !THREADS_ENABLED */
774
775 /* Since Emacs is reading keyboard input again, signify that queries
776 from input methods are no longer ``urgent''. */
777
778 __atomic_clear (&android_urgent_query, __ATOMIC_RELEASE);
779
780 /* Check for and run anything the UI thread wants to run on the main
781 thread. */
782 android_check_query ();
783 920
784 pthread_mutex_lock (&event_queue.mutex); 921 pthread_mutex_lock (&event_queue.mutex);
785 922
@@ -804,60 +941,60 @@ android_select (int nfds, fd_set *readfds, fd_set *writefds,
804 941
805 nfds_return = 0; 942 nfds_return = 0;
806 943
807 pthread_mutex_lock (&event_queue.select_mutex); 944 data = android_get_poll_thread ();
808 android_pselect_nfds = nfds; 945
809 android_pselect_readfds = readfds; 946 pthread_mutex_lock (&data->select_mutex);
810 android_pselect_writefds = writefds; 947 data->select_nfds = nfds;
811 android_pselect_exceptfds = exceptfds; 948 data->select_readfds = readfds;
812 android_pselect_timeout = timeout; 949 data->select_writefds = writefds;
813 pthread_mutex_unlock (&event_queue.select_mutex); 950 data->select_exceptfds = exceptfds;
951 data->select_timeout = timeout;
952 pthread_mutex_unlock (&data->select_mutex);
814 953
815 /* Release the select thread. */ 954 /* Release the select thread. */
816 sem_post (&android_pselect_start_sem); 955 sem_post (&data->start_sem);
817 956
818 /* Start waiting for the event queue condition to be set. */ 957 /* Start waiting for the event queue condition to be set. */
819 pthread_cond_wait (&event_queue.read_var, &event_queue.mutex); 958 pthread_cond_wait (&event_queue.read_var, &event_queue.mutex);
820 959
821#if __ANDROID_API__ >= 16 960#if __ANDROID_API__ >= 21
822 /* Interrupt the select thread now, in case it's still in 961 /* Interrupt the select thread now, in case it's still in
823 pselect. */ 962 pselect. */
824 pthread_kill (event_queue.select_thread, SIGUSR1); 963 pthread_kill (data->select_thread, SELECT_SIGNAL);
825#else 964#else /* __ANDROID_API__ < 21 */
826 /* Interrupt the select thread by writing to the select pipe. */ 965 /* Interrupt the select thread by writing to the select pipe. */
827 if (write (select_pipe[1], &byte, 1) != 1) 966 if (write (data->select_pipe[1], &byte, 1) != 1)
828 __android_log_print (ANDROID_LOG_FATAL, __func__, 967 __android_log_print (ANDROID_LOG_FATAL, __func__,
829 "write: %s", strerror (errno)); 968 "write: %s", strerror (errno));
830#endif 969#endif /* __ANDROID_API__ < 21 */
831 970
832 /* Unlock the event queue mutex. */ 971 /* Are there any events in the event queue? */
972 nevents = event_queue.num_events;
833 pthread_mutex_unlock (&event_queue.mutex); 973 pthread_mutex_unlock (&event_queue.mutex);
834 974
835 /* Wait for pselect to return in any case. This must be done with 975 /* Wait for pselect to return in any case. This must be done with the
836 the event queue mutex unlocked. Otherwise, the pselect thread 976 event queue mutex unlocked. Otherwise, the pselect thread can hang
837 can hang if it tries to lock the event queue mutex to signal 977 if it tries to lock the event queue mutex to signal read_var after
838 read_var after the UI thread has already done so. */ 978 the UI thread has already done so. */
839 while (sem_wait (&android_pselect_sem) < 0) 979 while (sem_wait (&data->select_sem) < 0)
840 ;; 980 ;;
841 981
842 /* If there are now events in the queue, return 1. */ 982 /* If there are now events in the queue, return 1. */
843 983 if (nevents)
844 pthread_mutex_lock (&event_queue.mutex);
845 if (event_queue.num_events)
846 nfds_return = 1; 984 nfds_return = 1;
847 pthread_mutex_unlock (&event_queue.mutex);
848 985
849 /* Add the return value of pselect if it has also found ready file 986 /* Add the return value of pselect if it has also discovered ready
850 descriptors. */ 987 file descriptors. */
851 988
852 if (android_pselect_rc >= 0) 989 if (data->select_rc >= 0)
853 nfds_return += android_pselect_rc; 990 nfds_return += data->select_rc;
854 else if (!nfds_return) 991 else if (!nfds_return)
855 /* If pselect was interrupted and nfds_return is 0 (meaning that 992 /* If pselect was interrupted and nfds_return is 0 (meaning that no
856 no events have been read), indicate that an error has taken 993 events have been read), indicate that an error has taken
857 place. */ 994 place. */
858 nfds_return = android_pselect_rc; 995 nfds_return = data->select_rc;
859 996
860 if ((android_pselect_rc < 0) && nfds_return >= 0) 997 if ((data->select_rc < 0) && nfds_return >= 0)
861 { 998 {
862 /* Clear the file descriptor sets if events will be delivered 999 /* Clear the file descriptor sets if events will be delivered
863 but no file descriptors have become ready to prevent the 1000 but no file descriptors have become ready to prevent the
@@ -6721,6 +6858,23 @@ static void *android_query_context;
6721 itself; however, the input signal handler executes a memory fence 6858 itself; however, the input signal handler executes a memory fence
6722 to ensure that all query related writes become visible. */ 6859 to ensure that all query related writes become visible. */
6723 6860
6861/* Clear the ``urgent query'' flag and run any function that the UI
6862 thread has asked to run. Must be invoked before `android_select'
6863 from the thread holding the global lock. */
6864
6865void
6866android_before_select (void)
6867{
6868 /* Since Emacs is reading keyboard input again, signify that queries
6869 from input methods are no longer ``urgent''. */
6870
6871 __atomic_clear (&android_urgent_query, __ATOMIC_RELEASE);
6872
6873 /* Check for and run anything the UI thread wants to run on the main
6874 thread. */
6875 android_check_query ();
6876}
6877
6724/* Run any function that the UI thread has asked to run, and then 6878/* Run any function that the UI thread has asked to run, and then
6725 signal its completion. */ 6879 signal its completion. */
6726 6880
@@ -6781,7 +6935,7 @@ android_check_query_urgent (void)
6781 if (!proc) 6935 if (!proc)
6782 return; 6936 return;
6783 6937
6784 proc (closure); 6938 (*proc) (closure);
6785 6939
6786 /* Finish the query. Don't clear `android_urgent_query'; instead, 6940 /* Finish the query. Don't clear `android_urgent_query'; instead,
6787 do that the next time Emacs enters the keyboard loop. */ 6941 do that the next time Emacs enters the keyboard loop. */
@@ -6931,8 +7085,8 @@ android_run_in_emacs_thread (void (*proc) (void *), void *closure)
6931 /* Send a dummy event. `android_check_query' will be called inside 7085 /* Send a dummy event. `android_check_query' will be called inside
6932 wait_reading_process_output after the event arrives. 7086 wait_reading_process_output after the event arrives.
6933 7087
6934 Otherwise, android_select will call android_check_thread the next 7088 Otherwise, android_select will call `android_check_query' when next
6935 time it is entered. */ 7089 it is entered. */
6936 android_write_event (&event); 7090 android_write_event (&event);
6937 7091
6938 /* Start waiting for the function to be executed. First, wait two 7092 /* Start waiting for the function to be executed. First, wait two
diff --git a/src/android.h b/src/android.h
index 31436301df8..1a12c95c9a5 100644
--- a/src/android.h
+++ b/src/android.h
@@ -244,6 +244,7 @@ extern void android_display_toast (const char *);
244 244
245/* Event loop functions. */ 245/* Event loop functions. */
246 246
247extern void android_before_select (void);
247extern void android_check_query (void); 248extern void android_check_query (void);
248extern void android_check_query_urgent (void); 249extern void android_check_query_urgent (void);
249extern int android_run_in_emacs_thread (void (*) (void *), void *); 250extern int android_run_in_emacs_thread (void (*) (void *), void *);
diff --git a/src/thread.c b/src/thread.c
index 5610f8be0dd..8fd713d0c81 100644
--- a/src/thread.c
+++ b/src/thread.c
@@ -653,6 +653,9 @@ thread_select (select_func *func, int max_fds, fd_set *rfds,
653 sa.efds = efds; 653 sa.efds = efds;
654 sa.timeout = timeout; 654 sa.timeout = timeout;
655 sa.sigmask = sigmask; 655 sa.sigmask = sigmask;
656#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY
657 android_before_select ();
658#endif /* HAVE_ANDROID && !defined ANDROID_STUBIFY */
656 flush_stack_call_func (really_call_select, &sa); 659 flush_stack_call_func (really_call_select, &sa);
657 return sa.result; 660 return sa.result;
658} 661}