Thread tidying.

Add is_started_ boolean to Thread so that we don't read an uncreated
pthread_key_self_, don't start twice or call shutdown when not started.
Don't use a MutexLock in ThreadList::Unregister, as the MutexLock will
hold a copy of self for the thread that's deleted.
Don't memory leak the resume condition variable.

Change-Id: I767968a9f785e560fc9e356a339e684de5ce2ffc
diff --git a/src/thread.cc b/src/thread.cc
index e6c32ca..07a3a90 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -66,8 +66,9 @@
 
 namespace art {
 
+bool Thread::is_started_ = false;
 pthread_key_t Thread::pthread_key_self_;
-ConditionVariable* Thread::resume_cond_;
+ConditionVariable* Thread::resume_cond_ = NULL;
 
 static const char* kThreadNameDuringStartup = "<native thread without managed peer>";
 
@@ -323,6 +324,7 @@
   // Set pthread_self_ ahead of pthread_setspecific, that makes Thread::Current function, this
   // avoids pthread_self_ ever being invalid when discovered from Thread::Current().
   pthread_self_ = pthread_self();
+  CHECK(is_started_);
   CHECK_PTHREAD_CALL(pthread_setspecific, (Thread::pthread_key_self_, this), "attach self");
   DCHECK_EQ(Thread::Current(), this);
 
@@ -829,7 +831,7 @@
 
   std::ostream& os;
   const Thread* thread;
-  bool can_allocate;
+  const bool can_allocate;
   MethodHelper mh;
   mirror::AbstractMethod* last_method;
   int last_line_number;
@@ -880,6 +882,7 @@
   Thread* self = reinterpret_cast<Thread*>(arg);
   if (self->thread_exit_check_count_ == 0) {
     LOG(WARNING) << "Native thread exiting without having called DetachCurrentThread (maybe it's going to use a pthread_key_create destructor?): " << *self;
+    CHECK(is_started_);
     CHECK_PTHREAD_CALL(pthread_setspecific, (Thread::pthread_key_self_, self), "reattach self");
     self->thread_exit_check_count_ = 1;
   } else {
@@ -888,6 +891,8 @@
 }
 
 void Thread::Startup() {
+  CHECK(!is_started_);
+  is_started_ = true;
   {
     MutexLock mu(Thread::Current(), *Locks::thread_suspend_count_lock_);  // Keep GCC happy.
     resume_cond_ = new ConditionVariable("Thread resumption condition variable",
@@ -915,7 +920,13 @@
 }
 
 void Thread::Shutdown() {
+  CHECK(is_started_);
+  is_started_ = false;
   CHECK_PTHREAD_CALL(pthread_key_delete, (Thread::pthread_key_self_), "self key");
+  if (resume_cond_ != NULL) {
+    delete resume_cond_;
+    resume_cond_ = NULL;
+  }
 }
 
 Thread::Thread(bool daemon)
diff --git a/src/thread.h b/src/thread.h
index 37f2721..f642d56 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -101,11 +101,15 @@
   // Reset internal state of child thread after fork.
   void InitAfterFork();
 
-  static Thread* Current() __attribute__ ((pure)) {
+  static Thread* Current() {
     // We rely on Thread::Current returning NULL for a detached thread, so it's not obvious
     // that we can replace this with a direct %fs access on x86.
-    void* thread = pthread_getspecific(Thread::pthread_key_self_);
-    return reinterpret_cast<Thread*>(thread);
+    if(!is_started_) {
+      return NULL;
+    } else {
+      void* thread = pthread_getspecific(Thread::pthread_key_self_);
+      return reinterpret_cast<Thread*>(thread);
+    }
   }
 
   static Thread* FromManagedThread(const ScopedObjectAccessUnchecked& ts,
@@ -617,6 +621,9 @@
 
   static void ThreadExitCallback(void* arg);
 
+  // Has Thread::Startup been called?
+  static bool is_started_;
+
   // TLS key used to retrieve the Thread*.
   static pthread_key_t pthread_key_self_;
 
diff --git a/src/thread_list.cc b/src/thread_list.cc
index 45ddd23..ebb63dd 100644
--- a/src/thread_list.cc
+++ b/src/thread_list.cc
@@ -554,7 +554,8 @@
   while (self != NULL) {
     // Remove and delete the Thread* while holding the thread_list_lock_ and
     // thread_suspend_count_lock_ so that the unregistering thread cannot be suspended.
-    MutexLock mu(self, *Locks::thread_list_lock_);
+    // Note: deliberately not using MutexLock that could hold a stale self pointer.
+    Locks::thread_list_lock_->ExclusiveLock(self);
     CHECK(Contains(self));
     // Note: we don't take the thread_suspend_count_lock_ here as to be suspending a thread other
     // than yourself you need to hold the thread_list_lock_ (see Thread::ModifySuspendCount).
@@ -563,6 +564,7 @@
       delete self;
       self = NULL;
     }
+    Locks::thread_list_lock_->ExclusiveUnlock(self);
   }
 
   // Clear the TLS data, so that the underlying native thread is recognizably detached.