blob: b5ee8203a82a39de03490946dd103dfdea5b43b0 [file]
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_CONNECTIVITY_NETWORK_DRIVERS_NETWORK_DEVICE_DEVICE_LOCKS_H_
#define SRC_CONNECTIVITY_NETWORK_DRIVERS_NETWORK_DEVICE_DEVICE_LOCKS_H_
#include <mutex>
#include <shared_mutex>
#include <fbl/mutex.h>
namespace network::internal {
// TODO(https://fxbug.dev/75544): Get rid of these classes and this file once std::shared_mutex and
// std::shared_lock have thread analysis annotations.
class __TA_CAPABILITY("shared_mutex") SharedLock {
public:
SharedLock() = default;
void Acquire() __TA_ACQUIRE() { m_.lock(); }
void Release() __TA_RELEASE() { m_.unlock(); }
void AcquireShared() __TA_ACQUIRE_SHARED() { m_.lock(); }
void ReleaseShared() __TA_RELEASE_SHARED() { m_.unlock(); }
DISALLOW_COPY_ASSIGN_AND_MOVE(SharedLock);
private:
std::shared_mutex m_;
};
template <typename T>
class __TA_SCOPED_CAPABILITY SharedAutoLock {
public:
__WARN_UNUSED_CONSTRUCTOR explicit SharedAutoLock(T* mutex) __TA_ACQUIRE_SHARED(mutex)
: mutex_(mutex) {
mutex_->AcquireShared();
}
~SharedAutoLock() __TA_RELEASE() { release(); }
// early release the mutex before the object goes out of scope
void release() __TA_RELEASE() {
// In typical usage, this conditional will be optimized away so
// that mutex_->Release() is called unconditionally.
if (mutex_ != nullptr) {
mutex_->ReleaseShared();
mutex_ = nullptr;
}
}
DISALLOW_COPY_ASSIGN_AND_MOVE(SharedAutoLock);
private:
T* mutex_;
};
} // namespace network::internal
#endif // SRC_CONNECTIVITY_NETWORK_DRIVERS_NETWORK_DEVICE_DEVICE_LOCKS_H_