pvaClientCPP  4.8.1-dev
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 
24 class ChannelProcessRequesterImpl : public ChannelProcessRequester
25 {
26  PvaClientProcess::weak_pointer pvaClientProcess;
27  PvaClient::weak_pointer pvaClient;
28 public:
29  ChannelProcessRequesterImpl(
30  PvaClientProcessPtr const & pvaClientProcess,
31  PvaClientPtr const &pvaClient)
32  : pvaClientProcess(pvaClientProcess),
33  pvaClient(pvaClient)
34  {}
35  virtual ~ChannelProcessRequesterImpl() {
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, 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 string PvaClientProcess::getRequesterName()
115 {
116  return pvaClientChannel->getRequesterName();
117 }
118 
119 void PvaClientProcess::message(string const & message,MessageType messageType)
120 {
121  pvaClientChannel->message(message,messageType);
122 }
123 
124 void PvaClientProcess::channelProcessConnect(
125  const Status& status,
126  ChannelProcess::shared_pointer const & channelProcess)
127 {
128  if(PvaClient::getDebug()) {
129  cout << "PvaClientProcess::channelProcessConnect"
130  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
131  << " status.isOK " << (status.isOK() ? "true" : "false")
132  << endl;
133  }
134  {
135  Lock xx(mutex);
136  channelProcessConnectStatus = status;
137  if(status.isOK()) {
138  this->channelProcess = channelProcess;
139  connectState = connected;
140  }
141  waitForConnect.signal();
142  }
143  PvaClientProcessRequesterPtr req(pvaClientProcessRequester.lock());
144  if(req) {
145  req->channelProcessConnect(status,shared_from_this());
146  }
147 }
148 
149 void PvaClientProcess::processDone(
150  const Status& status,
151  ChannelProcess::shared_pointer const & channelProcess)
152 {
153  if(PvaClient::getDebug()) {
154  cout << "PvaClientProcess::processDone"
155  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
156  << " status.isOK " << (status.isOK() ? "true" : "false")
157  << endl;
158  }
159  {
160  Lock xx(mutex);
161  channelProcessStatus = status;
162  processState = processComplete;
163  waitForProcess.signal();
164  }
165  PvaClientProcessRequesterPtr req(pvaClientProcessRequester.lock());
166  if(req) {
167  req->processDone(status,shared_from_this());
168  }
169 }
170 
171 void PvaClientProcess::connect()
172 {
173  if(PvaClient::getDebug()) {
174  cout << "PvaClientProcess::connect"
175  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
176  << endl;
177  }
178  issueConnect();
179  Status status = waitConnect();
180  if(status.isOK()) return;
181  string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
182  + " PvaClientProcess::connect " + status.getMessage();
183  throw std::runtime_error(message);
184 }
185 
186 void PvaClientProcess::issueConnect()
187 {
188  if(PvaClient::getDebug()) {
189  cout << "PvaClientProcess::issueConnect"
190  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
191  << endl;
192  }
193  if(connectState!=connectIdle) {
194  string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
195  + " pvaClientProcess already connected ";
196  throw std::runtime_error(message);
197  }
198  connectState = connectActive;
199  channelProcessConnectStatus = Status(Status::STATUSTYPE_ERROR, "connect active");
200  channelProcess = pvaClientChannel->getChannel()->createChannelProcess(channelProcessRequester,pvRequest);
201 }
202 
203 Status PvaClientProcess::waitConnect()
204 {
205  if(PvaClient::getDebug()) {
206  cout << "PvaClientProcess::waitConnect"
207  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
208  << endl;
209  }
210  waitForConnect.wait();
211  return channelProcessConnectStatus;
212 }
213 
214 void PvaClientProcess::process()
215 {
216  if(PvaClient::getDebug()) {
217  cout << "PvaClientProcess::process"
218  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
219  << endl;
220  }
221  issueProcess();
222  Status status = waitProcess();
223  if(status.isOK()) return;
224  string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
225  + " PvaClientProcess::process" + status.getMessage();
226  throw std::runtime_error(message);
227 }
228 
229 void PvaClientProcess::issueProcess()
230 {
231  if(PvaClient::getDebug()) {
232  cout << "PvaClientProcess::issueProcess"
233  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
234  << endl;
235  }
236  if(connectState==connectIdle) connect();
237  if(processState==processActive) {
238  string message = string("channel ") + pvaClientChannel->getChannel()->getChannelName()
239  + " PvaClientProcess::issueProcess process aleady active ";
240  throw std::runtime_error(message);
241  }
242  processState = processActive;
243  channelProcess->process();
244 }
245 
246 Status PvaClientProcess::waitProcess()
247 {
248  if(PvaClient::getDebug()) {
249  cout << "PvaClientProcess::waitProcess"
250  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
251  << endl;
252  }
253  waitForProcess.wait();
254  processState = processComplete;
255  return channelProcessStatus;
256 }
257 
258 void PvaClientProcess::setRequester(PvaClientProcessRequesterPtr const & pvaClientProcessRequester)
259 {
260  if(PvaClient::getDebug()) {
261  cout << "PvaClientProcess::setRequester"
262  << " channelName " << pvaClientChannel->getChannel()->getChannelName()
263  << endl;
264  }
265  this->pvaClientProcessRequester = pvaClientProcessRequester;
266 }
267 
268 PvaClientChannelPtr PvaClientProcess::getPvaClientChannel()
269 {
270  return pvaClientChannel;
271 }
272 
273 
274 }}
std::tr1::shared_ptr< PvaClient > PvaClientPtr
Definition: pvaClient.h:46
std::tr1::shared_ptr< PvaClientProcessRequester > PvaClientProcessRequesterPtr
Definition: pvaClient.h:61
An easy to use alternative to ChannelProcess.
Definition: pvaClient.h:861
std::tr1::shared_ptr< ChannelProcessRequesterImpl > ChannelProcessRequesterImplPtr
Definition: pvaClient.h:854
std::tr1::shared_ptr< PvaClientChannel > PvaClientChannelPtr
Definition: pvaClient.h:59
STL namespace.
std::tr1::shared_ptr< PvaClientProcess > PvaClientProcessPtr
Definition: pvaClient.h:64