pvaClientCPP  4.8.1-dev
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 
18 using namespace epics::pvData;
19 using namespace epics::pvAccess;
20 using namespace std;
21 
22 namespace epics { namespace pvaClient {
23 
24 class ChannelPutRequesterImpl : public ChannelPutRequester
25 {
26  PvaClientPut::weak_pointer pvaClientPut;
27  PvaClient::weak_pointer pvaClient;
28 public:
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 
82 PvaClientPutPtr PvaClientPut::create(
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 
94 PvaClientPut::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 
111 PvaClientPut::~PvaClientPut()
112 {
113  if(PvaClient::getDebug()) {
114  cout<< "PvaClientPut::~PvaClientPut"
115  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
116  << endl;
117  }
118 }
119 
120 
121 void 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 
139 string PvaClientPut::getRequesterName()
140 {
141  return pvaClientChannel->getRequesterName();
142 }
143 
144 void PvaClientPut::message(string const & message,MessageType messageType)
145 {
146  pvaClientChannel->message(message,messageType);
147 }
148 
149 void 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 
177 void 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 
208 void 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 
228 void PvaClientPut::connect()
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 
245 void PvaClientPut::issueConnect()
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 
263 Status PvaClientPut::waitConnect()
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 
274 void PvaClientPut::get()
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 
291 void PvaClientPut::issueGet()
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 
309 Status PvaClientPut::waitGet()
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 
321 void PvaClientPut::put()
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 
338 void PvaClientPut::issuePut()
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 
358 Status PvaClientPut::waitPut()
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 
371 PvaClientPutDataPtr PvaClientPut::getData()
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 
383 void 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 
393 PvaClientChannelPtr PvaClientPut::getPvaClientChannel()
394 {
395  return pvaClientChannel;
396 }
397 
398 }}
std::tr1::shared_ptr< PvaClient > PvaClientPtr
Definition: pvaClient.h:46
std::tr1::shared_ptr< PvaClientChannel > PvaClientChannelPtr
Definition: pvaClient.h:59
STL namespace.
std::tr1::shared_ptr< PvaClientPut > PvaClientPutPtr
Definition: pvaClient.h:74
std::tr1::shared_ptr< PvaClientPutRequester > PvaClientPutRequesterPtr
Definition: pvaClient.h:71
An easy to use alternative to ChannelPut.
Definition: pvaClient.h:1147
std::tr1::shared_ptr< ChannelPutRequesterImpl > ChannelPutRequesterImplPtr
Definition: pvaClient.h:1101
std::tr1::shared_ptr< PvaClientPutData > PvaClientPutDataPtr
Definition: pvaClient.h:52