aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPo Lu2023-06-12 14:19:01 +0800
committerPo Lu2023-06-12 14:19:01 +0800
commit3b08bb1318cd0bf6bc1811b520f9c6934b1aa3bd (patch)
treeb7effb4669608cb3329923a7c7a8a1387dbea412
parente3196835ed08a1d1a675b933a53d1a397defd561 (diff)
downloademacs-3b08bb1318cd0bf6bc1811b520f9c6934b1aa3bd.tar.gz
emacs-3b08bb1318cd0bf6bc1811b520f9c6934b1aa3bd.zip
Fix deadlocks
* java/org/gnu/emacs/EmacsView.java (EmacsView) (showOnScreenKeyboard, hideOnScreenKeyboard): Don't synchronize. * java/org/gnu/emacs/EmacsWindow.java (EmacsWindow) (toggleOnScreenKeyboard): Revert to calling IMM functions from the main thread. * src/android.c (struct android_event_container) (android_pselect_nfds, android_pselect_readfds) (android_pselect_writefds, android_pselect_exceptfds) (android_pselect_timeout): Don't make volatile. (android_wait_event): Run queries if necessary.
-rw-r--r--java/org/gnu/emacs/EmacsView.java5
-rw-r--r--java/org/gnu/emacs/EmacsWindow.java25
-rw-r--r--src/android.c30
3 files changed, 39 insertions, 21 deletions
diff --git a/java/org/gnu/emacs/EmacsView.java b/java/org/gnu/emacs/EmacsView.java
index 7fd672233f2..278c6025902 100644
--- a/java/org/gnu/emacs/EmacsView.java
+++ b/java/org/gnu/emacs/EmacsView.java
@@ -590,16 +590,17 @@ public final class EmacsView extends ViewGroup
590 super.onAttachedToWindow (); 590 super.onAttachedToWindow ();
591 } 591 }
592 592
593 public synchronized void 593 public void
594 showOnScreenKeyboard () 594 showOnScreenKeyboard ()
595 { 595 {
596 /* Specifying no flags at all tells the system the user asked for 596 /* Specifying no flags at all tells the system the user asked for
597 the input method to be displayed. */ 597 the input method to be displayed. */
598
598 imManager.showSoftInput (this, 0); 599 imManager.showSoftInput (this, 0);
599 isCurrentlyTextEditor = true; 600 isCurrentlyTextEditor = true;
600 } 601 }
601 602
602 public synchronized void 603 public void
603 hideOnScreenKeyboard () 604 hideOnScreenKeyboard ()
604 { 605 {
605 imManager.hideSoftInputFromWindow (this.getWindowToken (), 606 imManager.hideSoftInputFromWindow (this.getWindowToken (),
diff --git a/java/org/gnu/emacs/EmacsWindow.java b/java/org/gnu/emacs/EmacsWindow.java
index f5e40e9a2d9..68a18ec2aa7 100644
--- a/java/org/gnu/emacs/EmacsWindow.java
+++ b/java/org/gnu/emacs/EmacsWindow.java
@@ -1201,16 +1201,25 @@ public final class EmacsWindow extends EmacsHandleObject
1201 } 1201 }
1202 1202
1203 public void 1203 public void
1204 toggleOnScreenKeyboard (boolean on) 1204 toggleOnScreenKeyboard (final boolean on)
1205 { 1205 {
1206 /* InputMethodManager functions are thread safe. Call 1206 /* Even though InputMethodManager functions are thread safe,
1207 `showOnScreenKeyboard' etc from the Emacs thread in order to 1207 `showOnScreenKeyboard' etc must be called from the UI thread in
1208 keep the calls in sync with updates to the input context. */ 1208 order to avoid deadlocks if the calls happen in tandem with a
1209 call to a synchronizing function within
1210 `onCreateInputConnection'. */
1209 1211
1210 if (on) 1212 EmacsService.SERVICE.runOnUiThread (new Runnable () {
1211 view.showOnScreenKeyboard (); 1213 @Override
1212 else 1214 public void
1213 view.hideOnScreenKeyboard (); 1215 run ()
1216 {
1217 if (on)
1218 view.showOnScreenKeyboard ();
1219 else
1220 view.hideOnScreenKeyboard ();
1221 }
1222 });
1214 } 1223 }
1215 1224
1216 public String 1225 public String
diff --git a/src/android.c b/src/android.c
index 4414d465107..873d821361c 100644
--- a/src/android.c
+++ b/src/android.c
@@ -272,7 +272,7 @@ void *unused_pointer;
272struct android_event_container 272struct android_event_container
273{ 273{
274 /* The next and last events in this queue. */ 274 /* The next and last events in this queue. */
275 struct android_event_container *volatile next, *last; 275 struct android_event_container *next, *last;
276 276
277 /* The event itself. */ 277 /* The event itself. */
278 union android_event event; 278 union android_event event;
@@ -301,11 +301,11 @@ struct android_event_queue
301}; 301};
302 302
303/* Arguments to pselect used by the select thread. */ 303/* Arguments to pselect used by the select thread. */
304static volatile int android_pselect_nfds; 304static int android_pselect_nfds;
305static fd_set *volatile android_pselect_readfds; 305static fd_set *android_pselect_readfds;
306static fd_set *volatile android_pselect_writefds; 306static fd_set *android_pselect_writefds;
307static fd_set *volatile android_pselect_exceptfds; 307static fd_set *android_pselect_exceptfds;
308static struct timespec *volatile android_pselect_timeout; 308static struct timespec *android_pselect_timeout;
309 309
310/* Value of pselect. */ 310/* Value of pselect. */
311static int android_pselect_rc; 311static int android_pselect_rc;
@@ -569,12 +569,20 @@ android_pending (void)
569 return i; 569 return i;
570} 570}
571 571
572/* Forward declaration. */
573
574static void android_check_query (void);
575
572/* Wait for events to become available synchronously. Return once an 576/* Wait for events to become available synchronously. Return once an
573 event arrives. */ 577 event arrives. Also, reply to the UI thread whenever it requires a
578 response. */
574 579
575void 580void
576android_wait_event (void) 581android_wait_event (void)
577{ 582{
583 /* Run queries from the UI thread to the Emacs thread. */
584 android_check_query ();
585
578 pthread_mutex_lock (&event_queue.mutex); 586 pthread_mutex_lock (&event_queue.mutex);
579 587
580 /* Wait for events to appear if there are none available to 588 /* Wait for events to appear if there are none available to
@@ -584,6 +592,10 @@ android_wait_event (void)
584 &event_queue.mutex); 592 &event_queue.mutex);
585 593
586 pthread_mutex_unlock (&event_queue.mutex); 594 pthread_mutex_unlock (&event_queue.mutex);
595
596 /* Check for queries again. If a query is sent after the call to
597 `android_check_query' above, `read_var' will be signaled. */
598 android_check_query ();
587} 599}
588 600
589void 601void
@@ -701,10 +713,6 @@ android_write_event (union android_event *event)
701 should answer the query ASAP. */ 713 should answer the query ASAP. */
702static bool android_urgent_query; 714static bool android_urgent_query;
703 715
704/* Forward declaration. */
705
706static void android_check_query (void);
707
708int 716int
709android_select (int nfds, fd_set *readfds, fd_set *writefds, 717android_select (int nfds, fd_set *readfds, fd_set *writefds,
710 fd_set *exceptfds, struct timespec *timeout) 718 fd_set *exceptfds, struct timespec *timeout)