PLCnext API Documentation 25.0.2.69
NonBlockingNotificationRegistration3ArgumentsBuffer.hpp
1
2//
3// Copyright Phoenix Contact GmbH & Co. KG
4//
6#pragma once
8#include "Arp/System/Commons/Threading/LockGuard.hpp"
9#include "Arp/System/Commons/Threading/Mutex.hpp"
10#include "Arp/System/Nm/NonBlockingNotificationRegistration3ArgumentsBufferBase.hpp"
11#include <algorithm>
12#include <limits>
13#include <numeric>
14
15namespace Arp { namespace System { namespace Nm
16{
17
18template<typename ArgumentsType>
21{
22private:
25
26public:
28
29 InsertResult Insert(const ArgumentsType& argument);
30
32 {
33 ArgumentsType Args{};
34 bool IsValid = false;
35 };
36 RemoveResult Remove(size_t index);
37
38 bool IsFull() const;
39 bool IsFree(size_t index) const;
40
41private:
42 bool IsFullUnsynced() const;
43 bool IsFreeUnsynced(size_t index) const;
44
45private:
46 std::vector<ArgumentsType> arguments;
47 std::vector<size_t> freeList;
48 size_t next = 0;
49 mutable Mutex mutex;
50};
51
52template<typename ArgumentsType>
54 size_t capacity)
55 : arguments(capacity), freeList(capacity)
56{
57 std::iota(freeList.begin(), freeList.end(), 1);
58}
59
60template<typename ArgumentsType>
63{
64 LockGuard lock(this->mutex);
65 if (this->IsFullUnsynced())
66 {
67 return {this->arguments.size(), false};
68 }
69
70 size_t current = this->next;
71 this->arguments.at(current) = argument;
72 this->next = std::exchange(this->freeList.at(current), this->arguments.size());
73 return {current, true};
74}
75
76template<typename ArgumentsType>
77typename NonBlockingNotificationRegistration3ArgumentsBuffer<ArgumentsType>::RemoveResult
78NonBlockingNotificationRegistration3ArgumentsBuffer<ArgumentsType>::Remove(size_t index)
79{
80 LockGuard lock(this->mutex);
81 if ((index >= this->arguments.size()) || this->IsFreeUnsynced(index))
82 {
83 return {{}, false};
84 }
85
86 this->freeList.at(index) = this->next;
87 this->next = index;
88 return {this->arguments.at(index), true};
89}
90
91template<typename ArgumentsType>
92bool NonBlockingNotificationRegistration3ArgumentsBuffer<ArgumentsType>::IsFull() const
93{
94 LockGuard lock(this->mutex);
95 return this->IsFullUnsynced();
96}
97
98template<typename ArgumentsType>
99bool NonBlockingNotificationRegistration3ArgumentsBuffer<ArgumentsType>::IsFree(size_t index) const
100{
101 LockGuard lock(this->mutex);
102 return this->IsFreeUnsynced(index);
103}
104
105template<typename ArgumentsType>
106bool NonBlockingNotificationRegistration3ArgumentsBuffer<ArgumentsType>::IsFullUnsynced() const
107{
108 return this->next == this->arguments.size();
109}
110
111template<typename ArgumentsType>
112bool NonBlockingNotificationRegistration3ArgumentsBuffer<ArgumentsType>::IsFreeUnsynced(size_t index) const
113{
114 return (index < this->arguments.size()) &&
115 ((this->next == index) ||
116 (std::find(this->freeList.begin(), this->freeList.end(), index) != this->freeList.end()));
117}
118
119}}} // namespace Arp::System::Nm
Simple lock guard, acquiring lock on construction and release it on destruction.
Definition: LockGuard.hpp:17
Mutual exclusion object to prevent data from concurrent modifications.
Definition: Mutex.hpp:27
Internal base class for ArgumentsBuffer
Definition: NonBlockingNotificationRegistration3ArgumentsBufferBase.hpp:20
Definition: NonBlockingNotificationRegistration3ArgumentsBuffer.hpp:21
Root namespace for the PLCnext API
Definition: NonBlockingNotificationRegistration3ArgumentsBufferBase.hpp:39
Definition: NonBlockingNotificationRegistration3ArgumentsBuffer.hpp:32