pvaClientCPP 4.8.1
pvaClientPutGet.cpp
Go to the documentation of this file.
1/* pvaClientPutGet.cpp */
11#include <pv/event.h>
12
13#define epicsExportSharedSymbols
14
15#include <pv/pvaClient.h>
16
17using namespace epics::pvData;
18using namespace epics::pvAccess;
19using namespace std;
20
21namespace epics { namespace pvaClient {
22
23class ChannelPutGetRequesterImpl : public ChannelPutGetRequester
24{
25 PvaClientPutGet::weak_pointer pvaClientPutGet;
26 PvaClient::weak_pointer pvaClient;
27public:
28 ChannelPutGetRequesterImpl(
29 PvaClientPutGetPtr const & pvaClientPutGet,
30 PvaClientPtr const &pvaClient)
31 : pvaClientPutGet(pvaClientPutGet),
32 pvaClient(pvaClient)
33 {}
34 virtual ~ChannelPutGetRequesterImpl() {
35 if(PvaClient::getDebug()) std::cout << "~ChannelPutGetRequesterImpl" << std::endl;
36 }
37
38 virtual std::string getRequesterName() {
39 PvaClientPutGetPtr clientPutGet(pvaClientPutGet.lock());
40 if(!clientPutGet) return string("clientPutGet is null");
41 return clientPutGet->getRequesterName();
42 }
43
44 virtual void message(std::string const & message, MessageType messageType) {
45 PvaClientPutGetPtr clientPutGet(pvaClientPutGet.lock());
46 if(!clientPutGet) return;
47 clientPutGet->message(message,messageType);
48 }
49
50 virtual void channelPutGetConnect(
51 const Status& status,
52 ChannelPutGet::shared_pointer const & channelPutGet,
53 Structure::const_shared_pointer const & putStructure,
54 Structure::const_shared_pointer const & getStructure)
55 {
56 PvaClientPutGetPtr clientPutGet(pvaClientPutGet.lock());
57 if(!clientPutGet) return;
58 clientPutGet->channelPutGetConnect(status,channelPutGet,putStructure,getStructure);
59 }
60
61 virtual void putGetDone(
62 const Status& status,
63 ChannelPutGet::shared_pointer const & channelPutGet,
64 PVStructurePtr const & getPVStructure,
65 BitSet::shared_pointer const & getBitSet)
66 {
67 PvaClientPutGetPtr clientPutGet(pvaClientPutGet.lock());
68 if(!clientPutGet) return;
69 clientPutGet->putGetDone(status,channelPutGet,getPVStructure,getBitSet);
70 }
71
72 virtual void getPutDone(
73 const Status& status,
74 ChannelPutGet::shared_pointer const & channelPutGet,
75 PVStructurePtr const & putPVStructure,
76 BitSet::shared_pointer const & putBitSet)
77 {
78 PvaClientPutGetPtr clientPutGet(pvaClientPutGet.lock());
79 if(!clientPutGet) return;
80 clientPutGet->getPutDone(status,channelPutGet,putPVStructure,putBitSet);
81 }
82
83
84 virtual void getGetDone(
85 const Status& status,
86 ChannelPutGet::shared_pointer const & channelPutGet,
87 PVStructurePtr const & getPVStructure,
88 BitSet::shared_pointer const & getBitSet)
89 {
90 PvaClientPutGetPtr clientPutGet(pvaClientPutGet.lock());
91 if(!clientPutGet) return;
92 clientPutGet->getGetDone(status,channelPutGet,getPVStructure,getBitSet);
93 }
94};
95
97 PvaClientPtr const &pvaClient,
98 PvaClientChannelPtr const & pvaClientChannel,
99 PVStructurePtr const &pvRequest)
100{
101 PvaClientPutGetPtr clientPutGet(new PvaClientPutGet(pvaClient,pvaClientChannel,pvRequest));
102 clientPutGet->channelPutGetRequester = ChannelPutGetRequesterImplPtr(
103 new ChannelPutGetRequesterImpl(clientPutGet,pvaClient));
104 return clientPutGet;
105}
106
107PvaClientPutGet::PvaClientPutGet(
108 PvaClientPtr const &pvaClient,
109 PvaClientChannelPtr const & pvaClientChannel,
110 PVStructurePtr const &pvRequest)
111: pvaClient(pvaClient),
112 pvaClientChannel(pvaClientChannel),
113 pvRequest(pvRequest),
114 connectState(connectIdle),
115 putGetState(putGetIdle)
116{
117 if(PvaClient::getDebug()) {
118 cout<< "PvaClientPutGet::PvaClientPutGet"
119 << " channelName " << pvaClientChannel->getChannel()->getChannelName()
120 << endl;
121 }
122}
123
125{
126 if(PvaClient::getDebug()) {
127 cout<< "PvaClientPutGet::~PvaClientPutGet"
128 << " channelName " << pvaClientChannel->getChannel()->getChannelName()
129 << endl;
130 }
131}
132
133void PvaClientPutGet::checkPutGetState()
134{
135 if(PvaClient::getDebug()) {
136 cout << "PvaClientPutGet::checkPutGetState"
137 << " channelName " << pvaClientChannel->getChannel()->getChannelName()
138 << endl;
139 }
140 if(connectState==connectIdle){
141 connect();
142 }
143 if(connectState==connectActive){
144 string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
145 + " "
146 + channelPutGetConnectStatus.getMessage();
147 throw std::runtime_error(message);
148 }
149}
150
151string PvaClientPutGet::getRequesterName()
152{
153 return pvaClientChannel->getRequesterName();
154}
155
156void PvaClientPutGet::message(string const & message,MessageType messageType)
157{
158 pvaClientChannel->message(message,messageType);
159}
160
161void PvaClientPutGet::channelPutGetConnect(
162 const Status& status,
163 ChannelPutGet::shared_pointer const & channelPutGet,
164 StructureConstPtr const & putStructure,
165 StructureConstPtr const & getStructure)
166{
167 if(PvaClient::getDebug()) {
168 cout << "PvaClientPutGet::channelPutGetConnect"
169 << " channelName " << pvaClientChannel->getChannel()->getChannelName()
170 << " status.isOK " << (status.isOK() ? "true" : "false")
171 << endl;
172 }
173 {
174 Lock xx(mutex);
175 channelPutGetConnectStatus = status;
176 if(status.isOK()) {
177 this->channelPutGet = channelPutGet;
178 connectState = connected;
179 pvaClientPutData = PvaClientPutData::create(putStructure);
180 pvaClientPutData->setMessagePrefix(channelPutGet->getChannel()->getChannelName());
181 pvaClientGetData = PvaClientGetData::create(getStructure);
182 pvaClientGetData->setMessagePrefix(channelPutGet->getChannel()->getChannelName());
183 }
184 waitForConnect.signal();
185 }
186 PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock());
187 if(req) {
188 req->channelPutGetConnect(status,shared_from_this());
189 }
190}
191
192void PvaClientPutGet::putGetDone(
193 const Status& status,
194 ChannelPutGet::shared_pointer const & channelPutGet,
195 PVStructurePtr const & getPVStructure,
196 BitSetPtr const & getChangedBitSet)
197{
198 if(PvaClient::getDebug()) {
199 cout << "PvaClientPutGet::putGetDone"
200 << " channelName " << pvaClientChannel->getChannel()->getChannelName()
201 << " status.isOK " << (status.isOK() ? "true" : "false")
202 << endl;
203 }
204 {
205 Lock xx(mutex);
206 channelPutGetStatus = status;
207 if(status.isOK()) {
208 pvaClientGetData->setData(getPVStructure,getChangedBitSet);
209 }
210 putGetState = putGetComplete;
211 waitForPutGet.signal();
212 }
213 PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock());
214 if(req) {
215 req->putGetDone(status,shared_from_this());
216 }
217}
218
219void PvaClientPutGet::getPutDone(
220 const Status& status,
221 ChannelPutGet::shared_pointer const & channelPutGet,
222 PVStructurePtr const & putPVStructure,
223 BitSetPtr const & putBitSet)
224{
225 if(PvaClient::getDebug()) {
226 cout << "PvaClientPutGet::getPutDone"
227 << " channelName " << pvaClientChannel->getChannel()->getChannelName()
228 << " status.isOK " << (status.isOK() ? "true" : "false")
229 << endl;
230 }
231 {
232 Lock xx(mutex);
233 channelPutGetStatus = status;
234 if(status.isOK()) {
235 PVStructurePtr pvs = pvaClientPutData->getPVStructure();
236 pvs->copyUnchecked(*putPVStructure,*putBitSet);
237 BitSetPtr bs = pvaClientPutData->getChangedBitSet();
238 bs->clear();
239 *bs |= *putBitSet;
240 }
241 putGetState = putGetComplete;
242 waitForPutGet.signal();
243 }
244 PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock());
245 if(req) {
246 req->getPutDone(status,shared_from_this());
247 }
248}
249
250void PvaClientPutGet::getGetDone(
251 const Status& status,
252 ChannelPutGet::shared_pointer const & channelPutGet,
253 PVStructurePtr const & getPVStructure,
254 BitSetPtr const & getChangedBitSet)
255{
256 if(PvaClient::getDebug()) {
257 cout << "PvaClientPutGet::getGetDone"
258 << " channelName " << pvaClientChannel->getChannel()->getChannelName()
259 << " status.isOK " << (status.isOK() ? "true" : "false")
260 << endl;
261 }
262 {
263 Lock xx(mutex);
264 channelPutGetStatus = status;
265 if(status.isOK()) {
266 pvaClientGetData->setData(getPVStructure,getChangedBitSet);
267 }
268 putGetState = putGetComplete;
269 waitForPutGet.signal();
270 }
271 PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock());
272 if(req) {
273 req->getGetDone(status,shared_from_this());
274 }
275}
276
278{
279 if(PvaClient::getDebug()) {
280 cout << "PvaClientPutGet::connect"
281 << " channelName " << pvaClientChannel->getChannel()->getChannelName()
282 << endl;
283 }
284 issueConnect();
285 Status status = waitConnect();
286 if(status.isOK()) return;
287 string message = string("channel ")
288 + pvaClientChannel->getChannel()->getChannelName()
289 + " PvaClientPutGet::connect "
290 + status.getMessage();
291 throw std::runtime_error(message);
292}
293
295{
296 if(PvaClient::getDebug()) {
297 cout << "PvaClientPutGet::issueConnect"
298 << " channelName " << pvaClientChannel->getChannel()->getChannelName()
299 << endl;
300 }
301 if(connectState!=connectIdle) {
302 string message = string("channel ")
303 + pvaClientChannel->getChannel()->getChannelName()
304 + " pvaClientPutGet already connected ";
305 throw std::runtime_error(message);
306 }
307 connectState = connectActive;
308 channelPutGetConnectStatus = Status(Status::STATUSTYPE_ERROR, "connect active");
309 channelPutGet = pvaClientChannel->getChannel()->createChannelPutGet(channelPutGetRequester,pvRequest);
310}
311
313{
314 if(PvaClient::getDebug()) {
315 cout << "PvaClientPutGet::waitConnect"
316 << " channelName " << pvaClientChannel->getChannel()->getChannelName()
317 << endl;
318 }
319 waitForConnect.wait();
320 return channelPutGetConnectStatus;
321}
322
323
325{
326 if(PvaClient::getDebug()) {
327 cout << "PvaClientPutGet::putGet"
328 << " channelName " << pvaClientChannel->getChannel()->getChannelName()
329 << endl;
330 }
331 issuePutGet();
332 Status status = waitPutGet();
333 if(status.isOK()) return;
334 string message = string("channel ")
335 + pvaClientChannel->getChannel()->getChannelName()
336 + " PvaClientPut::putGet "
337 + status.getMessage();
338 throw std::runtime_error(message);
339}
340
342{
343 if(PvaClient::getDebug()) {
344 cout << "PvaClientPutGet::issuePutGet"
345 << " channelName " << pvaClientChannel->getChannel()->getChannelName()
346 << endl;
347 }
348 if(connectState==connectIdle) connect();
349 if(putGetState==putGetActive) {
350 string message = string("channel ")
351 + pvaClientChannel->getChannel()->getChannelName()
352 + " PvaClientPutGet::issuePutGet get or put aleady active ";
353 throw std::runtime_error(message);
354 }
355 putGetState = putGetActive;
356 channelPutGet->putGet(pvaClientPutData->getPVStructure(),pvaClientPutData->getChangedBitSet());
357}
358
359
361{
362 if(PvaClient::getDebug()) {
363 cout << "PvaClientPutGet::waitPutGet"
364 << " channelName " << pvaClientChannel->getChannel()->getChannelName()
365 << endl;
366 }
367 waitForPutGet.wait();
368 if(channelPutGetStatus.isOK()) pvaClientPutData->getChangedBitSet()->clear();
369 return channelPutGetStatus;
370}
371
373{
374 if(PvaClient::getDebug()) {
375 cout << "PvaClientPutGet::getGet"
376 << " channelName " << pvaClientChannel->getChannel()->getChannelName()
377 << endl;
378 }
379 issueGetGet();
380 Status status = waitGetGet();
381 if(status.isOK()) return;
382 string message = string("channel ")
383 + pvaClientChannel->getChannel()->getChannelName()
384 + " PvaClientPut::getGet "
385 + status.getMessage();
386 throw std::runtime_error(message);
387}
388
390{
391 if(PvaClient::getDebug()) {
392 cout << "PvaClientPutGet::issueGetGet"
393 << " channelName " << pvaClientChannel->getChannel()->getChannelName()
394 << endl;
395 }
396 if(connectState==connectIdle) connect();
397 if(putGetState==putGetActive) {
398 string message = string("channel ")
399 + pvaClientChannel->getChannel()->getChannelName()
400 + " PvaClientPutGet::issueGetGet get or put aleady active ";
401 throw std::runtime_error(message);
402 }
403 putGetState = putGetActive;
404 channelPutGet->getGet();
405}
406
408{
409 if(PvaClient::getDebug()) {
410 cout << "PvaClientPutGet::waitGetGet"
411 << " channelName " << pvaClientChannel->getChannel()->getChannelName()
412 << endl;
413 }
414 waitForPutGet.wait();
415 return channelPutGetStatus;
416}
417
419{
420 if(PvaClient::getDebug()) {
421 cout << "PvaClientPutGet::getGetPut"
422 << " channelName " << pvaClientChannel->getChannel()->getChannelName()
423 << endl;
424 }
425 issueGetPut();
426 Status status = waitGetPut();
427 if(status.isOK()) return;
428 string message = string("channel ")
429 + pvaClientChannel->getChannel()->getChannelName()
430 + " PvaClientPut::getPut "
431 + status.getMessage();
432 throw std::runtime_error(message);
433}
434
436{
437 if(PvaClient::getDebug()) {
438 cout << "PvaClientPutGet::issueGetPut"
439 << " channelName " << pvaClientChannel->getChannel()->getChannelName()
440 << endl;
441 }
442 if(connectState==connectIdle) connect();
443 if(putGetState==putGetActive) {
444 string message = string("channel ")
445 + pvaClientChannel->getChannel()->getChannelName()
446 + " PvaClientPutGet::issueGetPut get or put aleady active ";
447 throw std::runtime_error(message);
448 }
449 putGetState = putGetActive;
450 channelPutGet->getPut();
451}
452
454{
455 if(PvaClient::getDebug()) {
456 cout << "PvaClientPutGet::waitGetPut"
457 << " channelName " << pvaClientChannel->getChannel()->getChannelName()
458 << endl;
459 }
460 waitForPutGet.wait();
461 return channelPutGetStatus;
462}
463
465{
466 if(PvaClient::getDebug()) {
467 cout<< "PvaClientPutGet::getGetData"
468 << " channelName " << pvaClientChannel->getChannel()->getChannelName()
469 << endl;
470 }
471 checkPutGetState();
472 if(putGetState==putGetIdle){
473 getGet();
474 getPut();
475 }
476 return pvaClientGetData;
477}
478
480{
481 if(PvaClient::getDebug()) {
482 cout<< "PvaClientPutGet::getPutData"
483 << " channelName " << pvaClientChannel->getChannel()->getChannelName()
484 << endl;
485 }
486 checkPutGetState();
487 if(putGetState==putGetIdle){
488 getGet();
489 getPut();
490 }
491 return pvaClientPutData;
492}
493
494void PvaClientPutGet::setRequester(PvaClientPutGetRequesterPtr const & pvaClientPutGetRequester)
495{
496 if(PvaClient::getDebug()) {
497 cout << "PvaClientPutGet::setRequester"
498 << " channelName " << pvaClientChannel->getChannel()->getChannelName()
499 << endl;
500 }
501 this->pvaClientPutGetRequester = pvaClientPutGetRequester;
502}
503
504
506{
507 return pvaClientChannel;
508}
509
510}}
static PvaClientGetDataPtr create(epics::pvData::StructureConstPtr const &structure)
Factory method for creating an instance of PvaClientGetData.
static PvaClientPutDataPtr create(epics::pvData::StructureConstPtr const &structure)
An easy to use alternative to ChannelPutGet.
Definition pvaClient.h:1325
PvaClientChannelPtr getPvaClientChannel()
Get the PvaClientChannel;.
epics::pvData::Status waitGetGet()
Wait until getGet completes.
void issueGetPut()
Issue a getPut and return immediately.
void setRequester(PvaClientPutGetRequesterPtr const &pvaClientPutGetRequester)
Set a user callback.
epics::pvData::Status waitPutGet()
Wait until putGet completes.
void getGet()
Call issueGet and then waitGetGet. An exception is thrown if get fails.
static PvaClientPutGetPtr create(PvaClientPtr const &pvaClient, PvaClientChannelPtr const &pvaClientChannel, epics::pvData::PVStructurePtr const &pvRequest)
Create a PvaClientPutGet.
void putGet()
Call issuePutGet and then waitPutGet.
PvaClientPutDataPtr getPutData()
Get the put data.
void connect()
Call issueConnect and then waitConnect.
PvaClientGetDataPtr getGetData()
Get the get data.
void getPut()
Call issuePut and then waitGetPut.
epics::pvData::Status waitGetPut()
Wait until getPut completes.
void issuePutGet()
Issue a putGet and return immediately.
epics::pvData::Status waitConnect()
Wait until the channelPutGet connection to the channel is complete.
void issueGetGet()
Issue a getGet and return immediately.
void issueConnect()
Issue the channelPutGet connection to the channel.
static bool getDebug()
Is debug set?
Definition pvaClient.cpp:97
std::tr1::shared_ptr< ChannelPutGetRequesterImpl > ChannelPutGetRequesterImplPtr
Definition pvaClient.h:1266
std::tr1::shared_ptr< PvaClientPutGet > PvaClientPutGetPtr
Definition pvaClient.h:80
std::tr1::shared_ptr< PvaClientChannel > PvaClientChannelPtr
Definition pvaClient.h:60
std::tr1::shared_ptr< PvaClientGetData > PvaClientGetDataPtr
Definition pvaClient.h:51
std::tr1::shared_ptr< PvaClient > PvaClientPtr
Definition pvaClient.h:47
std::tr1::shared_ptr< PvaClientPutData > PvaClientPutDataPtr
Definition pvaClient.h:53
std::tr1::shared_ptr< PvaClientPutGetRequester > PvaClientPutGetRequesterPtr
Definition pvaClient.h:77