File indexing completed on 2024-04-06 12:11:55
0001 #ifndef FWCore_Concurrency_ThreadSafeAddOnlyContainer_h
0002 #define FWCore_Concurrency_ThreadSafeAddOnlyContainer_h
0003
0004 #include <atomic>
0005 #include <utility>
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 namespace edm {
0029
0030 template <typename T>
0031 class ThreadSafeAddOnlyContainer {
0032 public:
0033 ThreadSafeAddOnlyContainer();
0034
0035 ~ThreadSafeAddOnlyContainer();
0036
0037 template <typename... Args>
0038 T* makeAndHold(Args&&... args);
0039
0040 private:
0041 class Node {
0042 public:
0043 template <typename... Args>
0044 Node(Node* iNext, Args&&... args);
0045 Node const* next() const { return next_; }
0046 void setNext(Node* v) { next_ = v; }
0047 T* address() { return &data_; }
0048
0049 private:
0050 Node* next_;
0051 T data_;
0052 };
0053
0054 std::atomic<Node*> front_;
0055 };
0056
0057 template <typename T>
0058 ThreadSafeAddOnlyContainer<T>::ThreadSafeAddOnlyContainer() : front_(nullptr) {}
0059
0060 template <typename T>
0061 ThreadSafeAddOnlyContainer<T>::~ThreadSafeAddOnlyContainer() {
0062 Node const* node = front_.load();
0063 while (node) {
0064 Node const* next = node->next();
0065 delete node;
0066 node = next;
0067 }
0068 }
0069
0070 template <typename T>
0071 template <typename... Args>
0072 T* ThreadSafeAddOnlyContainer<T>::makeAndHold(Args&&... args) {
0073 Node* expected = front_.load();
0074 Node* newNode = new Node(expected, std::forward<Args>(args)...);
0075 while (!front_.compare_exchange_strong(expected, newNode)) {
0076
0077 newNode->setNext(expected);
0078 }
0079 return newNode->address();
0080 }
0081
0082 template <typename T>
0083 template <typename... Args>
0084 ThreadSafeAddOnlyContainer<T>::Node::Node(Node* iNext, Args&&... args)
0085 : next_(iNext), data_(std::forward<Args>(args)...) {}
0086 }
0087
0088 #endif