diff --git a/LibCarla/source/carla/AtomicList.h b/LibCarla/source/carla/AtomicList.h new file mode 100644 index 000000000..50b5375fb --- /dev/null +++ b/LibCarla/source/carla/AtomicList.h @@ -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 . + +#pragma once + +#include "carla/AtomicSharedPtr.h" +#include "carla/NonCopyable.h" + +#include +#include + +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 > + class AtomicList : private NonCopyable { + public: + + AtomicList() : _list(std::make_shared()) {} + + template + void Push(ValueT &&value) { + std::lock_guard lock(_mutex); + auto new_list = std::make_shared(*Load()); + new_list->push_back(std::forward(value)); + _list = new_list; + } + + void Clear() { + std::lock_guard lock(_mutex); + _list = std::make_shared(); + } + + /// Returns a pointer to the list. + std::shared_ptr Load() const { + return _list.load(); + } + + private: + + std::mutex _mutex; + + AtomicSharedPtr _list; + }; + +} // namespace detail +} // namespace client +} // namespace carla diff --git a/LibCarla/source/carla/client/detail/CallbackList.h b/LibCarla/source/carla/client/detail/CallbackList.h index 062b000d6..112a53be7 100644 --- a/LibCarla/source/carla/client/detail/CallbackList.h +++ b/LibCarla/source/carla/client/detail/CallbackList.h @@ -6,11 +6,10 @@ #pragma once -#include "carla/AtomicSharedPtr.h" +#include "carla/AtomicList.h" #include "carla/NonCopyable.h" #include -#include namespace carla { namespace client { @@ -22,31 +21,24 @@ namespace detail { using CallbackType = std::function; - CallbackList() : _list(std::make_shared()) {} - 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(*_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(); + _list.Clear(); } private: - using ListType = std::vector; - - AtomicSharedPtr _list; + AtomicList _list; }; } // namespace detail