pvaClientCPP 4.8.1
pvaClientPut.cpp
Go to the documentation of this file.
1/* pvaClientPut.cpp */
12#include <pv/event.h>
13
14#define epicsExportSharedSymbols
15
16#include <pv/pvaClient.h>
17
18using namespace epics::pvData;
19using namespace epics::pvAccess;
20using namespace std;
21
22namespace epics { namespace pvaClient {
23
24class ChannelPutRequesterImpl : public ChannelPutRequester
25{
26 PvaClientPut::weak_pointer pvaClientPut;
27 PvaClient::weak_pointer pvaClient;
28public:
29 ChannelPutRequesterImpl(
30 PvaClientPutPtr const & pvaClientPut,
31 PvaClientPtr const &pvaClient)
32 : pvaClientPut(pvaClientPut),
33 pvaClient(pvaClient)
34 {}
35 virtual ~ChannelPutRequesterImpl() {
36 if(PvaClient::getDebug()) std::cout << "~ChannelPutRequesterImpl" << std::endl;
37 }
38
39 virtual std::string getRequesterName() {
40 PvaClientPutPtr clientPut(pvaClientPut.lock());
41 if(!clientPut) return string("clientPut is null");
42 return clientPut->getRequesterName();
43 }
44
45 virtual void message(std::string const & message, MessageType messageType) {
46 PvaClientPutPtr clientPut(pvaClientPut.lock());
47 if(!clientPut) return;
48 clientPut->message(message,messageType);
49 }
50
51 virtual void channelPutConnect(
52 const Status& status,
53 ChannelPut::shared_pointer const & channelPut,
54 Structure::const_shared_pointer const & structure)
55 {
56 PvaClientPutPtr clientPut(pvaClientPut.lock());
57 if(!clientPut) return;
58 clientPut->channelPutConnect(status,channelPut,structure);
59 }
60
61 virtual void getDone(
62 const Status& status,
63 ChannelPut::shared_pointer const & channelPut,
64 PVStructurePtr const & pvStructure,
65 BitSet::shared_pointer const & bitSet)
66 {
67 PvaClientPutPtr clientPut(pvaClientPut.lock());
68 if(!clientPut) return;
69 clientPut->getDone(status,channelPut,pvStructure,bitSet);
70 }
71
72 virtual void putDone(
73 const Status& status,
74 ChannelPut::shared_pointer const & channelPut)
75 {
76 PvaClientPutPtr clientPut(pvaClientPut.lock());
77 if(!clientPut) return;
78 clientPut->putDone(status,channelPut);
79 }
80};
81
83 PvaClientPtr const &pvaClient,
84 PvaClientChannelPtr const & pvaClientChannel,
85 PVStructurePtr const &pvRequest)
86{
87 PvaClientPutPtr clientPut(new PvaClientPut(pvaClient,pvaClientChannel,pvRequest));
88 clientPut->channelPutRequester = ChannelPutRequesterImplPtr(
89 new ChannelPutRequesterImpl(clientPut,pvaClient));
90 return clientPut;
91}
92
93
94PvaClientPut::PvaClientPut(
95 PvaClientPtr const &pvaClient,
96 PvaClientChannelPtr const & pvaClientChannel,
97 PVStructurePtr const &pvRequest)
98: pvaClient(pvaClient),
99 pvaClientChannel(pvaClientChannel),
100 pvRequest(pvRequest),
101 connectState(connectIdle),
102 putState(putIdle)
103{
104 if(PvaClient::getDebug()) {
105 cout<< "PvaClientPut::PvaClientPut"
106 << " channelName " << pvaClientChannel->getChannel()->getChannelName()
107 << endl;
108 }
109}
110
112{
113 if(PvaClient::getDebug()) {
114 cout<< "PvaClientPut::~PvaClientPut"
115 << " channelName " << pvaClientChannel->getChannel()->getChannelName()
116 << endl;
117 }
118}
119
120
121void PvaClientPut::checkConnectState()
122{
123 if(PvaClient::getDebug()) {
124 cout << "PvaClientPut::checkConnectState"
125 << " channelName " << pvaClientChannel->getChannel()->getChannelName()
126 << endl;
127 }
128 if(connectState==connectIdle){
129 connect();
130 }
131 if(connectState==connectActive){
132 string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
133 + " "
134 + channelPutConnectStatus.getMessage();
135 throw std::runtime_error(message);
136 }
137}
138
139string PvaClientPut::getRequesterName()
140{
141 return pvaClientChannel->getRequesterName();
142}
143
144void PvaClientPut::message(string const & message,MessageType messageType)
145{
146 pvaClientChannel->message(message,messageType);
147}
148
149void PvaClientPut::channelPutConnect(
150 const Status& status,
151 ChannelPut::shared_pointer const & channelPut,
152 StructureConstPtr const & structure)
153{
154 if(PvaClient::getDebug()) {
155 cout << "PvaClientPut::channelPutConnect"
156 << " channelName " << pvaClientChannel->getChannel()->getChannelName()
157 << " status.isOK " << (status.isOK() ? "true" : "false")
158 << endl;
159 }
160 {
161 Lock xx(mutex);
162 channelPutConnectStatus = status;
163 if(status.isOK()) {
164 this->channelPut = channelPut;
165 connectState = connected;
166 pvaClientData = PvaClientPutData::create(structure);
167 pvaClientData->setMessagePrefix(channelPut->getChannel()->getChannelName());
168 }
169 waitForConnect.signal();
170 }
171 PvaClientPutRequesterPtr req(pvaClientPutRequester.lock());
172 if(req) {
173 req->channelPutConnect(status,shared_from_this());
174 }
175}
176
177void PvaClientPut::getDone(
178 const Status& status,
179 ChannelPut::shared_pointer const & channelPut,
180 PVStructurePtr const & pvStructure,
181 BitSetPtr const & bitSet)
182{
183 if(PvaClient::getDebug()) {
184 cout << "PvaClientPut::getDone"
185 << " channelName " << pvaClientChannel->getChannel()->getChannelName()
186 << " status.isOK " << (status.isOK() ? "true" : "false")
187 << endl;
188 }
189 {
190 Lock xx(mutex);
191 channelGetPutStatus = status;
192 if(status.isOK()) {
193 PVStructurePtr pvs = pvaClientData->getPVStructure();
194 pvs->copyUnchecked(*pvStructure,*bitSet);
195 BitSetPtr bs = pvaClientData->getChangedBitSet();
196 bs->clear();
197 *bs |= *bitSet;
198 }
199 putState = putComplete;
200 waitForGetPut.signal();
201 }
202 PvaClientPutRequesterPtr req(pvaClientPutRequester.lock());
203 if(req) {
204 req->getDone(status,shared_from_this());
205 }
206}
207
208void PvaClientPut::putDone(
209 const Status& status,
210 ChannelPut::shared_pointer const & channelPut)
211{
212 if(PvaClient::getDebug()) {
213 cout << "PvaClientPut::putDone"
214 << " channelName " << pvaClientChannel->getChannel()->getChannelName()
215 << " status.isOK " << (status.isOK() ? "true" : "false")
216 << endl;
217 }
218 {
219 Lock xx(mutex);
220 channelGetPutStatus = status;
221 putState = putComplete;
222 waitForGetPut.signal();
223 }
224 PvaClientPutRequesterPtr req(pvaClientPutRequester.lock());
225 if(req) { req->putDone(status,shared_from_this());}
226}
227
229{
230 if(PvaClient::getDebug()) {
231 cout << "PvaClientPut::connect"
232 << " channelName " << pvaClientChannel->getChannel()->getChannelName()
233 << endl;
234 }
235 issueConnect();
236 Status status = waitConnect();
237 if(status.isOK()) return;
238 string message = string("channel ")
239 + pvaClientChannel->getChannel()->getChannelName()
240 + " PvaClientPut::connect "
241 + status.getMessage();
242 throw std::runtime_error(message);
243}
244
246{
247 if(PvaClient::getDebug()) {
248 cout << "PvaClientPut::issueConnect"
249 << " channelName " << pvaClientChannel->getChannel()->getChannelName()
250 << endl;
251 }
252 if(connectState!=connectIdle) {
253 string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
254 + " pvaClientPut already connected ";
255 throw std::runtime_error(message);
256 }
257 connectState = connectActive;
258 channelPutConnectStatus = Status(Status::STATUSTYPE_ERROR, "connect active");
259 channelPut = pvaClientChannel->getChannel()->createChannelPut(channelPutRequester,pvRequest);
260
261}
262
264{
265 if(PvaClient::getDebug()) {
266 cout << "PvaClientPut::waitConnect"
267 << " channelName " << pvaClientChannel->getChannel()->getChannelName()
268 << endl;
269 }
270 waitForConnect.wait();
271 return channelPutConnectStatus;
272}
273
275{
276 if(PvaClient::getDebug()) {
277 cout << "PvaClientPut::get"
278 << " channelName " << pvaClientChannel->getChannel()->getChannelName()
279 << endl;
280 }
281 issueGet();
282 Status status = waitGet();
283 if(status.isOK()) return;
284 string message = string("channel ")
285 + pvaClientChannel->getChannel()->getChannelName()
286 + " PvaClientPut::get "
287 + status.getMessage();
288 throw std::runtime_error(message);
289}
290
292{
293 if(PvaClient::getDebug()) {
294 cout << "PvaClientPut::issueGet"
295 << " channelName " << pvaClientChannel->getChannel()->getChannelName()
296 << endl;
297 }
298 if(connectState==connectIdle) connect();
299 if(putState==getActive || putState==putActive) {
300 string message = string("channel ")
301 + pvaClientChannel->getChannel()->getChannelName()
302 + "PvaClientPut::issueGet get or put aleady active ";
303 throw std::runtime_error(message);
304 }
305 putState = getActive;
306 channelPut->get();
307}
308
310{
311 if(PvaClient::getDebug()) {
312 cout << "PvaClientPut::waitGet"
313 << " channelName " << pvaClientChannel->getChannel()->getChannelName()
314 << endl;
315 }
316 waitForGetPut.wait();
317 putState = putComplete;
318 return channelGetPutStatus;
319}
320
322{
323 if(PvaClient::getDebug()) {
324 cout << "PvaClientPut::put"
325 << " channelName " << pvaClientChannel->getChannel()->getChannelName()
326 << endl;
327 }
328 issuePut();
329 Status status = waitPut();
330 if(status.isOK()) return;
331 string message = string("channel ")
332 + pvaClientChannel->getChannel()->getChannelName()
333 + " PvaClientPut::put "
334 + status.getMessage();
335 throw std::runtime_error(message);
336}
337
339{
340 if(PvaClient::getDebug()) {
341 cout << "PvaClientPut::issuePut"
342 << " channelName " << pvaClientChannel->getChannel()->getChannelName()
343 << " pvStructure\n" << pvaClientData->getPVStructure()
344 << " bitSet " << *pvaClientData->getChangedBitSet() << endl
345 << endl;
346 }
347 if(connectState==connectIdle) connect();
348 if(putState==getActive || putState==putActive) {
349 string message = string("channel ")
350 + pvaClientChannel->getChannel()->getChannelName()
351 + " PvaClientPut::issuePut get or put aleady active ";
352 throw std::runtime_error(message);
353 }
354 putState = putActive;
355 channelPut->put(pvaClientData->getPVStructure(),pvaClientData->getChangedBitSet());
356}
357
359{
360 if(PvaClient::getDebug()) {
361 cout << "PvaClientPut::waitPut"
362 << " channelName " << pvaClientChannel->getChannel()->getChannelName()
363 << endl;
364 }
365 waitForGetPut.wait();
366 putState = putComplete;
367 if(channelGetPutStatus.isOK()) pvaClientData->getChangedBitSet()->clear();
368 return channelGetPutStatus;
369}
370
372{
373 if(PvaClient::getDebug()) {
374 cout<< "PvaClientPut::getData"
375 << " channelName " << pvaClientChannel->getChannel()->getChannelName()
376 << endl;
377 }
378 checkConnectState();
379 if(putState==putIdle) get();
380 return pvaClientData;
381}
382
383void PvaClientPut::setRequester(PvaClientPutRequesterPtr const & pvaClientPutRequester)
384{
385 if(PvaClient::getDebug()) {
386 cout << "PvaClientPut::setRequester"
387 << " channelName " << pvaClientChannel->getChannel()->getChannelName()
388 << endl;
389 }
390 this->pvaClientPutRequester = pvaClientPutRequester;
391}
392
394{
395 return pvaClientChannel;
396}
397
398}}
static PvaClientPutDataPtr create(epics::pvData::StructureConstPtr const &structure)
An easy to use alternative to ChannelPut.
Definition pvaClient.h:1149
void connect()
Call issueConnect and then waitConnect.
void issueConnect()
Issue the channelPut connection to the channel.
PvaClientPutDataPtr getData()
Get the data/.
static PvaClientPutPtr create(PvaClientPtr const &pvaClient, PvaClientChannelPtr const &pvaClientChannel, epics::pvData::PVStructurePtr const &pvRequest)
Create a PvaClientPut.
void issueGet()
Issue a get and return immediately.
void issuePut()
Issue a put and return immediately.
epics::pvData::Status waitPut()
Wait until put completes.
PvaClientChannelPtr getPvaClientChannel()
Get the PvaClientChannel;.
void setRequester(PvaClientPutRequesterPtr const &pvaClientPutRequester)
Set a user callback.
epics::pvData::Status waitGet()
Wait until get completes.
void get()
Call issueGet and then waitGet.
void put()
Call issuePut and then waitPut. An exception is thrown if get fails.
epics::pvData::Status waitConnect()
Wait until the channelPut connection to the channel is complete.
static bool getDebug()
Is debug set?
Definition pvaClient.cpp:97
std::tr1::shared_ptr< PvaClientChannel > PvaClientChannelPtr
Definition pvaClient.h:60
std::tr1::shared_ptr< PvaClientPutRequester > PvaClientPutRequesterPtr
Definition pvaClient.h:72
std::tr1::shared_ptr< PvaClient > PvaClientPtr
Definition pvaClient.h:47
std::tr1::shared_ptr< PvaClientPutData > PvaClientPutDataPtr
Definition pvaClient.h:53
std::tr1::shared_ptr< ChannelPutRequesterImpl > ChannelPutRequesterImplPtr
Definition pvaClient.h:1102
std::tr1::shared_ptr< PvaClientPut > PvaClientPutPtr
Definition pvaClient.h:75