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:
parent
7f073df533
commit
c321eea5af
3 changed files with 53 additions and 0 deletions
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue