A bit further along the track of multiple threads.

This also makes valgrind happy, and tsan mostly happy. (The heap, it turns out,
doesn't have a lock yet.)

The DexVerifier changes are just to make valgrind happy, and the code a little
less unidiomatic.

Change-Id: Ic5d436b4863b9d7088eb0b8fe9d32308919899d8
diff --git a/src/signal_catcher.cc b/src/signal_catcher.cc
index e2e2360..1552180 100644
--- a/src/signal_catcher.cc
+++ b/src/signal_catcher.cc
@@ -29,11 +29,12 @@
 
 namespace art {
 
-bool SignalCatcher::halt_ = false;
-
 SignalCatcher::SignalCatcher() {
+  lock_ = Mutex::Create("SignalCatcher lock");
+  SetHaltFlag(false);
+
   // Create a raw pthread; its start routine will attach to the runtime.
-  errno = pthread_create(&thread_, NULL, &Run, NULL);
+  errno = pthread_create(&thread_, NULL, &Run, this);
   if (errno != 0) {
     PLOG(FATAL) << "pthread_create failed for signal catcher thread";
   }
@@ -42,11 +43,21 @@
 SignalCatcher::~SignalCatcher() {
   // Since we know the thread is just sitting around waiting for signals
   // to arrive, send it one.
-  halt_ = true;
+  SetHaltFlag(true);
   pthread_kill(thread_, SIGQUIT);
   pthread_join(thread_, NULL);
 }
 
+void SignalCatcher::SetHaltFlag(bool new_value) {
+  MutexLock mu(lock_);
+  halt_ = new_value;
+}
+
+bool SignalCatcher::ShouldHalt() {
+  MutexLock mu(lock_);
+  return halt_;
+}
+
 void SignalCatcher::HandleSigQuit() {
   // TODO: suspend all threads
 
@@ -100,8 +111,11 @@
   return signal_number;
 }
 
-void* SignalCatcher::Run(void*) {
-  Runtime::Current()->AttachCurrentThread("Signal Catcher", NULL, true);
+void* SignalCatcher::Run(void* arg) {
+  SignalCatcher* signal_catcher = reinterpret_cast<SignalCatcher*>(arg);
+  CHECK(signal_catcher != NULL);
+
+  Runtime::Current()->AttachCurrentThread("Signal Catcher", true);
   Thread* self = Thread::Current();
   CHECK(self != NULL);
 
@@ -113,7 +127,7 @@
 
   while (true) {
     int signal_number = WaitForSignal(self, mask);
-    if (halt_) {
+    if (signal_catcher->ShouldHalt()) {
       Runtime::Current()->DetachCurrentThread();
       return NULL;
     }