pva2pva 1.4.2
Loading...
Searching...
No Matches
utilities.h
1#ifndef UTILITIES_H
2#define UTILITIES_H
3
4#include <deque>
5#include <sstream>
6
7#include <errlog.h>
8#include <epicsEvent.h>
9#include <epicsUnitTest.h>
10#include <dbUnitTest.h>
11
12#include <pv/pvUnitTest.h>
13#include <pv/pvAccess.h>
14
15#include "pvahelper.h"
16#include "weakmap.h"
17#include "weakset.h"
18
19struct TestPV;
20struct TestPVChannel;
21struct TestPVMonitor;
22struct TestProvider;
23
24// minimally useful boilerplate which must appear *everywhere*
25#define DUMBREQUESTER(NAME) \
26 virtual std::string getRequesterName() OVERRIDE { return #NAME; }
27
28template<typename T>
29inline std::string toString(const T& tbs)
30{
31 std::ostringstream oss;
32 oss << tbs;
33 return oss.str();
34}
35
36// Boilerplate reduction for accessing a scalar field
37template<typename T>
38struct ScalarAccessor {
39 epics::pvData::PVScalar::shared_pointer field;
40 typedef T value_type;
41 ScalarAccessor(const epics::pvData::PVStructurePtr& s, const char *name)
42 :field(s->getSubFieldT<epics::pvData::PVScalar>(name))
43 {}
44 operator value_type() {
45 return field->getAs<T>();
46 }
47 ScalarAccessor& operator=(T v) {
48 field->putFrom<T>(v);
49 return *this;
50 }
51 ScalarAccessor& operator+=(T v) {
52 field->putFrom<T>(field->getAs<T>()+v);
53 return *this;
54 }
55};
56
57struct TestChannelRequester : public epics::pvAccess::ChannelRequester
58{
59 POINTER_DEFINITIONS(TestChannelRequester);
60 DUMBREQUESTER(TestChannelRequester)
61
62 epicsMutex lock;
63 epicsEvent wait;
64 epics::pvAccess::Channel::shared_pointer chan;
65 epics::pvData::Status status;
66 epics::pvAccess::Channel::ConnectionState laststate;
67 TestChannelRequester();
68 virtual ~TestChannelRequester();
69 virtual void channelCreated(const epics::pvData::Status& status,
70 epics::pvAccess::Channel::shared_pointer const & channel) OVERRIDE FINAL;
71 virtual void channelStateChange(epics::pvAccess::Channel::shared_pointer const & channel,
72 epics::pvAccess::Channel::ConnectionState connectionState) OVERRIDE FINAL;
73
74 bool waitForConnect();
75};
76
77struct TestChannelFieldRequester : public epics::pvAccess::GetFieldRequester
78{
79 POINTER_DEFINITIONS(TestChannelFieldRequester);
80 DUMBREQUESTER(TestChannelFieldRequester)
81
82 bool done;
83 epics::pvData::Status status;
84 epics::pvData::FieldConstPtr fielddesc;
85
86 TestChannelFieldRequester() :done(false) {}
87 virtual ~TestChannelFieldRequester() {}
88
89 virtual void getDone(
90 const epics::pvData::Status& status,
91 epics::pvData::FieldConstPtr const & field) OVERRIDE FINAL
92 {
93 this->status = status;
94 fielddesc = field;
95 done = true;
96 }
97};
98
99struct TestChannelGetRequester : public epics::pvAccess::ChannelGetRequester
100{
101 POINTER_DEFINITIONS(TestChannelGetRequester);
102 DUMBREQUESTER(TestChannelGetRequester)
103
104 bool connected, done;
105 epics::pvData::Status statusConnect, statusDone;
106 epics::pvAccess::ChannelGet::shared_pointer channelGet;
107 epics::pvData::Structure::const_shared_pointer fielddesc;
108 epics::pvData::PVStructure::shared_pointer value;
109 epics::pvData::BitSet::shared_pointer changed;
110
111 TestChannelGetRequester();
112 virtual ~TestChannelGetRequester();
113
114 virtual void channelGetConnect(
115 const epics::pvData::Status& status,
116 epics::pvAccess::ChannelGet::shared_pointer const & channelGet,
117 epics::pvData::Structure::const_shared_pointer const & structure)
118 OVERRIDE FINAL;
119
120 virtual void getDone(
121 const epics::pvData::Status& status,
122 epics::pvAccess::ChannelGet::shared_pointer const & channelGet,
123 epics::pvData::PVStructure::shared_pointer const & pvStructure,
124 epics::pvData::BitSet::shared_pointer const & bitSet)
125 OVERRIDE FINAL;
126};
127
128struct TestChannelPutRequester : public epics::pvAccess::ChannelPutRequester
129{
130 POINTER_DEFINITIONS(TestChannelPutRequester);
131 DUMBREQUESTER(TestChannelPutRequester)
132
133 bool connected, doneGet, donePut;
134 epics::pvData::Status statusConnect, statusPut, statusGet;
135 epics::pvAccess::ChannelPut::shared_pointer put;
136 epics::pvData::Structure::const_shared_pointer fielddesc;
137 epics::pvData::PVStructure::shared_pointer value;
138 epics::pvData::BitSet::shared_pointer changed;
139
140 TestChannelPutRequester();
141 virtual ~TestChannelPutRequester();
142
143 virtual void channelPutConnect(
144 const epics::pvData::Status& status,
145 epics::pvAccess::ChannelPut::shared_pointer const & channelPut,
146 epics::pvData::Structure::const_shared_pointer const & structure)
147 OVERRIDE FINAL;
148
149 virtual void putDone(
150 const epics::pvData::Status& status,
151 epics::pvAccess::ChannelPut::shared_pointer const & channelPut)
152 OVERRIDE FINAL;
153
154 virtual void getDone(
155 const epics::pvData::Status& status,
156 epics::pvAccess::ChannelPut::shared_pointer const & channelPut,
157 epics::pvData::PVStructure::shared_pointer const & pvStructure,
158 epics::pvData::BitSet::shared_pointer const & bitSet)
159 OVERRIDE FINAL;
160};
161
162struct TestChannelMonitorRequester : public epics::pvData::MonitorRequester
163{
164 POINTER_DEFINITIONS(TestChannelMonitorRequester);
165 DUMBREQUESTER(TestChannelMonitorRequester)
166
167 epicsMutex lock;
168 epicsEvent wait;
169 bool connected;
170 bool unlistend;
171 size_t eventCnt;
172 epics::pvData::Status connectStatus;
173 epics::pvData::MonitorPtr mon;
174 epics::pvData::StructureConstPtr dtype;
175
176 TestChannelMonitorRequester();
177 virtual ~TestChannelMonitorRequester();
178
179 virtual void monitorConnect(epics::pvData::Status const & status,
180 epics::pvData::MonitorPtr const & monitor,
181 epics::pvData::StructureConstPtr const & structure)
182 OVERRIDE FINAL;
183 virtual void monitorEvent(epics::pvData::MonitorPtr const & monitor) OVERRIDE FINAL;
184 virtual void unlisten(epics::pvData::MonitorPtr const & monitor) OVERRIDE FINAL;
185
186 bool waitForConnect();
187 bool waitForEvent();
188};
189
190struct TestPVChannel : public BaseChannel
191{
192 POINTER_DEFINITIONS(TestPVChannel);
193 DUMBREQUESTER(TestPVChannel)
194 std::tr1::weak_ptr<TestPVChannel> weakself;
195
196 const std::tr1::shared_ptr<TestPV> pv;
197 ConnectionState state;
198
199 typedef weak_set<TestPVMonitor> monitors_t;
200 monitors_t monitors;
201
202 TestPVChannel(const std::tr1::shared_ptr<TestPV>& pv,
203 const std::tr1::shared_ptr<epics::pvAccess::ChannelRequester>& req);
204 virtual ~TestPVChannel();
205
206 virtual std::string getRemoteAddress() OVERRIDE FINAL
207 { return "localhost:1234"; }
208 virtual ConnectionState getConnectionState() OVERRIDE FINAL;
209
210 virtual void getField(
211 epics::pvAccess::GetFieldRequester::shared_pointer const & requester,
212 std::string const & subField) OVERRIDE FINAL;
213
214 virtual epics::pvData::Monitor::shared_pointer createMonitor(
215 epics::pvData::MonitorRequester::shared_pointer const & monitorRequester,
216 epics::pvData::PVStructure::shared_pointer const & pvRequest)
217 OVERRIDE FINAL;
218};
219
220struct TestPVMonitor : public epics::pvData::Monitor
221{
222 POINTER_DEFINITIONS(TestPVMonitor);
223 std::tr1::weak_ptr<TestPVMonitor> weakself;
224
225 const TestPVChannel::shared_pointer channel;
226 const epics::pvData::MonitorRequester::weak_pointer requester;
227
228 bool running;
229 bool finalize;
230 bool inoverflow;
231 bool needWakeup;
232
233 TestPVMonitor(const TestPVChannel::shared_pointer& ch,
234 const epics::pvData::MonitorRequester::shared_pointer& req,
235 size_t bsize);
236 virtual ~TestPVMonitor();
237
238 virtual void destroy();
239
240 virtual epics::pvData::Status start();
241 virtual epics::pvData::Status stop();
242 virtual epics::pvData::MonitorElementPtr poll();
243 virtual void release(epics::pvData::MonitorElementPtr const & monitorElement);
244
245 std::deque<epics::pvData::MonitorElementPtr> buffer, free;
246 epics::pvData::MonitorElementPtr overflow;
247};
248
249struct TestPV
250{
251 POINTER_DEFINITIONS(TestPV);
252 std::tr1::weak_ptr<TestPV> weakself;
253
254 const std::string name;
255 std::tr1::weak_ptr<TestProvider> const provider;
256
257 epics::pvData::PVDataCreatePtr factory;
258
259 const epics::pvData::StructureConstPtr dtype;
260 epics::pvData::PVStructurePtr value;
261
262 TestPV(const std::string& name,
263 const std::tr1::shared_ptr<TestProvider>& provider,
264 const epics::pvData::StructureConstPtr& dtype);
265 ~TestPV();
266
267 void post(bool notify = true);
268 void post(const epics::pvData::BitSet& changed, bool notify = true);
269
270 void disconnect();
271
272 mutable epicsMutex lock;
273
274 typedef weak_set<TestPVChannel> channels_t;
275 channels_t channels;
276 friend struct TestProvider;
277};
278
279struct TestProvider : public epics::pvAccess::ChannelProvider, std::tr1::enable_shared_from_this<TestProvider>
280{
281 POINTER_DEFINITIONS(TestProvider);
282
283 virtual std::string getProviderName() { return "TestProvider"; }
284
285 virtual void destroy();
286
287 virtual epics::pvAccess::ChannelFind::shared_pointer channelFind(std::string const & channelName,
288 epics::pvAccess::ChannelFindRequester::shared_pointer const & channelFindRequester);
289 virtual epics::pvAccess::ChannelFind::shared_pointer channelList(epics::pvAccess::ChannelListRequester::shared_pointer const & channelListRequester);
290 virtual epics::pvAccess::Channel::shared_pointer createChannel(std::string const & channelName,epics::pvAccess::ChannelRequester::shared_pointer const & channelRequester,
291 short priority = PRIORITY_DEFAULT);
292 virtual epics::pvAccess::Channel::shared_pointer createChannel(std::string const & channelName, epics::pvAccess::ChannelRequester::shared_pointer const & channelRequester,
293 short priority, std::string const & address);
294
295 TestProvider();
296 virtual ~TestProvider();
297
298 TestPV::shared_pointer addPV(const std::string& name, const epics::pvData::StructureConstPtr& tdef);
299
300 void dispatch();
301
302 mutable epicsMutex lock;
304 pvs_t pvs;
305
306 static void testCounts();
307};
308
309struct TestIOC {
310 bool hasInit;
311 TestIOC() : hasInit(false) {
312 testdbPrepare();
313 }
314 ~TestIOC() {
315 this->shutdown();
316 testdbCleanup();
317 }
318 void init() {
319 if(!hasInit) {
320 eltc(0);
321 testIocInitOk();
322 eltc(1);
323 hasInit = true;
324 }
325 }
326 void shutdown() {
327 if(hasInit) {
328 testIocShutdownOk();
329 hasInit = false;
330 }
331 }
332};
333
334#endif // UTILITIES_H
a std::set-ish container where entries are removed when ref. counts fall to zero
Definition weakset.h:58
An associative map where a weak_ptr to the value is stored.
Definition weakmap.h:60