diff options
author | 2015-09-03 16:13:34 -0700 | |
---|---|---|
committer | 2015-09-03 17:33:19 -0700 | |
commit | f1d666e1b48f8070ef1177fce156c08827f08eb8 (patch) | |
tree | 772cbbe6652b32ea2be31532156295db27579390 /runtime/scoped_thread_state_change.h | |
parent | 897ce64153e4758663e464fb5fb339f9a7b496c8 (diff) |
Add ScopedThreadSuspension
Fixes the TransitionFromRunnableToSuspended and
TransitionFromSuspendedToRunnable pattern that was prone to errors.
Change-Id: Ie6ae9c0357c83b4fc4899d05dfa0975553170267
Diffstat (limited to 'runtime/scoped_thread_state_change.h')
-rw-r--r-- | runtime/scoped_thread_state_change.h | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/runtime/scoped_thread_state_change.h b/runtime/scoped_thread_state_change.h index b90aa0ec0e..d1cc09ab09 100644 --- a/runtime/scoped_thread_state_change.h +++ b/runtime/scoped_thread_state_change.h @@ -31,7 +31,7 @@ namespace art { // more complicated suspension checking. The subclasses ScopedObjectAccessUnchecked and // ScopedObjectAccess are used to handle the change into Runnable to Get direct access to objects, // the unchecked variant doesn't aid annotalysis. -class ScopedThreadStateChange { +class ScopedThreadStateChange : public ValueObject { public: ScopedThreadStateChange(Thread* self, ThreadState new_thread_state) REQUIRES(!Locks::thread_suspend_count_lock_) ALWAYS_INLINE @@ -102,7 +102,7 @@ class ScopedThreadStateChange { }; // Assumes we are already runnable. -class ScopedObjectAccessAlreadyRunnable { +class ScopedObjectAccessAlreadyRunnable : public ValueObject { public: Thread* Self() const { return self_; @@ -277,6 +277,30 @@ class ScopedObjectAccess : public ScopedObjectAccessUnchecked { DISALLOW_COPY_AND_ASSIGN(ScopedObjectAccess); }; +// Annotalysis helper for going to a suspended state from runnable. +class ScopedThreadSuspension : public ValueObject { + public: + explicit ScopedThreadSuspension(Thread* self, ThreadState suspended_state) + REQUIRES(!Locks::thread_suspend_count_lock_, !Roles::uninterruptible_) + UNLOCK_FUNCTION(Locks::mutator_lock_) + ALWAYS_INLINE + : self_(self), suspended_state_(suspended_state) { + DCHECK(self_ != nullptr); + self_->TransitionFromRunnableToSuspended(suspended_state); + } + + ~ScopedThreadSuspension() SHARED_LOCK_FUNCTION(Locks::mutator_lock_) ALWAYS_INLINE { + DCHECK_EQ(self_->GetState(), suspended_state_); + self_->TransitionFromSuspendedToRunnable(); + } + + private: + Thread* const self_; + const ThreadState suspended_state_; + DISALLOW_COPY_AND_ASSIGN(ScopedThreadSuspension); +}; + + } // namespace art #endif // ART_RUNTIME_SCOPED_THREAD_STATE_CHANGE_H_ |