This is Unofficial EPICS BASE Doxygen Site
pvaClientProcess.cpp
Go to the documentation of this file.
1 /* pvaClientProcess.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  PvaClientProcess::weak_pointer pvaClientProcess;
27  PvaClient::weak_pointer pvaClient;
28 public:
30  PvaClientProcessPtr const & pvaClientProcess,
31  PvaClientPtr const &pvaClient)
32  : pvaClientProcess(pvaClientProcess),
33  pvaClient(pvaClient)
34  {}
36  if(PvaClient::getDebug()) std::cout << "~ChannelProcessRequesterImpl" << std::endl;
37  }
38 
39  virtual std::string getRequesterName() {
40  PvaClientProcessPtr clientProcess(pvaClientProcess.lock());
41  if(!clientProcess) return string("clientProcess is null");
42  return clientProcess->getRequesterName();
43  }
44 
45  virtual void message(std::string const & message, epics::pvData::MessageType messageType) {
46  PvaClientProcessPtr clientProcess(pvaClientProcess.lock());
47  if(!clientProcess) return;
48  clientProcess->message(message,messageType);
49  }
50 
51  virtual void channelProcessConnect(
52  const Status& status,
53  ChannelProcess::shared_pointer const & channelProcess)
54  {
55  PvaClientProcessPtr clientProcess(pvaClientProcess.lock());
56  if(!clientProcess) return;
57  clientProcess->channelProcessConnect(status,channelProcess);
58  }
59 
60  virtual void processDone(
61  const Status& status,
62  ChannelProcess::shared_pointer const & ChannelProcess)
63  {
64  PvaClientProcessPtr clientProcess(pvaClientProcess.lock());
65  if(!clientProcess) return;
66  clientProcess->processDone(status,ChannelProcess);
67  }
68 };
69 
70 PvaClientProcessPtr PvaClientProcess::create(
71  PvaClientPtr const &pvaClient,
72  PvaClientChannelPtr const & pvaClientChannel,
73  PVStructurePtr const &pvRequest)
74 {
75  if(PvaClient::getDebug()) {
76  cout<< "PvaClientProcess::create(pvaClient,channelName,pvRequest)\n"
77  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
78  << " pvRequest " << pvRequest
79  << endl;
80  }
81  PvaClientProcessPtr channelProcess(new PvaClientProcess(pvaClient,pvaClientChannel,pvRequest));
82  channelProcess->channelProcessRequester = ChannelProcessRequesterImplPtr(
83  new ChannelProcessRequesterImpl(channelProcess,pvaClient));
84  return channelProcess;
85 }
86 
87 
88 PvaClientProcess::PvaClientProcess(
89  PvaClientPtr const &pvaClient,
90  PvaClientChannelPtr const & pvaClientChannel,
91  PVStructurePtr const &pvRequest)
92 : pvaClient(pvaClient),
93  pvaClientChannel(pvaClientChannel),
94  pvRequest(pvRequest),
95  connectState(connectIdle),
96  processState(processIdle)
97 {
98  if(PvaClient::getDebug()) {
99  cout<< "PvaClientProcess::PvaClientProcess()"
100  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
101  << endl;
102  }
103 }
104 
105 PvaClientProcess::~PvaClientProcess()
106 {
107  if(PvaClient::getDebug()) {
108  cout<< "PvaClientProcess::~PvaClientProcess()"
109  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
110  << endl;
111  }
112 }
113 
114 // from ChannelProcessRequester
115 string PvaClientProcess::getRequesterName()
116 {
117  PvaClientPtr yyy = pvaClient.lock();
118  if(!yyy) throw std::runtime_error("pvaClient was destroyed");
119  return yyy->getRequesterName();
120 }
121 
122 void PvaClientProcess::message(string const & message,MessageType messageType)
123 {
124  PvaClientPtr yyy = pvaClient.lock();
125  if(!yyy) throw std::runtime_error("pvaClient was destroyed");
126  yyy->message(message, messageType);
127 }
128 
129 void PvaClientProcess::channelProcessConnect(
130  const Status& status,
131  ChannelProcess::shared_pointer const & channelProcess)
132 {
133  if(PvaClient::getDebug()) {
134  cout << "PvaClientProcess::channelProcessConnect"
135  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
136  << " status.isOK " << (status.isOK() ? "true" : "false")
137  << endl;
138  }
139  {
140  Lock xx(mutex);
141  this->channelProcess = channelProcess;
142  if(status.isOK()) {
143  channelProcessConnectStatus = status;
144  connectState = connected;
145  } else {
146  stringstream ss;
147  ss << pvRequest;
148  string message = string("PvaClientProcess::channelProcessConnect")
149  + "\npvRequest\n" + ss.str()
150  + "\nerror\n" + status.getMessage();
151  channelProcessConnectStatus = Status(Status::STATUSTYPE_ERROR,message);
152  }
153  }
154  PvaClientProcessRequesterPtr req(pvaClientProcessRequester.lock());
155  if(req) {
156  req->channelProcessConnect(status,shared_from_this());
157  }
158  waitForConnect.signal();
159 
160 }
161 
162 void PvaClientProcess::processDone(
163  const Status& status,
164  ChannelProcess::shared_pointer const & channelProcess)
165 {
166  if(PvaClient::getDebug()) {
167  cout << "PvaClientProcess::processDone"
168  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
169  << " status.isOK " << (status.isOK() ? "true" : "false")
170  << endl;
171  }
172  {
173  Lock xx(mutex);
174  channelProcessStatus = status;
175  processState = processComplete;
176  }
177 
178  PvaClientProcessRequesterPtr req(pvaClientProcessRequester.lock());
179  if(req) {
180  req->processDone(status,shared_from_this());
181  }
182  waitForProcess.signal();
183 }
184 
185 void PvaClientProcess::connect()
186 {
187  if(PvaClient::getDebug()) {
188  cout << "PvaClientProcess::connect"
189  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
190  << endl;
191  }
192  issueConnect();
193  Status status = waitConnect();
194  if(status.isOK()) return;
195  string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
196  + " PvaClientProcess::connect " + status.getMessage();
197  throw std::runtime_error(message);
198 }
199 
200 void PvaClientProcess::issueConnect()
201 {
202  if(PvaClient::getDebug()) {
203  cout << "PvaClientProcess::issueConnect"
204  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
205  << endl;
206  }
207  if(connectState!=connectIdle) {
208  string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
209  + " pvaClientProcess already connected ";
210  throw std::runtime_error(message);
211  }
212  connectState = connectActive;
213  channelProcessConnectStatus = Status(Status::STATUSTYPE_ERROR, "connect active");
214  channelProcess = pvaClientChannel->getChannel()->createChannelProcess(channelProcessRequester,pvRequest);
215 }
216 
217 Status PvaClientProcess::waitConnect()
218 {
219  if(PvaClient::getDebug()) {
220  cout << "PvaClientProcess::waitConnect"
221  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
222  << endl;
223  }
224  if(connectState==connected) {
225  if(!channelProcessConnectStatus.isOK()) connectState = connectIdle;
226  return channelProcessConnectStatus;
227  }
228  if(connectState!=connectActive) {
229  string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
230  + " pvaClientProcess illegal connect state ";
231  throw std::runtime_error(message);
232  }
233  waitForConnect.wait();
234  if(!channelProcessConnectStatus.isOK()) connectState = connectIdle;
235  return channelProcessConnectStatus;
236 }
237 
238 void PvaClientProcess::process()
239 {
240  if(PvaClient::getDebug()) {
241  cout << "PvaClientProcess::process"
242  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
243  << endl;
244  }
245  issueProcess();
246  Status status = waitProcess();
247  if(status.isOK()) return;
248  string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
249  + " PvaClientProcess::process" + status.getMessage();
250  throw std::runtime_error(message);
251 }
252 
253 void PvaClientProcess::issueProcess()
254 {
255  if(PvaClient::getDebug()) {
256  cout << "PvaClientProcess::issueProcess"
257  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
258  << endl;
259  }
260  if(connectState==connectIdle) connect();
261  if(processState==processActive) {
262  string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
263  + " PvaClientProcess::issueProcess process aleady active ";
264  throw std::runtime_error(message);
265  }
266  processState = processActive;
267  channelProcess->process();
268 }
269 
270 Status PvaClientProcess::waitProcess()
271 {
272  if(PvaClient::getDebug()) {
273  cout << "PvaClientProcess::waitProcess"
274  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
275  << endl;
276  }
277  {
278  Lock xx(mutex);
279  if(processState==processComplete) {
280  processState = processIdle;
281  return channelProcessStatus;
282  }
283  if(processState!=processActive){
284  string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
285  + " PvaClientProcess::waitProcess llegal process state";
286  throw std::runtime_error(message);
287  }
288  }
289  waitForProcess.wait();
290  processState = processComplete;
291  return channelProcessStatus;
292 }
293 
294 void PvaClientProcess::setRequester(PvaClientProcessRequesterPtr const & pvaClientProcessRequester)
295 {
296  if(PvaClient::getDebug()) {
297  cout << "PvaClientProcess::setRequester"
298  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
299  << endl;
300  }
301  this->pvaClientProcessRequester = pvaClientProcessRequester;
302 }
303 
304 PvaClientChannelPtr PvaClientProcess::getPvaClientChannel()
305 {
306  return pvaClientChannel;
307 }
308 
309 
310 }}
std::tr1::shared_ptr< PvaClient > PvaClientPtr
Definition: pvaClient.h:46
std::tr1::shared_ptr< PvaClientProcessRequester > PvaClientProcessRequesterPtr
Definition: pvaClient.h:63
An easy to use alternative to ChannelProcess.
Definition: pvaClient.h:901
pvd::Status status
std::tr1::shared_ptr< ChannelProcessRequesterImpl > ChannelProcessRequesterImplPtr
Definition: pvaClient.h:893
virtual void processDone(const Status &status, ChannelProcess::shared_pointer const &ChannelProcess)
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
A lock for multithreading.
Definition: lock.h:36
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
virtual void channelProcessConnect(const Status &status, ChannelProcess::shared_pointer const &channelProcess)
ChannelProcessRequesterImpl(PvaClientProcessPtr const &pvaClientProcess, PvaClientPtr const &pvaClient)
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< PvaClientProcess > PvaClientProcessPtr
Definition: pvaClient.h:66
bool isOK() const
Definition: status.h:95