Block profiling signals in the Android UI thread

* java/org/gnu/emacs/EmacsNative.java (EmacsNative): New
function `setupSystemThread'.
* java/org/gnu/emacs/EmacsService.java (onCreate): Block all
signals except for SIGBUS and SIGSEGV in the UI thread.
* src/android.c (setupSystemThread): New function.
This commit is contained in:
Po Lu 2023-06-09 14:03:50 +08:00
parent 7f073df533
commit c321eea5af
3 changed files with 53 additions and 0 deletions

View file

@ -188,6 +188,10 @@ public static native long sendExpose (short window, int x, int y,
KEYCODE_VOLUME_MUTE should be forwarded to Emacs. */
public static native boolean shouldForwardMultimediaButtons ();
/* Initialize the current thread, by blocking signals that do not
interest it. */
public static native void setupSystemThread ();
/* Input connection functions. These mostly correspond to their

View file

@ -25,6 +25,7 @@
import java.util.List;
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicInteger;
import android.graphics.Matrix;
@ -211,6 +212,7 @@ public final class EmacsService extends Service
final String filesDir, libDir, cacheDir, classPath;
final double pixelDensityX;
final double pixelDensityY;
final Semaphore signalSemaphore;
SERVICE = this;
handler = new Handler (Looper.getMainLooper ());
@ -220,6 +222,7 @@ public final class EmacsService extends Service
pixelDensityX = metrics.xdpi;
pixelDensityY = metrics.ydpi;
resolver = getContentResolver ();
signalSemaphore = new Semaphore (0);
try
{
@ -248,11 +251,33 @@ invocation of app_process (through android-emacs) can
cacheDir, (float) pixelDensityX,
(float) pixelDensityY,
classPath, EmacsService.this);
/* Wait for the signal mask to be set up in the UI
thread. */
while (true)
{
try
{
signalSemaphore.acquire ();
break;
}
catch (InterruptedException e)
{
;;
}
}
}
}, extraStartupArgument,
/* If any file needs to be opened, open it now. */
EmacsOpenActivity.fileToOpen);
thread.start ();
/* Now that the thread has been started, block signals which
don't interest the current thread. */
EmacsNative.setupSystemThread ();
signalSemaphore.release ();
}
catch (IOException exception)
{

View file

@ -3077,6 +3077,30 @@ NATIVE_NAME (answerQuerySpin) (JNIEnv *env, jobject object)
android_answer_query_spin ();
}
/* System thread setup. Android doesn't always block signals Emacs is
interested in from being received by the UI or render threads,
which can lead to problems when those signals then interrupt one of
those threads. */
JNIEXPORT void JNICALL
NATIVE_NAME (setupSystemThread) (void)
{
sigset_t sigset;
/* Block everything except for SIGSEGV and SIGBUS; those two are
used by the runtime. */
sigfillset (&sigset);
sigaddset (&sigset, SIGSEGV);
sigaddset (&sigset, SIGBUS);
if (pthread_sigmask (SIG_BLOCK, &sigset, NULL))
__android_log_print (ANDROID_LOG_WARN, __func__,
"pthread_sigmask: %s", strerror (errno));
}
#ifdef __clang__
#pragma clang diagnostic pop
#else