14 #include <pv/bitSetUtil.h> 16 #define epicsExportSharedSymbols 24 namespace epics {
namespace pvaClient {
26 class MonitorRequesterImpl :
public MonitorRequester
28 PvaClientMonitor::weak_pointer pvaClientMonitor;
29 PvaClient::weak_pointer pvaClient;
34 : pvaClientMonitor(pvaClientMonitor),
37 virtual ~MonitorRequesterImpl() {
38 if(PvaClient::getDebug()) std::cout <<
"~MonitorRequesterImpl" << std::endl;
41 virtual std::string getRequesterName() {
43 if(!clientMonitor)
return string(
"pvaClientMonitor is null");
44 return clientMonitor->getRequesterName();
47 virtual void message(std::string
const & message, MessageType messageType) {
49 if(!clientMonitor)
return;
50 clientMonitor->message(message,messageType);
53 virtual void monitorConnect(
55 Monitor::shared_pointer
const & monitor,
56 Structure::const_shared_pointer
const & structure)
59 if(!clientMonitor)
return;
60 clientMonitor->monitorConnect(status,monitor,structure);
63 virtual void unlisten(MonitorPtr
const & monitor)
66 if(!clientMonitor)
return;
67 clientMonitor->unlisten(monitor);
70 virtual void monitorEvent(MonitorPtr
const & monitor)
73 if(!clientMonitor)
return;
74 clientMonitor->monitorEvent(monitor);
82 PVStructurePtr
const &pvRequest)
84 PvaClientMonitorPtr clientMonitor(
new PvaClientMonitor(pvaClient,pvaClientChannel,pvRequest));
86 new MonitorRequesterImpl(clientMonitor,pvaClient));
92 std::string
const & channelName,
93 std::string
const & providerName,
94 std::string
const & request,
98 if(PvaClient::getDebug()) {
99 cout<<
"PvaClientMonitor::create(pvaClient,channelName,providerName,request,stateChangeRequester,monitorRequester)\n" 100 <<
" channelName " << channelName
101 <<
" providerName " << providerName
102 <<
" request " << request
105 CreateRequest::shared_pointer createRequest(CreateRequest::create());
106 PVStructurePtr pvRequest(createRequest->createRequest(request));
107 if(!pvRequest)
throw std::runtime_error(createRequest->getMessage());
111 new MonitorRequesterImpl(clientMonitor,pvaClient));
112 if(stateChangeRequester) clientMonitor->pvaClientChannelStateChangeRequester = stateChangeRequester;
113 if(monitorRequester) clientMonitor->pvaClientMonitorRequester = monitorRequester;
114 pvaClientChannel->setStateChangeRequester(clientMonitor);
115 pvaClientChannel->issueConnect();
116 return clientMonitor;
120 PvaClientMonitor::PvaClientMonitor(
123 PVStructurePtr
const &pvRequest)
124 : pvaClient(pvaClient),
125 pvaClientChannel(pvaClientChannel),
126 pvRequest(pvRequest),
128 connectState(connectIdle),
132 if(PvaClient::getDebug()) {
133 cout<<
"PvaClientMonitor::PvaClientMonitor\n" 134 <<
" channelName " << pvaClientChannel->getChannel()->getChannelName()
139 PvaClientMonitor::~PvaClientMonitor()
141 if(PvaClient::getDebug()) {
142 cout<<
"PvaClientMonitor::~PvaClientMonitor" 143 <<
" channelName " << pvaClientChannel->getChannel()->getChannelName()
147 if(isStarted) monitor->stop();
153 if(PvaClient::getDebug()) {
154 cout<<
"PvaClientMonitor::channelStateChange" 155 <<
" channelName " << channel->getChannelName()
156 <<
" isConnected " << (isConnected ?
"true" :
"false")
159 if(isConnected&&!monitor)
161 connectState = connectActive;
162 monitor = pvaClientChannel->getChannel()->createMonitor(monitorRequester,pvRequest);
166 req->channelStateChange(channel,isConnected);
172 if(PvaClient::getDebug()) {
173 cout <<
"PvaClientMonitor::event" 174 <<
" channelName " << pvaClientChannel->getChannel()->getChannelName()
178 if(req) req->event(monitor);
181 void PvaClientMonitor::checkMonitorState()
183 if(PvaClient::getDebug()) {
184 cout <<
"PvaClientMonitor::checkMonitorState" 185 <<
" channelName " << pvaClientChannel->getChannel()->getChannelName()
186 <<
" connectState " << connectState
189 if(connectState==connectIdle) {
191 if(!isStarted) start();
194 if(connectState==connectActive){
195 string message = string(
"channel ") + pvaClientChannel->getChannel()->getChannelName()
197 + monitorConnectStatus.getMessage();
198 throw std::runtime_error(message);
202 string PvaClientMonitor::getRequesterName()
204 return pvaClientChannel->getRequesterName();
207 void PvaClientMonitor::message(
string const & message,MessageType messageType)
209 pvaClientChannel->message(message,messageType);
212 void PvaClientMonitor::monitorConnect(
213 const Status& status,
214 Monitor::shared_pointer
const & monitor,
215 StructureConstPtr
const & structure)
217 if(PvaClient::getDebug()) {
218 cout <<
"PvaClientMonitor::monitorConnect" 219 <<
" channelName " << pvaClientChannel->getChannel()->getChannelName()
220 <<
" status.isOK " << (status.isOK() ?
"true" :
"false")
225 monitorConnectStatus = status;
227 this->monitor = monitor;
231 string message = string(
"\nPvaClientMonitor::monitorConnect)")
232 +
"\nchannelName=" + pvaClientChannel->getChannel()->getChannelName()
233 +
"\npvRequest\n" + ss.str()
234 +
"\nerror\n" + status.getMessage();
235 monitorConnectStatus = Status(Status::STATUSTYPE_ERROR,message);
236 waitForConnect.signal();
238 if(req) req->monitorConnect(status,shared_from_this(),structure);
242 bool signal = (connectState==connectWait) ?
true :
false;
243 connectState = connected;
245 if(PvaClient::getDebug()) {
246 cout <<
"PvaClientMonitor::monitorConnect" 247 <<
" channelName " << pvaClientChannel->getChannel()->getChannelName()
248 <<
" is already started " 251 waitForConnect.signal();
253 if(req) req->monitorConnect(status,shared_from_this(),structure);
256 pvaClientData = PvaClientMonitorData::create(structure);
257 pvaClientData->setMessagePrefix(pvaClientChannel->getChannel()->getChannelName());
259 if(PvaClient::getDebug()) {
260 cout <<
"PvaClientMonitor::monitorConnect calling waitForConnect.signal\n";
262 waitForConnect.signal();
263 if(PvaClient::getDebug()) {
264 cout <<
"PvaClientMonitor::monitorConnect calling start\n";
268 if(PvaClient::getDebug()) {
269 cout <<
"PvaClientMonitor::monitorConnect calling start\n";
274 if(req) req->monitorConnect(status,shared_from_this(),structure);
277 void PvaClientMonitor::monitorEvent(MonitorPtr
const & monitor)
279 if(PvaClient::getDebug()) {
280 cout <<
"PvaClientMonitor::monitorEvent" 281 <<
" channelName " << pvaClientChannel->getChannel()->getChannelName()
285 if(req) req->event(shared_from_this());
286 if(userWait) waitForEvent.signal();
289 void PvaClientMonitor::unlisten(MonitorPtr
const & monitor)
291 if(PvaClient::getDebug()) cout <<
"PvaClientMonitor::unlisten\n";
299 void PvaClientMonitor::connect()
301 if(PvaClient::getDebug()) cout <<
"PvaClientMonitor::connect\n";
303 Status status = waitConnect();
304 if(status.isOK())
return;
305 string message = string(
"channel ")
306 + pvaClientChannel->getChannel()->getChannelName()
307 +
" PvaClientMonitor::connect " 308 + status.getMessage();
309 throw std::runtime_error(message);
312 void PvaClientMonitor::issueConnect()
314 if(PvaClient::getDebug()) cout <<
"PvaClientMonitor::issueConnect\n";
315 if(connectState!=connectIdle) {
316 string message = string(
"channel ")
317 + pvaClientChannel->getChannel()->getChannelName()
318 +
" pvaClientMonitor already connected ";
319 throw std::runtime_error(message);
321 connectState = connectWait;
322 monitor = pvaClientChannel->getChannel()->createMonitor(monitorRequester,pvRequest);
325 Status PvaClientMonitor::waitConnect()
327 if(PvaClient::getDebug()) {
328 cout <<
"PvaClientMonitor::waitConnect " 329 << pvaClientChannel->getChannel()->getChannelName()
332 waitForConnect.wait();
333 if(PvaClient::getDebug()) {
334 cout <<
"PvaClientMonitor::waitConnect" 335 <<
" monitorConnectStatus " << (monitorConnectStatus.isOK() ?
"connected" :
"not connected")
338 return monitorConnectStatus;
343 if(PvaClient::getDebug()) {
344 cout <<
"PvaClientMonitor::setRequester" 345 <<
" channelName " << pvaClientChannel->getChannel()->getChannelName()
348 this->pvaClientMonitorRequester = pvaClientMonitorRequester;
351 void PvaClientMonitor::start()
353 if(PvaClient::getDebug()) {
354 cout <<
"PvaClientMonitor::start" 355 <<
" channelName " << pvaClientChannel->getChannel()->getChannelName()
356 <<
" connectState " << connectState
362 if(connectState==connectIdle) connect();
363 if(connectState!=connected) {
364 string message = string(
"channel ") + pvaClientChannel->getChannel()->getChannelName()
365 +
" PvaClientMonitor::start illegal state ";
366 throw std::runtime_error(message);
372 void PvaClientMonitor::start(
string const & request)
374 if(PvaClient::getDebug()) {
375 cout<<
"PvaMonitor::start(request)" 376 <<
" request " << request
380 if(!client)
throw std::runtime_error(
"pvaClient was deleted");
381 if(!pvaClientChannel->getChannel()->isConnected()) {
383 "PvaClientMonitor::start(request) but not connected",
387 CreateRequest::shared_pointer createRequest(CreateRequest::create());
388 PVStructurePtr pvr(createRequest->createRequest(request));
389 if(!pvr)
throw std::runtime_error(createRequest->getMessage());
391 if(isStarted) monitor->stop();
393 monitorRequester.reset();
396 connectState = connectIdle;
400 new MonitorRequesterImpl(shared_from_this(),client));
406 void PvaClientMonitor::stop()
408 if(PvaClient::getDebug()) {
409 cout <<
"PvaClientMonitor::stop" 410 <<
" channelName " << pvaClientChannel->getChannel()->getChannelName()
413 if(!isStarted)
return;
418 bool PvaClientMonitor::poll()
420 if(PvaClient::getDebug()) {
421 cout <<
"PvaClientMonitor::poll" 422 <<
" channelName " << pvaClientChannel->getChannel()->getChannelName()
426 monitorElement = monitor->poll();
427 if(!monitorElement)
return false;
429 pvaClientData->setData(monitorElement);
433 bool PvaClientMonitor::waitEvent(
double secondsToWait)
435 if(PvaClient::getDebug()) {
436 cout <<
"PvaClientMonitor::waitEvent" 437 <<
" channelName " << pvaClientChannel->getChannel()->getChannelName()
441 string message = string(
"channel ") + pvaClientChannel->getChannel()->getChannelName()
442 +
" PvaClientMonitor::waitEvent illegal state ";
443 throw std::runtime_error(message);
445 if(poll())
return true;
447 if(secondsToWait==0.0) {
450 waitForEvent.wait(secondsToWait);
456 void PvaClientMonitor::releaseEvent()
458 if(PvaClient::getDebug()) {
459 cout <<
"PvaClientMonitor::releaseEvent" 460 <<
" channelName " << pvaClientChannel->getChannel()->getChannelName()
464 string message = string(
"channel ") + pvaClientChannel->getChannel()->getChannelName()
465 +
" PvaClientMonitor::releaseEvent did not call poll";
466 throw std::runtime_error(message);
469 monitor->release(monitorElement);
474 return pvaClientChannel;
479 if(PvaClient::getDebug()) {
480 cout <<
"PvaClientMonitor::getData" 481 <<
" channelName " << pvaClientChannel->getChannel()->getChannelName()
485 return pvaClientData;
std::tr1::shared_ptr< PvaClient > PvaClientPtr
std::tr1::shared_ptr< PvaClientMonitorData > PvaClientMonitorDataPtr
std::tr1::shared_ptr< PvaClientChannel > PvaClientChannelPtr
std::tr1::shared_ptr< PvaClientMonitorRequester > PvaClientMonitorRequesterPtr
std::tr1::shared_ptr< MonitorRequesterImpl > MonitorRequesterImplPtr
std::tr1::shared_ptr< PvaClientChannelStateChangeRequester > PvaClientChannelStateChangeRequesterPtr
An easy to use alternative to Monitor.
std::tr1::shared_ptr< PvaClientMonitor > PvaClientMonitorPtr