pvaClientCPP  4.8.1-dev
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 
23 class ChannelPutGetRequesterImpl : public ChannelPutGetRequester
24 {
25  PvaClientPutGet::weak_pointer pvaClientPutGet;
26  PvaClient::weak_pointer pvaClient;
27 public:
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 
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  return pvaClientChannel->getRequesterName();
154 }
155 
156 void PvaClientPutGet::message(string const & message,MessageType messageType)
157 {
158  pvaClientChannel->message(message,messageType);
159 }
160 
161 void 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 
192 void 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 
219 void 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 
250 void 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 
277 void PvaClientPutGet::connect()
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 
294 void PvaClientPutGet::issueConnect()
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 
312 Status PvaClientPutGet::waitConnect()
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 
324 void PvaClientPutGet::putGet()
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 
341 void PvaClientPutGet::issuePutGet()
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 
360 Status PvaClientPutGet::waitPutGet()
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 
372 void PvaClientPutGet::getGet()
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 
389 void PvaClientPutGet::issueGetGet()
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 
407 Status PvaClientPutGet::waitGetGet()
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 
418 void PvaClientPutGet::getPut()
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 
435 void PvaClientPutGet::issueGetPut()
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 
453 Status PvaClientPutGet::waitGetPut()
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 
464 PvaClientGetDataPtr PvaClientPutGet::getGetData()
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 
479 PvaClientPutDataPtr PvaClientPutGet::getPutData()
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 
494 void 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 
505 PvaClientChannelPtr PvaClientPutGet::getPvaClientChannel()
506 {
507  return pvaClientChannel;
508 }
509 
510 }}
std::tr1::shared_ptr< PvaClient > PvaClientPtr
Definition: pvaClient.h:46
std::tr1::shared_ptr< PvaClientGetData > PvaClientGetDataPtr
Definition: pvaClient.h:50
std::tr1::shared_ptr< PvaClientChannel > PvaClientChannelPtr
Definition: pvaClient.h:59
STL namespace.
std::tr1::shared_ptr< PvaClientPutGetRequester > PvaClientPutGetRequesterPtr
Definition: pvaClient.h:76
std::tr1::shared_ptr< PvaClientPutGet > PvaClientPutGetPtr
Definition: pvaClient.h:79
std::tr1::shared_ptr< ChannelPutGetRequesterImpl > ChannelPutGetRequesterImplPtr
Definition: pvaClient.h:1265
An easy to use alternative to ChannelPutGet.
Definition: pvaClient.h:1323
std::tr1::shared_ptr< PvaClientPutData > PvaClientPutDataPtr
Definition: pvaClient.h:52