Merge "base: add ScopedLockAssertion." am: 3777d9cc10
am: 379b6f403f
Change-Id: I47d1ab2dc1d904e7f22c541232b15ee1ec97aa17
This commit is contained in:
commit
f01d33b9e8
2 changed files with 43 additions and 14 deletions
|
@ -52,6 +52,8 @@
|
|||
#include "fdevent.h"
|
||||
#include "sysdeps/chrono.h"
|
||||
|
||||
using android::base::ScopedLockAssertion;
|
||||
|
||||
static void remove_transport(atransport* transport);
|
||||
static void transport_unref(atransport* transport);
|
||||
|
||||
|
@ -72,17 +74,6 @@ const char* const kFeatureAbb = "abb";
|
|||
|
||||
namespace {
|
||||
|
||||
// A class that helps the Clang Thread Safety Analysis deal with
|
||||
// std::unique_lock. Given that std::unique_lock is movable, and the analysis
|
||||
// can not currently perform alias analysis, it is not annotated. In order to
|
||||
// assert that the mutex is held, a ScopedAssumeLocked can be created just after
|
||||
// the std::unique_lock.
|
||||
class SCOPED_CAPABILITY ScopedAssumeLocked {
|
||||
public:
|
||||
ScopedAssumeLocked(std::mutex& mutex) ACQUIRE(mutex) {}
|
||||
~ScopedAssumeLocked() RELEASE() {}
|
||||
};
|
||||
|
||||
#if ADB_HOST
|
||||
// Tracks and handles atransport*s that are attempting reconnection.
|
||||
class ReconnectHandler {
|
||||
|
@ -180,7 +171,7 @@ void ReconnectHandler::Run() {
|
|||
ReconnectAttempt attempt;
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(reconnect_mutex_);
|
||||
ScopedAssumeLocked assume_lock(reconnect_mutex_);
|
||||
ScopedLockAssertion assume_lock(reconnect_mutex_);
|
||||
|
||||
if (!reconnect_queue_.empty()) {
|
||||
// FIXME: libstdc++ (used on Windows) implements condition_variable with
|
||||
|
@ -296,7 +287,7 @@ void BlockingConnectionAdapter::Start() {
|
|||
LOG(INFO) << this->transport_name_ << ": write thread spawning";
|
||||
while (true) {
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
ScopedAssumeLocked assume_locked(mutex_);
|
||||
ScopedLockAssertion assume_locked(mutex_);
|
||||
cv_.wait(lock, [this]() REQUIRES(mutex_) {
|
||||
return this->stopped_ || !this->write_queue_.empty();
|
||||
});
|
||||
|
@ -923,7 +914,7 @@ atransport* acquire_one_transport(TransportType type, const char* serial, Transp
|
|||
|
||||
bool ConnectionWaitable::WaitForConnection(std::chrono::milliseconds timeout) {
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
ScopedAssumeLocked assume_locked(mutex_);
|
||||
ScopedLockAssertion assume_locked(mutex_);
|
||||
return cv_.wait_for(lock, timeout, [&]() REQUIRES(mutex_) {
|
||||
return connection_established_ready_;
|
||||
}) && connection_established_;
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
|
||||
|
||||
#define CAPABILITY(x) \
|
||||
|
@ -104,3 +106,39 @@
|
|||
|
||||
#define NO_THREAD_SAFETY_ANALYSIS \
|
||||
THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis)
|
||||
|
||||
namespace android {
|
||||
namespace base {
|
||||
|
||||
// A class to help thread safety analysis deal with std::unique_lock and condition_variable.
|
||||
//
|
||||
// Clang's thread safety analysis currently doesn't perform alias analysis, so movable types
|
||||
// like std::unique_lock can't be marked with thread safety annotations. This helper allows
|
||||
// for manual assertion of lock state in a scope.
|
||||
//
|
||||
// For example:
|
||||
//
|
||||
// std::mutex mutex;
|
||||
// std::condition_variable cv;
|
||||
// std::vector<int> vec GUARDED_BY(mutex);
|
||||
//
|
||||
// int pop() {
|
||||
// std::unique_lock lock(mutex);
|
||||
// ScopedLockAssertion lock_assertion(mutex);
|
||||
// cv.wait(lock, []() {
|
||||
// ScopedLockAssertion lock_assertion(mutex);
|
||||
// return !vec.empty();
|
||||
// });
|
||||
//
|
||||
// int result = vec.back();
|
||||
// vec.pop_back();
|
||||
// return result;
|
||||
// }
|
||||
class SCOPED_CAPABILITY ScopedLockAssertion {
|
||||
public:
|
||||
ScopedLockAssertion(std::mutex& mutex) ACQUIRE(mutex) {}
|
||||
~ScopedLockAssertion() RELEASE() {}
|
||||
};
|
||||
|
||||
} // namespace base
|
||||
} // namespace android
|
||||
|
|
Loading…
Reference in a new issue