This is Unofficial EPICS BASE Doxygen Site
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 
17 using namespace epics::pvData;
18 using namespace epics::pvAccess;
19 using namespace std;
20 
21 namespace epics { namespace pvaClient {
22 
24 {
25  PvaClientPutGet::weak_pointer pvaClientPutGet;
26  PvaClient::weak_pointer pvaClient;
27 public:
29  PvaClientPutGetPtr const & pvaClientPutGet,
30  PvaClientPtr const &pvaClient)
31  : pvaClientPutGet(pvaClientPutGet),
32  pvaClient(pvaClient)
33  {}
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, epics::pvData::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 
96 PvaClientPutGetPtr PvaClientPutGet::create(
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 
107 PvaClientPutGet::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 
124 PvaClientPutGet::~PvaClientPutGet()
125 {
126  if(PvaClient::getDebug()) {
127  cout<< "PvaClientPutGet::~PvaClientPutGet"
128  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
129  << endl;
130  }
131 }
132 
133 void 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 
151 string PvaClientPutGet::getRequesterName()
152 {
153  PvaClientPtr yyy = pvaClient.lock();
154  if(!yyy) return string("PvaClientPutGet::getRequesterName() PvaClient isDestroyed");
155  return yyy->getRequesterName();
156 }
157 
158 void PvaClientPutGet::message(string const & message,MessageType messageType)
159 {
160  PvaClientPtr yyy = pvaClient.lock();
161  if(!yyy) return;
162  yyy->message(message, messageType);
163 }
164 
165 void PvaClientPutGet::channelPutGetConnect(
166  const Status& status,
167  ChannelPutGet::shared_pointer const & channelPutGet,
168  StructureConstPtr const & putStructure,
169  StructureConstPtr const & getStructure)
170 {
171  if(PvaClient::getDebug()) {
172  cout << "PvaClientPutGet::channelPutGetConnect"
173  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
174  << " status.isOK " << (status.isOK() ? "true" : "false")
175  << endl;
176  }
177  {
178  Lock xx(mutex);
179  this->channelPutGet = channelPutGet;
180  if(status.isOK()) {
181  channelPutGetConnectStatus = status;
182  connectState = connected;
183  pvaClientPutData = PvaClientPutData::create(putStructure);
184  pvaClientPutData->setMessagePrefix(channelPutGet->getChannel()->getChannelName());
185  pvaClientGetData = PvaClientGetData::create(getStructure);
186  pvaClientGetData->setMessagePrefix(channelPutGet->getChannel()->getChannelName());
187 
188  } else {
189  stringstream ss;
190  ss << pvRequest;
191  string message = string("\nPvaClientPutGet::channelPutGetConnect)")
192  + "\npvRequest\n" + ss.str()
193  + "\nerror\n" + status.getMessage();
194  channelPutGetConnectStatus = Status(Status::STATUSTYPE_ERROR,message);
195  }
196  }
197  PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock());
198  if(req) {
199  req->channelPutGetConnect(status,shared_from_this());
200  }
201  waitForConnect.signal();
202 
203 }
204 
205 void PvaClientPutGet::putGetDone(
206  const Status& status,
207  ChannelPutGet::shared_pointer const & channelPutGet,
208  PVStructurePtr const & getPVStructure,
209  BitSetPtr const & getChangedBitSet)
210 {
211  if(PvaClient::getDebug()) {
212  cout << "PvaClientPutGet::putGetDone"
213  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
214  << " status.isOK " << (status.isOK() ? "true" : "false")
215  << endl;
216  }
217  {
218  Lock xx(mutex);
219  channelPutGetStatus = status;
220  putGetState = putGetComplete;
221  if(status.isOK()) {
222  pvaClientGetData->setData(getPVStructure,getChangedBitSet);
223  }
224  }
225  PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock());
226  if(req) {
227  req->putGetDone(status,shared_from_this());
228  }
229  waitForPutGet.signal();
230 }
231 
232 void PvaClientPutGet::getPutDone(
233  const Status& status,
234  ChannelPutGet::shared_pointer const & channelPutGet,
235  PVStructurePtr const & putPVStructure,
236  BitSetPtr const & putBitSet)
237 {
238  if(PvaClient::getDebug()) {
239  cout << "PvaClientPutGet::getPutDone"
240  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
241  << " status.isOK " << (status.isOK() ? "true" : "false")
242  << endl;
243  }
244  {
245  Lock xx(mutex);
246  channelPutGetStatus = status;
247  putGetState = putGetComplete;
248  if(status.isOK()) {
249  PVStructurePtr pvs = pvaClientPutData->getPVStructure();
250  pvs->copyUnchecked(*putPVStructure,*putBitSet);
251  BitSetPtr bs = pvaClientPutData->getChangedBitSet();
252  bs->clear();
253  *bs |= *putBitSet;
254  }
255  }
256  PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock());
257  if(req) {
258  req->getPutDone(status,shared_from_this());
259  }
260  waitForPutGet.signal();
261 }
262 
263 void PvaClientPutGet::getGetDone(
264  const Status& status,
265  ChannelPutGet::shared_pointer const & channelPutGet,
266  PVStructurePtr const & getPVStructure,
267  BitSetPtr const & getChangedBitSet)
268 {
269  if(PvaClient::getDebug()) {
270  cout << "PvaClientPutGet::getGetDone"
271  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
272  << " status.isOK " << (status.isOK() ? "true" : "false")
273  << endl;
274  }
275  {
276  Lock xx(mutex);
277  channelPutGetStatus = status;
278  putGetState = putGetComplete;
279  if(status.isOK()) {
280  pvaClientGetData->setData(getPVStructure,getChangedBitSet);
281  }
282  }
283  PvaClientPutGetRequesterPtr req(pvaClientPutGetRequester.lock());
284  if(req) {
285  req->getGetDone(status,shared_from_this());
286  }
287  waitForPutGet.signal();
288 }
289 
290 void PvaClientPutGet::connect()
291 {
292  if(PvaClient::getDebug()) {
293  cout << "PvaClientPutGet::connect"
294  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
295  << endl;
296  }
297  issueConnect();
298  Status status = waitConnect();
299  if(status.isOK()) return;
300  string message = string("channel ")
301  + pvaClientChannel->getChannel()->getChannelName()
302  + " PvaClientPutGet::connect "
303  + status.getMessage();
304  throw std::runtime_error(message);
305 }
306 
307 void PvaClientPutGet::issueConnect()
308 {
309  if(PvaClient::getDebug()) {
310  cout << "PvaClientPutGet::issueConnect"
311  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
312  << endl;
313  }
314  if(connectState!=connectIdle) {
315  string message = string("channel ")
316  + pvaClientChannel->getChannel()->getChannelName()
317  + " pvaClientPutGet already connected ";
318  throw std::runtime_error(message);
319  }
320  connectState = connectActive;
321  channelPutGetConnectStatus = Status(Status::STATUSTYPE_ERROR, "connect active");
322  channelPutGet = pvaClientChannel->getChannel()->createChannelPutGet(channelPutGetRequester,pvRequest);
323 }
324 
325 Status PvaClientPutGet::waitConnect()
326 {
327  if(PvaClient::getDebug()) {
328  cout << "PvaClientPutGet::waitConnect"
329  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
330  << endl;
331  }
332  {
333  Lock xx(mutex);
334  if(connectState==connected) {
335  if(!channelPutGetConnectStatus.isOK()) connectState = connectIdle;
336  return channelPutGetConnectStatus;
337  }
338  if(connectState!=connectActive) {
339  string message = string("channel ")
340  + pvaClientChannel->getChannel()->getChannelName()
341  + " PvaClientPutGet::waitConnect illegal connect state ";
342  throw std::runtime_error(message);
343  }
344  }
345  waitForConnect.wait();
346  if(!channelPutGetConnectStatus.isOK()) connectState = connectIdle;
347  return channelPutGetConnectStatus;
348 }
349 
350 
351 void PvaClientPutGet::putGet()
352 {
353  if(PvaClient::getDebug()) {
354  cout << "PvaClientPutGet::putGet"
355  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
356  << endl;
357  }
358  issuePutGet();
359  Status status = waitPutGet();
360  if(status.isOK()) return;
361  string message = string("channel ")
362  + pvaClientChannel->getChannel()->getChannelName()
363  + " PvaClientPut::putGet "
364  + status.getMessage();
365  throw std::runtime_error(message);
366 }
367 
368 void PvaClientPutGet::issuePutGet()
369 {
370  if(PvaClient::getDebug()) {
371  cout << "PvaClientPutGet::issuePutGet"
372  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
373  << endl;
374  }
375  if(connectState==connectIdle) connect();
376  if(putGetState==putGetActive) {
377  string message = string("channel ")
378  + pvaClientChannel->getChannel()->getChannelName()
379  + " PvaClientPutGet::issuePutGet get or put aleady active ";
380  throw std::runtime_error(message);
381  }
382  putGetState = putGetActive;
383  channelPutGet->putGet(pvaClientPutData->getPVStructure(),pvaClientPutData->getChangedBitSet());
384 }
385 
386 
387 Status PvaClientPutGet::waitPutGet()
388 {
389  if(PvaClient::getDebug()) {
390  cout << "PvaClientPutGet::waitPutGet"
391  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
392  << endl;
393  }
394  if(putGetState==putGetComplete) return channelPutGetStatus;
395  if(putGetState!=putGetActive){
396  string message = string("channel ")
397  + pvaClientChannel->getChannel()->getChannelName()
398  + " PvaClientPutGet::waitPutGet get or put aleady active ";
399  throw std::runtime_error(message);
400  }
401  waitForPutGet.wait();
402  if(channelPutGetStatus.isOK()) pvaClientPutData->getChangedBitSet()->clear();
403  return channelPutGetStatus;
404 }
405 
406 void PvaClientPutGet::getGet()
407 {
408  if(PvaClient::getDebug()) {
409  cout << "PvaClientPutGet::getGet"
410  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
411  << endl;
412  }
413  issueGetGet();
414  Status status = waitGetGet();
415  if(status.isOK()) return;
416  string message = string("channel ")
417  + pvaClientChannel->getChannel()->getChannelName()
418  + " PvaClientPut::getGet "
419  + status.getMessage();
420  throw std::runtime_error(message);
421 }
422 
423 void PvaClientPutGet::issueGetGet()
424 {
425  if(PvaClient::getDebug()) {
426  cout << "PvaClientPutGet::issueGetGet"
427  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
428  << endl;
429  }
430  if(connectState==connectIdle) connect();
431  if(putGetState==putGetActive) {
432  string message = string("channel ")
433  + pvaClientChannel->getChannel()->getChannelName()
434  + " PvaClientPutGet::issueGetGet get or put aleady active ";
435  throw std::runtime_error(message);
436  }
437  putGetState = putGetActive;
438  channelPutGet->getGet();
439 }
440 
441 Status PvaClientPutGet::waitGetGet()
442 {
443  if(PvaClient::getDebug()) {
444  cout << "PvaClientPutGet::waitGetGet"
445  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
446  << endl;
447  }
448  if(putGetState==putGetComplete) return channelPutGetStatus;
449  if(putGetState!=putGetActive){
450  string message = string("channel ")
451  + pvaClientChannel->getChannel()->getChannelName()
452  + " PvaClientPutGet::waitGetGet get or put aleady active ";
453  throw std::runtime_error(message);
454  }
455  waitForPutGet.wait();
456  return channelPutGetStatus;
457 }
458 
459 void PvaClientPutGet::getPut()
460 {
461  if(PvaClient::getDebug()) {
462  cout << "PvaClientPutGet::getGetPut"
463  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
464  << endl;
465  }
466  issueGetPut();
467  Status status = waitGetPut();
468  if(status.isOK()) return;
469  string message = string("channel ")
470  + pvaClientChannel->getChannel()->getChannelName()
471  + " PvaClientPut::getPut "
472  + status.getMessage();
473  throw std::runtime_error(message);
474 }
475 
476 void PvaClientPutGet::issueGetPut()
477 {
478  if(PvaClient::getDebug()) {
479  cout << "PvaClientPutGet::issueGetPut"
480  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
481  << endl;
482  }
483  if(connectState==connectIdle) connect();
484  if(putGetState==putGetActive) {
485  string message = string("channel ")
486  + pvaClientChannel->getChannel()->getChannelName()
487  + " PvaClientPutGet::issueGetPut get or put aleady active ";
488  throw std::runtime_error(message);
489  }
490  putGetState = putGetActive;
491  channelPutGet->getPut();
492 }
493 
494 Status PvaClientPutGet::waitGetPut()
495 {
496  if(PvaClient::getDebug()) {
497  cout << "PvaClientPutGet::waitGetPut"
498  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
499  << endl;
500  }
501  if(putGetState==putGetComplete) return channelPutGetStatus;
502  if(putGetState!=putGetActive){
503  string message = string("channel ")
504  + pvaClientChannel->getChannel()->getChannelName()
505  + " PvaClientPutGet::waitGetPut get or put aleady active ";
506  throw std::runtime_error(message);
507  }
508  waitForPutGet.wait();
509  return channelPutGetStatus;
510 }
511 
512 PvaClientGetDataPtr PvaClientPutGet::getGetData()
513 {
514  if(PvaClient::getDebug()) {
515  cout<< "PvaClientPutGet::getGetData"
516  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
517  << endl;
518  }
519  checkPutGetState();
520  if(putGetState==putGetIdle){
521  getGet();
522  getPut();
523  }
524  return pvaClientGetData;
525 }
526 
527 PvaClientPutDataPtr PvaClientPutGet::getPutData()
528 {
529  if(PvaClient::getDebug()) {
530  cout<< "PvaClientPutGet::getPutData"
531  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
532  << endl;
533  }
534  checkPutGetState();
535  if(putGetState==putGetIdle){
536  getGet();
537  getPut();
538  }
539  return pvaClientPutData;
540 }
541 
542 void PvaClientPutGet::setRequester(PvaClientPutGetRequesterPtr const & pvaClientPutGetRequester)
543 {
544  if(PvaClient::getDebug()) {
545  cout << "PvaClientPutGet::setRequester"
546  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
547  << endl;
548  }
549  this->pvaClientPutGetRequester = pvaClientPutGetRequester;
550 }
551 
552 
553 PvaClientChannelPtr PvaClientPutGet::getPvaClientChannel()
554 {
555  return pvaClientChannel;
556 }
557 
558 }}
std::tr1::shared_ptr< PvaClient > PvaClientPtr
Definition: pvaClient.h:46
pvd::Status status
std::tr1::shared_ptr< PvaClientGetData > PvaClientGetDataPtr
Definition: pvaClient.h:50
std::tr1::shared_ptr< PvaClientChannel > PvaClientChannelPtr
Definition: pvaClient.h:59
virtual void getGetDone(const Status &status, ChannelPutGet::shared_pointer const &channelPutGet, PVStructurePtr const &getPVStructure, BitSet::shared_pointer const &getBitSet)
Definition: memory.hpp:41
TODO only here because of the Lockable.
Definition: ntaggregate.cpp:16
std::tr1::shared_ptr< const Structure > StructureConstPtr
Definition: pvIntrospect.h:162
A lock for multithreading.
Definition: lock.h:36
const std::string & getMessage() const
Definition: status.h:80
virtual void channelPutGetConnect(const Status &status, ChannelPutGet::shared_pointer const &channelPutGet, Structure::const_shared_pointer const &putStructure, Structure::const_shared_pointer const &getStructure)
Holds all PVA related.
Definition: pvif.h:34
pvData
Definition: monitor.h:428
epicsMutex mutex
Definition: pvAccess.cpp:71
virtual void putGetDone(const Status &status, ChannelPutGet::shared_pointer const &channelPutGet, PVStructurePtr const &getPVStructure, BitSet::shared_pointer const &getBitSet)
std::tr1::shared_ptr< PvaClientPutGetRequester > PvaClientPutGetRequesterPtr
Definition: pvaClient.h:78
virtual void message(std::string const &message, epics::pvData::MessageType messageType)
std::tr1::shared_ptr< PVStructure > PVStructurePtr
Definition: pvData.h:87
std::tr1::shared_ptr< PvaClientPutGet > PvaClientPutGetPtr
Definition: pvaClient.h:81
std::tr1::shared_ptr< BitSet > BitSetPtr
Definition: bitSet.h:26
bool isOK() const
Definition: status.h:95
std::tr1::shared_ptr< ChannelPutGetRequesterImpl > ChannelPutGetRequesterImplPtr
Definition: pvaClient.h:1309
An easy to use alternative to ChannelPutGet.
Definition: pvaClient.h:1369
virtual void getPutDone(const Status &status, ChannelPutGet::shared_pointer const &channelPutGet, PVStructurePtr const &putPVStructure, BitSet::shared_pointer const &putBitSet)
ChannelPutGetRequesterImpl(PvaClientPutGetPtr const &pvaClientPutGet, PvaClientPtr const &pvaClient)
std::tr1::shared_ptr< PvaClientPutData > PvaClientPutDataPtr
Definition: pvaClient.h:52