Add class AtomicList

This commit is contained in:
nsubiron 2019-05-28 14:10:15 +02:00 committed by Néstor Subirón
parent 976e4db97a
commit 283c5ce17c
2 changed files with 62 additions and 14 deletions

View File

@ -0,0 +1,56 @@
// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma
// de Barcelona (UAB).
//
// This work is licensed under the terms of the MIT license.
// For a copy, see <https://opensource.org/licenses/MIT>.
#pragma once
#include "carla/AtomicSharedPtr.h"
#include "carla/NonCopyable.h"
#include <mutex>
#include <vector>
namespace carla {
namespace client {
namespace detail {
/// Holds an atomic pointer to a list.
///
/// @warning Only Load method is atomic, modifications to the list are locked
/// with a mutex.
template <typename T, typename ListT = std::vector<T>>
class AtomicList : private NonCopyable {
public:
AtomicList() : _list(std::make_shared<ListT>()) {}
template <typename ValueT>
void Push(ValueT &&value) {
std::lock_guard<std::mutex> lock(_mutex);
auto new_list = std::make_shared<ListT>(*Load());
new_list->push_back(std::forward<ValueT>(value));
_list = new_list;
}
void Clear() {
std::lock_guard<std::mutex> lock(_mutex);
_list = std::make_shared<ListT>();
}
/// Returns a pointer to the list.
std::shared_ptr<const ListT> Load() const {
return _list.load();
}
private:
std::mutex _mutex;
AtomicSharedPtr<const ListT> _list;
};
} // namespace detail
} // namespace client
} // namespace carla

View File

@ -6,11 +6,10 @@
#pragma once
#include "carla/AtomicSharedPtr.h"
#include "carla/AtomicList.h"
#include "carla/NonCopyable.h"
#include <functional>
#include <vector>
namespace carla {
namespace client {
@ -22,31 +21,24 @@ namespace detail {
using CallbackType = std::function<void(InputsT...)>;
CallbackList() : _list(std::make_shared<ListType>()) {}
void Call(InputsT... args) const {
auto list = _list.load();
auto list = _list.Load();
for (auto &callback : *list) {
callback(args...);
}
}
/// @todo This function cannot be called concurrently.
void RegisterCallback(CallbackType callback) {
auto new_list = std::make_shared<ListType>(*_list.load());
new_list->emplace_back(std::move(callback));
_list = new_list;
void RegisterCallback(CallbackType &&callback) {
_list.Push(std::move(callback));
}
void Clear() {
_list = std::make_shared<ListType>();
_list.Clear();
}
private:
using ListType = std::vector<CallbackType>;
AtomicSharedPtr<const ListType> _list;
AtomicList<CallbackType> _list;
};
} // namespace detail