emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 16831e290ed: Avert race condition between window attachment and b


From: Po Lu
Subject: master 16831e290ed: Avert race condition between window attachment and buffer swap
Date: Thu, 25 Jan 2024 22:26:11 -0500 (EST)

branch: master
commit 16831e290ed29f5f70dfe144ec63c583527485e8
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    Avert race condition between window attachment and buffer swap
    
    * java/org/gnu/emacs/EmacsView.java (swapBuffers): Synchronize
    such that code cannot execute between the bitmap's being loaded
    and being transferred to surfaceView.
    (onDetachedFromWindow): Recycle bitmap after the surface view is
    reset.
    
    * java/org/gnu/emacs/EmacsWindow.java (recreateActivity):
    
    * src/android.c (android_init_emacs_window)
    (android_recreate_activity):
    
    * src/androidfns.c (Fandroid_recreate_activity)
    (syms_of_androidfns): New functions for debugging window
    attachment.
    
    * src/androidgui.h: Update prototypes.
---
 java/org/gnu/emacs/EmacsView.java   | 27 +++++++++++++++------------
 java/org/gnu/emacs/EmacsWindow.java | 28 ++++++++++++++++++++++++++++
 src/android.c                       | 21 ++++++++++++++++++++-
 src/androidfns.c                    | 19 +++++++++++++++++++
 src/androidgui.h                    |  1 +
 5 files changed, 83 insertions(+), 13 deletions(-)

diff --git a/java/org/gnu/emacs/EmacsView.java 
b/java/org/gnu/emacs/EmacsView.java
index 136d8abc713..8398e4b784c 100644
--- a/java/org/gnu/emacs/EmacsView.java
+++ b/java/org/gnu/emacs/EmacsView.java
@@ -456,7 +456,6 @@ public final class EmacsView extends ViewGroup
   {
     Canvas canvas;
     Rect damageRect;
-    Bitmap bitmap;
 
     /* Make sure this function is called only from the Emacs
        thread.  */
@@ -474,11 +473,12 @@ public final class EmacsView extends ViewGroup
     damageRect = damageRegion.getBounds ();
     damageRegion.setEmpty ();
 
-    bitmap = getBitmap ();
-
-    /* Transfer the bitmap to the surface view, then invalidate
-       it.  */
-    surfaceView.setBitmap (bitmap, damageRect);
+    synchronized (this)
+      {
+       /* Transfer the bitmap to the surface view, then invalidate
+          it.  */
+       surfaceView.setBitmap (bitmap, damageRect);
+      }
   }
 
   @Override
@@ -724,17 +724,20 @@ public final class EmacsView extends ViewGroup
   public synchronized void
   onDetachedFromWindow ()
   {
-    isAttachedToWindow = false;
-
-    /* Recycle the bitmap and call GC.  */
-
-    if (bitmap != null)
-      bitmap.recycle ();
+    Bitmap savedBitmap;
 
+    savedBitmap = bitmap;
+    isAttachedToWindow = false;
     bitmap = null;
     canvas = null;
+
     surfaceView.setBitmap (null, null);
 
+    /* Recycle the bitmap and call GC.  */
+
+    if (savedBitmap != null)
+      savedBitmap.recycle ();
+
     /* Collect the bitmap storage; it could be large.  */
     Runtime.getRuntime ().gc ();
 
diff --git a/java/org/gnu/emacs/EmacsWindow.java 
b/java/org/gnu/emacs/EmacsWindow.java
index 207bd22c538..304304a328b 100644
--- a/java/org/gnu/emacs/EmacsWindow.java
+++ b/java/org/gnu/emacs/EmacsWindow.java
@@ -1784,4 +1784,32 @@ public final class EmacsWindow extends EmacsHandleObject
 
     return true;
   }
+
+
+
+  /* Miscellaneous functions for debugging graphics code.  */
+
+  /* Recreate the activity to which this window is attached, if any.
+     This is nonfunctional on Android 2.3.7 and earlier.  */
+
+  public void
+  recreateActivity ()
+  {
+    final EmacsWindowAttachmentManager.WindowConsumer attached;
+
+    attached = this.attached;
+
+    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB)
+      return;
+
+    view.post (new Runnable () {
+       @Override
+       public void
+       run ()
+       {
+         if (attached instanceof EmacsActivity)
+           ((EmacsActivity) attached).recreate ();
+       }
+      });
+  }
 };
diff --git a/src/android.c b/src/android.c
index 509f30a759b..51eb85a97e8 100644
--- a/src/android.c
+++ b/src/android.c
@@ -111,6 +111,7 @@ struct android_emacs_window
   jmethodID set_dont_focus_on_map;
   jmethodID define_cursor;
   jmethodID damage_rect;
+  jmethodID recreate_activity;
 };
 
 struct android_emacs_cursor
@@ -1802,12 +1803,12 @@ android_init_emacs_window (void)
   FIND_METHOD (set_dont_accept_focus, "setDontAcceptFocus", "(Z)V");
   FIND_METHOD (define_cursor, "defineCursor",
               "(Lorg/gnu/emacs/EmacsCursor;)V");
-
   /* In spite of the declaration of this function being located within
      EmacsDrawable, the ID of the `damage_rect' method is retrieved
      from EmacsWindow, which avoids virtual function dispatch within
      android_damage_window.  */
   FIND_METHOD (damage_rect, "damageRect", "(IIII)V");
+  FIND_METHOD (recreate_activity, "recreateActivity", "()V");
 #undef FIND_METHOD
 }
 
@@ -6638,6 +6639,24 @@ android_request_storage_access (void)
   android_exception_check ();
 }
 
+/* Recreate the activity to which WINDOW is attached to debug graphics
+   code executed in response to window attachment.  */
+
+void
+android_recreate_activity (android_window window)
+{
+  jobject object;
+  jmethodID method;
+
+  object = android_resolve_handle (window, ANDROID_HANDLE_WINDOW);
+  method = window_class.recreate_activity;
+
+  (*android_java_env)->CallNonvirtualVoidMethod (android_java_env, object,
+                                                window_class.class,
+                                                method);
+  android_exception_check ();
+}
+
 
 
 /* The thread from which a query against a thread is currently being
diff --git a/src/androidfns.c b/src/androidfns.c
index 34f1f533684..eaecb78338b 100644
--- a/src/androidfns.c
+++ b/src/androidfns.c
@@ -3164,6 +3164,24 @@ android_set_preeditarea (struct window *w, int x, int y)
                                     y + w->phys_cursor_height);
 }
 
+
+
+/* Debugging.  */
+
+DEFUN ("android-recreate-activity", Fandroid_recreate_activity,
+       Sandroid_recreate_activity, 0, 0, "",
+       doc: /* Recreate the activity attached to the current frame.
+This function exists for debugging purposes and is of no interest to
+users.  */)
+  (void)
+{
+  struct frame *f;
+
+  f = decode_window_system_frame (Qnil);
+  android_recreate_activity (FRAME_ANDROID_WINDOW (f));
+  return Qnil;
+}
+
 #endif /* !ANDROID_STUBIFY */
 
 
@@ -3550,6 +3568,7 @@ language to be US English if LANGUAGE is empty.  */);
   defsubr (&Sandroid_request_directory_access);
   defsubr (&Sandroid_external_storage_available_p);
   defsubr (&Sandroid_request_storage_access);
+  defsubr (&Sandroid_recreate_activity);
 
   tip_timer = Qnil;
   staticpro (&tip_timer);
diff --git a/src/androidgui.h b/src/androidgui.h
index 69efd393d55..89317581191 100644
--- a/src/androidgui.h
+++ b/src/androidgui.h
@@ -708,6 +708,7 @@ extern void android_translate_coordinates (android_window, 
int,
 extern int android_wc_lookup_string (android_key_pressed_event *,
                                     wchar_t *, int, int *,
                                     enum android_lookup_status *);
+extern void android_recreate_activity (android_window);
 extern void android_update_ic (android_window, ptrdiff_t, ptrdiff_t,
                               ptrdiff_t, ptrdiff_t);
 extern void android_reset_ic (android_window, enum android_ic_mode);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]