diff options
-rw-r--r-- | src/signal_catcher.cc | 6 | ||||
-rw-r--r-- | test/ThreadStress/ThreadStress.java | 10 |
2 files changed, 15 insertions, 1 deletions
diff --git a/src/signal_catcher.cc b/src/signal_catcher.cc index 9031c5e..80563e2 100644 --- a/src/signal_catcher.cc +++ b/src/signal_catcher.cc @@ -95,6 +95,12 @@ void SignalCatcher::HandleSigQuit() { Runtime* runtime = Runtime::Current(); ThreadList* thread_list = runtime->GetThreadList(); + // We take the heap lock before suspending all threads so we don't end up in a situation where + // one of the suspended threads suspended via the implicit FullSuspendCheck on the slow path of + // Heap::Lock, which is the only case where a thread can be suspended while holding the heap lock. + // (We need the heap lock when we dump the thread list. We could probably fix this by duplicating + // more state from java.lang.Thread in struct Thread.) + ScopedHeapLock heap_lock; thread_list->SuspendAll(); std::ostringstream os; diff --git a/test/ThreadStress/ThreadStress.java b/test/ThreadStress/ThreadStress.java index c294a38..1f8fb2d 100644 --- a/test/ThreadStress/ThreadStress.java +++ b/test/ThreadStress/ThreadStress.java @@ -20,6 +20,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import libcore.io.*; // Run on host with: // javac ThreadTest.java && java ThreadStress && rm *.class @@ -29,7 +30,8 @@ class ThreadStress implements Runnable { enum Operation { OOM(1), - ALLOC(99), + SIGQUIT(19), + ALLOC(80), EXIT(50), WAIT(50); @@ -194,6 +196,12 @@ class ThreadStress implements Runnable { case EXIT: { return; } + case SIGQUIT: { + try { + Libcore.os.kill(Libcore.os.getpid(), OsConstants.SIGQUIT); + } catch (ErrnoException ex) { + } + } case WAIT: { synchronized (lock) { try { |