pvaClientCPP  4.8.1-dev
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 
24 class ChannelGetRequesterImpl : public ChannelGetRequester
25 {
26  PvaClientGet::weak_pointer pvaClientGet;
27  PvaClient::weak_pointer pvaClient;
28 public:
29  ChannelGetRequesterImpl(
30  PvaClientGetPtr const & pvaClientGet,
31  PvaClientPtr const &pvaClient)
32  : pvaClientGet(pvaClientGet),
33  pvaClient(pvaClient)
34  {}
35  virtual ~ChannelGetRequesterImpl() {
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, 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 string PvaClientGet::getRequesterName()
138 {
139  return pvaClientChannel->getRequesterName();
140 }
141 
142 void PvaClientGet::message(string const & message,MessageType messageType)
143 {
144  pvaClientChannel->message(message,messageType);
145 }
146 
147 void PvaClientGet::channelGetConnect(
148  const Status& status,
149  ChannelGet::shared_pointer const & channelGet,
150  StructureConstPtr const & structure)
151 {
152  if(PvaClient::getDebug()) {
153  cout << "PvaClientGet::channelGetConnect channelName "
154  << pvaClientChannel->getChannel()->getChannelName()
155  << " status.isOK " << (status.isOK() ? "true" : "false")
156  << "\n";
157  }
158  {
159  Lock xx(mutex);
160  channelGetConnectStatus = status;
161  if(status.isOK()) {
162  this->channelGet = channelGet;
163  connectState = connected;
164  pvaClientData = PvaClientGetData::create(structure);
165  pvaClientData->setMessagePrefix(channelGet->getChannel()->getChannelName());
166  }
167  waitForConnect.signal();
168  }
169  PvaClientGetRequesterPtr req(pvaClientGetRequester.lock());
170  if(req) {
171  req->channelGetConnect(status,shared_from_this());
172  }
173 }
174 
175 void PvaClientGet::getDone(
176  const Status& status,
177  ChannelGet::shared_pointer const & channelGet,
178  PVStructurePtr const & pvStructure,
179  BitSetPtr const & bitSet)
180 {
181  if(PvaClient::getDebug()) {
182  cout << "PvaClientGet::getDone channelName "
183  << pvaClientChannel->getChannel()->getChannelName()
184  << " status.isOK " << (status.isOK() ? "true" : "false")
185  << "\n";
186  }
187  {
188  Lock xx(mutex);
189  channelGetStatus = status;
190  if(status.isOK()) {
191  pvaClientData->setData(pvStructure,bitSet);
192  }
193  getState = getComplete;
194  waitForGet.signal();
195  }
196  PvaClientGetRequesterPtr req(pvaClientGetRequester.lock());
197  if(req) {
198  req->getDone(status,shared_from_this());
199  }
200 }
201 
202 void PvaClientGet::connect()
203 {
204  if(PvaClient::getDebug()) {
205  cout << "PvaClientGet::connect channelName "
206  << pvaClientChannel->getChannel()->getChannelName() << "\n";
207  }
208  issueConnect();
209  Status status = waitConnect();
210  if(status.isOK()) return;
211  string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
212  + " PvaClientGet::connect " + status.getMessage();
213  throw std::runtime_error(message);
214 }
215 
216 void PvaClientGet::issueConnect()
217 {
218  if(PvaClient::getDebug()) {
219  cout << "PvaClientGet::issueConnect channelName "
220  << pvaClientChannel->getChannel()->getChannelName() << "\n";
221  }
222  if(connectState!=connectIdle) {
223  string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
224  + " pvaClientGet already connected ";
225  throw std::runtime_error(message);
226  }
227  connectState = connectActive;
228  channelGetConnectStatus = Status(Status::STATUSTYPE_ERROR, "connect active");
229  channelGet = pvaClientChannel->getChannel()->createChannelGet(channelGetRequester,pvRequest);
230 }
231 
232 Status PvaClientGet::waitConnect()
233 {
234  if(PvaClient::getDebug()) {
235  cout << "PvaClientGet::waitConnect channelName "
236  << pvaClientChannel->getChannel()->getChannelName() << "\n";
237  }
238  waitForConnect.wait();
239  return channelGetConnectStatus;
240 }
241 
242 void PvaClientGet::get()
243 {
244  if(PvaClient::getDebug()) {
245  cout << "PvaClientGet::get channelName "
246  << pvaClientChannel->getChannel()->getChannelName() << "\n";
247  }
248  issueGet();
249  Status status = waitGet();
250  if(status.isOK()) return;
251  string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
252  + " PvaClientGet::get " + status.getMessage();
253  throw std::runtime_error(message);
254 }
255 
256 void PvaClientGet::issueGet()
257 {
258  if(PvaClient::getDebug()) {
259  cout << "PvaClientGet::issueGet channelName "
260  << pvaClientChannel->getChannel()->getChannelName() << "\n";
261  }
262  if(connectState==connectIdle) connect();
263  if(getState==getActive) {
264  string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
265  + " PvaClientGet::issueGet get aleady active ";
266  throw std::runtime_error(message);
267  }
268  getState = getActive;
269  channelGet->get();
270 }
271 
272 Status PvaClientGet::waitGet()
273 {
274  if(PvaClient::getDebug()) {
275  cout << "PvaClientGet::waitGet channelName "
276  << pvaClientChannel->getChannel()->getChannelName() << "\n";
277  }
278  waitForGet.wait();
279  return channelGetStatus;
280 }
281 PvaClientGetDataPtr PvaClientGet::getData()
282 {
283  if(PvaClient::getDebug()) {
284  cout<< "PvaClientGet::getData channelName "
285  << pvaClientChannel->getChannel()->getChannelName() << "\n";
286  }
287  checkConnectState();
288  if(getState==getIdle) get();
289  return pvaClientData;
290 }
291 
292 void PvaClientGet::setRequester(PvaClientGetRequesterPtr const & pvaClientGetRequester)
293 {
294  if(PvaClient::getDebug()) {
295  cout << "PvaClientGet::setRequester channelName "
296  << pvaClientChannel->getChannel()->getChannelName() << "\n";
297  }
298  this->pvaClientGetRequester = pvaClientGetRequester;
299 }
300 
301 PvaClientChannelPtr PvaClientGet::getPvaClientChannel()
302 {
303  return pvaClientChannel;
304 }
305 
306 
307 
308 }}
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< ChannelGetRequesterImpl > ChannelGetRequesterImplPtr
Definition: pvaClient.h:958
std::tr1::shared_ptr< PvaClientGet > PvaClientGetPtr
Definition: pvaClient.h:69
An easy to use alternative to ChannelGet.
Definition: pvaClient.h:993
std::tr1::shared_ptr< PvaClientGetRequester > PvaClientGetRequesterPtr
Definition: pvaClient.h:66