blob: d8c7be1a60adac726739a4a0e5c703c952fffc63 [file] [log] [blame]
// Copyright 2021 The Chromium OS 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 LIBHWSEC_FOUNDATION_UTILITY_SYNCHRONIZED_H_
#define LIBHWSEC_FOUNDATION_UTILITY_SYNCHRONIZED_H_
#include <utility>
#include <base/synchronization/lock.h>
#include "libhwsec-foundation/hwsec-foundation_export.h"
namespace hwsec_foundation {
namespace utility {
template <class T>
class SynchronizedHandle;
// Wrapper that can provide synchronized access to the underlying class object.
// The Lock() method returns a SynchronizedHandle which acquires a lock to
// ensure exclusive access of the object. Note that the underlying
// implementation use locks, so you should be aware of when/how to use this as
// if you are using ordinary locks to prevent deadlock.
//
// Example usage:
// Synchronized<std::vector<int>> v;
// v.Lock()->push_back(1);
//
// SynchronizedHandle<std::vector<int>> handle = v.Lock();
// int original_size = handle->size();
// handle->push_back(2);
// assert(handle->size() == original_size + 1);
template <class T>
class HWSEC_FOUNDATION_EXPORT Synchronized {
public:
template <typename... Args>
explicit Synchronized(Args&&... args) : data_(std::forward<Args>(args)...) {}
Synchronized(const Synchronized&) = delete;
Synchronized& operator=(const Synchronized&) = delete;
~Synchronized() {}
// Returns a SynchronizedHandle which acquires a lock to ensure exclusive
// access of the object. The lock is released after the SynchronizedHandle is
// out of scope. If there is already a SynchronizedHandle instance generated
// by this method, this method blocks until that handle is out of scope.
SynchronizedHandle<T> Lock() { return SynchronizedHandle(this); }
private:
T data_;
base::Lock lock_;
friend class SynchronizedHandle<T>;
};
// Returned by the Lock() method of Synchronized. Provides exclusive
// access of the object, and derefs into it.
template <class T>
class HWSEC_FOUNDATION_EXPORT SynchronizedHandle {
public:
SynchronizedHandle(const SynchronizedHandle&) = delete;
SynchronizedHandle& operator=(const SynchronizedHandle&) = delete;
~SynchronizedHandle() {}
T* operator->() { return &synchronized_->data_; }
private:
explicit SynchronizedHandle(Synchronized<T>* synchronized)
: synchronized_(synchronized), auto_lock_(synchronized->lock_) {}
Synchronized<T>* synchronized_;
base::AutoLock auto_lock_;
friend class Synchronized<T>;
};
} // namespace utility
} // namespace hwsec_foundation
#endif // LIBHWSEC_FOUNDATION_UTILITY_SYNCHRONIZED_H_