RequestQueue.cpp
Go to the documentation of this file.
1#include "RequestQueue.h"
2
3#include <boost/lockfree/policies.hpp>
4#include <boost/lockfree/spsc_queue.hpp>
5
7
10
16
18{
20 {
21 static constexpr size_t queueSize = 100;
22
23 boost::lockfree::spsc_queue<std::shared_ptr<RequestBase>,
24 boost::lockfree::capacity<queueSize>>
26 };
27
28 RequestQueue::RequestQueue() : pimpl(std::make_unique<QueueImpl>())
29 {
30 }
31
32 RequestQueue::~RequestQueue() = default; // Need for std::unique_ptr to incomplete type
33
36 {
37 swap(pimpl, rhs.pimpl);
38 return *this;
39 }
40
41 std::shared_ptr<RequestBase>
43 {
44 std::shared_ptr<RequestBase> request;
45 if (!pimpl->queue.pop(request))
46 {
47 return nullptr;
48 }
49 return request;
50 }
51
52 void
53 RequestQueue::postReply(std::shared_ptr<RequestBase>&& request)
54 {
55 request->setProcessed();
56 requestCV.notify_all();
57 }
58
59 bool
60 RequestQueue::postRequest(const std::shared_ptr<RequestBase>& request)
61 {
62 static std::mutex mtx;
63 std::unique_lock<std::mutex> lck(mtx);
64
65 if (pimpl->queue.write_available() < 10)
66 {
67 GENERAL_ERROR("Queue is running full.");
68 }
69
70
71 pimpl->queue.push(request);
72 requestCV.wait(lck,
73 [&, request]() { return request->isProcessed() || request->hasFailed(); });
74 return !request->hasFailed();
75 }
76
77 bool
79 int* buflen,
80 unsigned char* buf,
81 bool completeAccess)
82 {
83 std::shared_ptr<SDOUpdateRequest> request =
84 std::make_shared<SDOUpdateRequest>(sdoIdentifier, buflen, buf, true, completeAccess);
85 return postSDOUpdateRequest(request);
86 }
87
88 bool
90 int buflen,
91 unsigned char* buf,
92 bool completeAccess)
93 {
94 std::shared_ptr<SDOUpdateRequest> request =
95 std::make_shared<SDOUpdateRequest>(sdoIdentifier, &buflen, buf, false, completeAccess);
96 return postSDOUpdateRequest(request);
97 }
98
99 bool
100 RequestQueue::postChangeStateRequest(std::uint16_t slaveIndex,
101 EtherCATState state,
102 bool validate,
103 EtherCATState* actualState)
104 {
105 std::shared_ptr<ChangeStateRequest> request =
106 std::make_shared<ChangeStateRequest>(slaveIndex, state, validate, actualState);
107 return postRequest(request);
108 }
109
110 bool
112 {
113 auto request = std::make_shared<ReadStatesRequest>(state);
114 return postRequest(request);
115 }
116
117 bool
119 {
120 auto request = std::make_shared<RegisterResetRequest>(slaveIndex);
121 return postRequest(request);
122 }
123
124 bool
125 RequestQueue::postRegisterReadRequest(std::vector<RegisterDataList>& registerData)
126 {
127 auto request = std::make_shared<RegisterReadRequest>(&registerData);
128 return postRequest(request);
129 }
130
131 bool
133 std::uint16_t amountFramesToRead)
134 {
135 auto request = std::make_shared<RegisterReadRequest>(frames, amountFramesToRead);
136 return postRequest(request);
137 }
138
139 bool
140 RequestQueue::postSDOUpdateRequest(const std::shared_ptr<SDOUpdateRequest>& request)
141 {
142 return postRequest(request);
143 }
144} // namespace armarx::control::ethercat
#define GENERAL_ERROR(...)
This class is a wrapper around an enum containing the different EtherCAT states.
Brief description of class RequestQueue.
bool postSDOReadRequest(SDOIdentifier sdoIdentifier, int *buflen, unsigned char *buf, bool completeAccess)
bool postRegisterReadRequest(std::vector< RegisterDataList > &registerData)
std::shared_ptr< RequestBase > getNextRequest()
RequestQueue & operator=(RequestQueue rhs)
bool postReadStatesRequest(EtherCATState *state)
void postReply(std::shared_ptr< RequestBase > &&request)
bool postChangeStateRequest(std::uint16_t slaveIndex, EtherCATState state, bool validate, EtherCATState *actualState)
bool postSDOWriteRequest(SDOIdentifier sdoIdentifier, int buflen, unsigned char *buf, bool completeAccess)
bool postRegisterResetRequest(std::uint16_t slaveIndex)
The EtherCATFrameList struct holds a list of EtherCAT frames that can be scheduled in round-robin-sty...
boost::lockfree::spsc_queue< std::shared_ptr< RequestBase >, boost::lockfree::capacity< queueSize > > queue