This is Unofficial EPICS BASE Doxygen Site
pvaClientGet.cpp
Go to the documentation of this file.
1 /* pvaClientGet.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 
25 {
26  PvaClientGet::weak_pointer pvaClientGet;
27  PvaClient::weak_pointer pvaClient;
28 public:
30  PvaClientGetPtr const & pvaClientGet,
31  PvaClientPtr const &pvaClient)
32  : pvaClientGet(pvaClientGet),
33  pvaClient(pvaClient)
34  {}
36  if(PvaClient::getDebug()) std::cout << "~ChannelGetRequesterImpl" << std::endl;
37  }
38 
39  virtual std::string getRequesterName() {
40  PvaClientGetPtr clientGet(pvaClientGet.lock());
41  if(!clientGet) return string("clientGet is null");
42  return clientGet->getRequesterName();
43  }
44 
45  virtual void message(std::string const & message, epics::pvData::MessageType messageType) {
46  PvaClientGetPtr clientGet(pvaClientGet.lock());
47  if(!clientGet) return;
48  clientGet->message(message,messageType);
49  }
50 
51  virtual void channelGetConnect(
52  const Status& status,
53  ChannelGet::shared_pointer const & channelGet,
54  Structure::const_shared_pointer const & structure)
55  {
56  PvaClientGetPtr clientGet(pvaClientGet.lock());
57  if(!clientGet) return;
58  clientGet->channelGetConnect(status,channelGet,structure);
59  }
60 
61  virtual void getDone(
62  const Status& status,
63  ChannelGet::shared_pointer const & channelGet,
64  PVStructurePtr const & pvStructure,
65  BitSet::shared_pointer const & bitSet)
66  {
67  PvaClientGetPtr clientGet(pvaClientGet.lock());
68  if(!clientGet) return;
69  clientGet->getDone(status,channelGet,pvStructure,bitSet);
70  }
71 };
72 
73 PvaClientGetPtr PvaClientGet::create(
74  PvaClientPtr const &pvaClient,
75  PvaClientChannelPtr const & pvaClientChannel,
76  PVStructurePtr const &pvRequest)
77 {
78  if(PvaClient::getDebug()) {
79  cout<< "PvaClientGet::create(pvaClient,channelName,pvRequest)\n"
80  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
81  << " pvRequest " << pvRequest
82  << endl;
83  }
84  PvaClientGetPtr clientGet(new PvaClientGet(pvaClient,pvaClientChannel,pvRequest));
85  clientGet->channelGetRequester = ChannelGetRequesterImplPtr(
86  new ChannelGetRequesterImpl(clientGet,pvaClient));
87  return clientGet;
88 }
89 
90 PvaClientGet::PvaClientGet(
91  PvaClientPtr const &pvaClient,
92  PvaClientChannelPtr const & pvaClientChannel,
93  PVStructurePtr const &pvRequest)
94 : pvaClient(pvaClient),
95  pvaClientChannel(pvaClientChannel),
96  pvRequest(pvRequest),
97  connectState(connectIdle),
98  getState(getIdle)
99 {
100  if(PvaClient::getDebug()) {
101  cout << "PvaClientGet::PvaClientGet channelName "
102  << pvaClientChannel->getChannel()->getChannelName() << "\n";
103  }
104 }
105 
106 PvaClientGet::~PvaClientGet()
107 {
108  if(PvaClient::getDebug()) {
109  cout<< "PvaClientGet::~PvaClientGet channelName "
110  << pvaClientChannel->getChannel()->getChannelName() << "\n";
111  }
112 }
113 
114 
115 void PvaClientGet::checkConnectState()
116 {
117  if(PvaClient::getDebug()) {
118  cout << "PvaClientGet::checkConnectState channelName "
119  << pvaClientChannel->getChannel()->getChannelName() << "\n";
120  }
121  if(!pvaClientChannel->getChannel()->isConnected()) {
122  string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
123  + " PvaClientGet::checkConnectState channel not connected ";
124  throw std::runtime_error(message);
125  }
126  if(connectState==connectIdle) {
127  connect();
128  }
129  if(connectState==connectActive){
130  string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
131  + " "
132  + channelGetConnectStatus.getMessage();
133  throw std::runtime_error(message);
134  }
135 }
136 
137 // from ChannelGetRequester
138 string PvaClientGet::getRequesterName()
139 {
140  PvaClientPtr yyy = pvaClient.lock();
141  if(!yyy) return string("PvaClientGet::getRequesterName PvaClient isDestroyed");
142  return yyy->getRequesterName();
143 }
144 
145 void PvaClientGet::message(string const & message,MessageType messageType)
146 {
147  PvaClientPtr yyy = pvaClient.lock();
148  if(!yyy) return;
149  yyy->message(message, messageType);
150 }
151 
152 void PvaClientGet::channelGetConnect(
153  const Status& status,
154  ChannelGet::shared_pointer const & channelGet,
156 {
157  if(PvaClient::getDebug()) {
158  cout << "PvaClientGet::channelGetConnect channelName "
159  << pvaClientChannel->getChannel()->getChannelName()
160  << " status.isOK " << (status.isOK() ? "true" : "false")
161  << "\n";
162  }
163  {
164  Lock xx(mutex);
165  this->channelGet = channelGet;
166  if(status.isOK()) {
167  channelGetConnectStatus = status;
168  connectState = connected;
169  pvaClientData = PvaClientGetData::create(structure);
170  pvaClientData->setMessagePrefix(channelGet->getChannel()->getChannelName());
171  } else {
172  stringstream ss;
173  ss << pvRequest;
174  string message = string("\nPvaClientGet::channelGetConnect)")
175  + "\npvRequest\n" + ss.str()
176  + "\nerror\n" + status.getMessage();
177  channelGetConnectStatus = Status(Status::STATUSTYPE_ERROR,message);
178  }
179  }
180  PvaClientGetRequesterPtr req(pvaClientGetRequester.lock());
181  if(req) {
182  req->channelGetConnect(status,shared_from_this());
183  }
184  waitForConnect.signal();
185 
186 }
187 
188 void PvaClientGet::getDone(
189  const Status& status,
190  ChannelGet::shared_pointer const & channelGet,
191  PVStructurePtr const & pvStructure,
192  BitSetPtr const & bitSet)
193 {
194  if(PvaClient::getDebug()) {
195  cout << "PvaClientGet::getDone channelName "
196  << pvaClientChannel->getChannel()->getChannelName()
197  << " status.isOK " << (status.isOK() ? "true" : "false")
198  << "\n";
199  }
200  {
201  Lock xx(mutex);
202  channelGetStatus = status;
203  getState = getComplete;
204  if(status.isOK()) {
205  pvaClientData->setData(pvStructure,bitSet);
206  }
207  }
208  PvaClientGetRequesterPtr req(pvaClientGetRequester.lock());
209  if(req) {
210  req->getDone(status,shared_from_this());
211  }
212  waitForGet.signal();
213 }
214 
215 void PvaClientGet::connect()
216 {
217  if(PvaClient::getDebug()) {
218  cout << "PvaClientGet::connect channelName "
219  << pvaClientChannel->getChannel()->getChannelName() << "\n";
220  }
221  issueConnect();
222  Status status = waitConnect();
223  if(status.isOK()) return;
224  string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
225  + " PvaClientGet::connect " + status.getMessage();
226  throw std::runtime_error(message);
227 }
228 
229 void PvaClientGet::issueConnect()
230 {
231  if(PvaClient::getDebug()) {
232  cout << "PvaClientGet::issueConnect channelName "
233  << pvaClientChannel->getChannel()->getChannelName() << "\n";
234  }
235  if(connectState!=connectIdle) {
236  string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
237  + " pvaClientGet already connected ";
238  throw std::runtime_error(message);
239  }
240  connectState = connectActive;
241  channelGetConnectStatus = Status(Status::STATUSTYPE_ERROR, "connect active");
242  channelGet = pvaClientChannel->getChannel()->createChannelGet(channelGetRequester,pvRequest);
243 }
244 
245 Status PvaClientGet::waitConnect()
246 {
247  if(PvaClient::getDebug()) {
248  cout << "PvaClientGet::waitConnect channelName "
249  << pvaClientChannel->getChannel()->getChannelName() << "\n";
250  }
251  {
252  Lock xx(mutex);
253  if(connectState==connected) {
254  if(!channelGetConnectStatus.isOK()) connectState = connectIdle;
255  return channelGetConnectStatus;
256  }
257  if(connectState!=connectActive) {
258  string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
259  + " PvaClientGet::waitConnect illegal connect state ";
260  throw std::runtime_error(message);
261  }
262  }
263  waitForConnect.wait();
264  if(!channelGetConnectStatus.isOK()) connectState = connectIdle;
265  return channelGetConnectStatus;
266 }
267 
269 {
270  if(PvaClient::getDebug()) {
271  cout << "PvaClientGet::get channelName "
272  << pvaClientChannel->getChannel()->getChannelName() << "\n";
273  }
274  issueGet();
275  Status status = waitGet();
276  if(status.isOK()) return;
277  string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
278  + " PvaClientGet::get " + status.getMessage();
279  throw std::runtime_error(message);
280 }
281 
282 void PvaClientGet::issueGet()
283 {
284  if(PvaClient::getDebug()) {
285  cout << "PvaClientGet::issueGet channelName "
286  << pvaClientChannel->getChannel()->getChannelName() << "\n";
287  }
288  if(connectState==connectIdle) connect();
289  if(getState==getActive) {
290  string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
291  + " PvaClientGet::issueGet get aleady active ";
292  throw std::runtime_error(message);
293  }
294  getState = getActive;
295  channelGet->get();
296 }
297 
298 Status PvaClientGet::waitGet()
299 {
300  if(PvaClient::getDebug()) {
301  cout << "PvaClientGet::waitGet channelName "
302  << pvaClientChannel->getChannel()->getChannelName() << "\n";
303  }
304  {
305  Lock xx(mutex);
306  if(getState==getComplete) {
307  getState = getIdle;
308  return channelGetStatus;
309  }
310  if(getState!=getActive){
311  string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
312  + " PvaClientGet::waitGet llegal get state";
313  throw std::runtime_error(message);
314  }
315  }
316  waitForGet.wait();
317  getState = getComplete;
318  return channelGetStatus;
319 }
320 PvaClientGetDataPtr PvaClientGet::getData()
321 {
322  if(PvaClient::getDebug()) {
323  cout<< "PvaClientGet::getData channelName "
324  << pvaClientChannel->getChannel()->getChannelName() << "\n";
325  }
326  checkConnectState();
327  if(getState==getIdle) get();
328  return pvaClientData;
329 }
330 
331 void PvaClientGet::setRequester(PvaClientGetRequesterPtr const & pvaClientGetRequester)
332 {
333  if(PvaClient::getDebug()) {
334  cout << "PvaClientGet::setRequester channelName "
335  << pvaClientChannel->getChannel()->getChannelName() << "\n";
336  }
337  this->pvaClientGetRequester = pvaClientGetRequester;
338 }
339 
340 PvaClientChannelPtr PvaClientGet::getPvaClientChannel()
341 {
342  return pvaClientChannel;
343 }
344 
345 
346 
347 }}
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
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
std::tr1::shared_ptr< ChannelGetRequesterImpl > ChannelGetRequesterImplPtr
Definition: pvaClient.h:998
const std::string & getMessage() const
Definition: status.h:80
Holds all PVA related.
Definition: pvif.h:34
pvData
Definition: monitor.h:428
epicsMutex mutex
Definition: pvAccess.cpp:71
std::tr1::shared_ptr< PvaClientGet > PvaClientGetPtr
Definition: pvaClient.h:71
std::tr1::shared_ptr< PVStructure > PVStructurePtr
Definition: pvData.h:87
virtual void channelGetConnect(const Status &status, ChannelGet::shared_pointer const &channelGet, Structure::const_shared_pointer const &structure)
An easy to use alternative to ChannelGet.
Definition: pvaClient.h:1035
virtual void message(std::string const &message, epics::pvData::MessageType messageType)
ChannelGetRequesterImpl(PvaClientGetPtr const &pvaClientGet, PvaClientPtr const &pvaClient)
Definition: caget.c:48
std::tr1::shared_ptr< BitSet > BitSetPtr
Definition: bitSet.h:26
bool isOK() const
Definition: status.h:95
virtual void getDone(const Status &status, ChannelGet::shared_pointer const &channelGet, PVStructurePtr const &pvStructure, BitSet::shared_pointer const &bitSet)
std::tr1::shared_ptr< PvaClientGetRequester > PvaClientGetRequesterPtr
Definition: pvaClient.h:68