Add ScopedThreadSuspension

Fixes the TransitionFromRunnableToSuspended and
TransitionFromSuspendedToRunnable pattern that was prone to errors.

Change-Id: Ie6ae9c0357c83b4fc4899d05dfa0975553170267
diff --git a/runtime/jdwp/jdwp_handler.cc b/runtime/jdwp/jdwp_handler.cc
index 7776f8f..0a4d6e3 100644
--- a/runtime/jdwp/jdwp_handler.cc
+++ b/runtime/jdwp/jdwp_handler.cc
@@ -31,6 +31,7 @@
 #include "jdwp/jdwp_expand_buf.h"
 #include "jdwp/jdwp_priv.h"
 #include "runtime.h"
+#include "scoped_thread_state_change.h"
 #include "thread-inl.h"
 #include "utils.h"
 
@@ -238,9 +239,8 @@
 static JdwpError VM_Suspend(JdwpState*, Request*, ExpandBuf*)
     SHARED_REQUIRES(Locks::mutator_lock_) {
   Thread* self = Thread::Current();
-  self->TransitionFromRunnableToSuspended(kWaitingForDebuggerSuspension);
+  ScopedThreadSuspension sts(self, kWaitingForDebuggerSuspension);
   Dbg::SuspendVM();
-  self->TransitionFromSuspendedToRunnable();
   return ERR_NONE;
 }
 
@@ -922,9 +922,8 @@
   }
 
   Thread* self = Thread::Current();
-  self->TransitionFromRunnableToSuspended(kWaitingForDebuggerSend);
+  ScopedThreadSuspension sts(self, kWaitingForDebuggerSend);
   JdwpError result = Dbg::SuspendThread(thread_id);
-  self->TransitionFromSuspendedToRunnable();
   return result;
 }
 
@@ -1609,7 +1608,7 @@
    * Do this after anything that can stall indefinitely.
    */
   Thread* self = Thread::Current();
-  ThreadState old_state = self->TransitionFromSuspendedToRunnable();
+  ScopedObjectAccess soa(self);
 
   expandBufAddSpace(pReply, kJDWPHeaderLen);
 
@@ -1670,9 +1669,6 @@
     last_activity_time_ms_.StoreSequentiallyConsistent(MilliTime());
   }
 
-  /* tell the VM that GC is okay again */
-  self->TransitionFromRunnableToSuspended(old_state);
-
   return replyLength;
 }