16 #define epicsExportSharedSymbols 24 namespace epics {
namespace pvaClient {
28 PvaClientMonitor::weak_pointer pvaClientMonitor;
29 PvaClient::weak_pointer pvaClient;
34 : pvaClientMonitor(pvaClientMonitor),
38 if(PvaClient::getDebug()) std::cout <<
"~MonitorRequesterImpl" << std::endl;
43 if(!clientMonitor)
return string(
"pvaClientMonitor is null");
44 return clientMonitor->getRequesterName();
49 if(!clientMonitor)
return;
50 clientMonitor->message(message,messageType);
55 Monitor::shared_pointer
const & monitor,
56 Structure::const_shared_pointer
const &
structure)
59 if(!clientMonitor)
return;
60 clientMonitor->monitorConnect(status,monitor,structure);
66 if(!clientMonitor)
return;
67 clientMonitor->unlisten(monitor);
73 if(!clientMonitor)
return;
74 clientMonitor->monitorEvent(monitor);
92 std::string
const & channelName,
93 std::string
const & providerName,
98 if(PvaClient::getDebug()) {
99 cout<<
"PvaClientMonitor::create(pvaClient,channelName,providerName,request,stateChangeRequester,monitorRequester)\n" 100 <<
" channelName " << channelName
101 <<
" providerName " << providerName
102 <<
" request " << request
107 if(!pvRequest)
throw std::runtime_error(createRequest->getMessage());
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(
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()
205 if(!yyy)
return string(
"PvaClientMonitor::getRequesterName() PvaClient isDestroyed");
206 return yyy->getRequesterName();
209 void PvaClientMonitor::message(
string const & message,
MessageType messageType)
213 yyy->message(message, messageType);
216 void PvaClientMonitor::monitorConnect(
218 Monitor::shared_pointer
const & monitor,
221 if(PvaClient::getDebug()) {
222 cout <<
"PvaClientMonitor::monitorConnect" 223 <<
" channelName " << pvaClientChannel->getChannel()->getChannelName()
224 <<
" status.isOK " << (status.
isOK() ?
"true" :
"false")
229 this->monitor = monitor;
233 string message = string(
"\nPvaClientMonitor::monitorConnect)")
234 +
"\npvRequest\n" + ss.str()
240 bool signal = (connectState==connectWait) ?
true :
false;
241 monitorConnectStatus =
status;
242 connectState = connected;
244 if(PvaClient::getDebug()) {
245 cout <<
"PvaClientMonitor::monitorConnect" 246 <<
" channelName " << pvaClientChannel->getChannel()->getChannelName()
247 <<
" is already started " 252 pvaClientData = PvaClientMonitorData::create(structure);
253 pvaClientData->setMessagePrefix(pvaClientChannel->getChannel()->getChannelName());
255 if(PvaClient::getDebug()) {
256 cout <<
"PvaClientMonitor::monitorConnect calling waitForConnect.signal\n";
258 waitForConnect.signal();
259 if(PvaClient::getDebug()) {
260 cout <<
"PvaClientMonitor::monitorConnect calling start\n";
264 if(PvaClient::getDebug()) {
265 cout <<
"PvaClientMonitor::monitorConnect calling start\n";
270 if(req) req->monitorConnect(status,shared_from_this(),structure);
273 void PvaClientMonitor::monitorEvent(
MonitorPtr const & monitor)
275 if(PvaClient::getDebug()) {
276 cout <<
"PvaClientMonitor::monitorEvent" 277 <<
" channelName " << pvaClientChannel->getChannel()->getChannelName()
281 if(req) req->event(shared_from_this());
282 if(userWait) waitForEvent.signal();
285 void PvaClientMonitor::unlisten(
MonitorPtr const & monitor)
287 if(PvaClient::getDebug()) cout <<
"PvaClientMonitor::unlisten\n";
293 cerr << pvaClientChannel->getChannel()->getChannelName() +
"pvaClientMonitor::unlisten called but no PvaClientMonitorRequester\n";
297 void PvaClientMonitor::connect()
299 if(PvaClient::getDebug()) cout <<
"PvaClientMonitor::connect\n";
301 Status status = waitConnect();
302 if(status.
isOK())
return;
303 string message = string(
"channel ")
304 + pvaClientChannel->getChannel()->getChannelName()
305 +
" PvaClientMonitor::connect " 307 throw std::runtime_error(message);
310 void PvaClientMonitor::issueConnect()
312 if(PvaClient::getDebug()) cout <<
"PvaClientMonitor::issueConnect\n";
313 if(connectState!=connectIdle) {
314 string message = string(
"channel ")
315 + pvaClientChannel->getChannel()->getChannelName()
316 +
" pvaClientMonitor already connected ";
317 throw std::runtime_error(message);
319 connectState = connectWait;
320 monitor = pvaClientChannel->getChannel()->createMonitor(monitorRequester,pvRequest);
325 if(PvaClient::getDebug()) {
326 cout <<
"PvaClientMonitor::waitConnect " 327 << pvaClientChannel->getChannel()->getChannelName()
332 if(connectState==connected) {
333 if(!monitorConnectStatus.isOK()) connectState = connectIdle;
334 return monitorConnectStatus;
336 if(connectState!=connectWait) {
337 string message = string(
"channel ") + pvaClientChannel->getChannel()->getChannelName()
338 +
" PvaClientMonitor::waitConnect illegal connect state ";
339 throw std::runtime_error(message);
342 waitForConnect.wait();
343 connectState = monitorConnectStatus.isOK() ? connected : connectIdle;
344 if(PvaClient::getDebug()) {
345 cout <<
"PvaClientMonitor::waitConnect" 346 <<
" monitorConnectStatus " << (monitorConnectStatus.isOK() ?
"connected" :
"not connected")
349 return monitorConnectStatus;
354 if(PvaClient::getDebug()) {
355 cout <<
"PvaClientMonitor::setRequester" 356 <<
" channelName " << pvaClientChannel->getChannel()->getChannelName()
359 this->pvaClientMonitorRequester = pvaClientMonitorRequester;
362 void PvaClientMonitor::start()
364 if(PvaClient::getDebug()) {
365 cout <<
"PvaClientMonitor::start" 366 <<
" channelName " << pvaClientChannel->getChannel()->getChannelName()
367 <<
" connectState " << connectState
373 if(connectState==connectIdle) connect();
374 if(connectState!=connected) {
375 string message = string(
"channel ") + pvaClientChannel->getChannel()->getChannelName()
376 +
" PvaClientMonitor::start illegal state ";
377 throw std::runtime_error(message);
383 void PvaClientMonitor::start(
string const &
request)
385 if(PvaClient::getDebug()) {
386 cout<<
"PvaMonitor::start(request)" 387 <<
" request " << request
391 if(!
client)
throw std::runtime_error(
"pvaClient was deleted");
392 if(!pvaClientChannel->getChannel()->isConnected()) {
394 "PvaClientMonitor::start(request) but not connected",
400 if(!pvr)
throw std::runtime_error(createRequest->getMessage());
402 if(isStarted) monitor->stop();
404 monitorRequester.reset();
407 connectState = connectIdle;
417 void PvaClientMonitor::stop()
419 if(PvaClient::getDebug()) {
420 cout <<
"PvaClientMonitor::stop" 421 <<
" channelName " << pvaClientChannel->getChannel()->getChannelName()
424 if(!isStarted)
return;
429 bool PvaClientMonitor::poll()
431 if(PvaClient::getDebug()) {
432 cout <<
"PvaClientMonitor::poll" 433 <<
" channelName " << pvaClientChannel->getChannel()->getChannelName()
437 monitorElement = monitor->poll();
438 if(!monitorElement)
return false;
440 pvaClientData->setData(monitorElement);
444 bool PvaClientMonitor::waitEvent(
double secondsToWait)
446 if(PvaClient::getDebug()) {
447 cout <<
"PvaClientMonitor::waitEvent" 448 <<
" channelName " << pvaClientChannel->getChannel()->getChannelName()
452 string message = string(
"channel ") + pvaClientChannel->getChannel()->getChannelName()
453 +
" PvaClientMonitor::waitEvent illegal state ";
454 throw std::runtime_error(message);
456 if(poll())
return true;
458 if(secondsToWait==0.0) {
461 waitForEvent.wait(secondsToWait);
467 void PvaClientMonitor::releaseEvent()
469 if(PvaClient::getDebug()) {
470 cout <<
"PvaClientMonitor::releaseEvent" 471 <<
" channelName " << pvaClientChannel->getChannel()->getChannelName()
475 string message = string(
"channel ") + pvaClientChannel->getChannel()->getChannelName()
476 +
" PvaClientMonitor::releaseEvent did not call poll";
477 throw std::runtime_error(message);
480 monitor->release(monitorElement);
485 return pvaClientChannel;
490 if(PvaClient::getDebug()) {
491 cout <<
"PvaClientMonitor::getData" 492 <<
" channelName " << pvaClientChannel->getChannel()->getChannelName()
496 return pvaClientData;
std::tr1::shared_ptr< PvaClient > PvaClientPtr
static CreateRequest::shared_pointer create()
virtual void message(std::string const &message, epics::pvData::MessageType messageType)
virtual void monitorEvent(epics::pvData::MonitorPtr const &monitor)
std::tr1::shared_ptr< PvaClientMonitorData > PvaClientMonitorDataPtr
std::tr1::shared_ptr< PvaClientChannel > PvaClientChannelPtr
TODO only here because of the Lockable.
std::tr1::shared_ptr< const Structure > StructureConstPtr
A lock for multithreading.
const std::string & getMessage() const
PVStructure::shared_pointer createRequest(std::string const &request)
virtual std::string getRequesterName()
std::tr1::shared_ptr< PvaClientMonitorRequester > PvaClientMonitorRequesterPtr
virtual ~MonitorRequesterImpl()
std::tr1::shared_ptr< PVStructure > PVStructurePtr
std::tr1::shared_ptr< MonitorRequesterImpl > MonitorRequesterImplPtr
virtual void unlisten(epics::pvData::MonitorPtr const &monitor)
Callback implemented by monitor clients.
std::tr1::shared_ptr< PvaClientChannelStateChangeRequester > PvaClientChannelStateChangeRequesterPtr
virtual void monitorConnect(const Status &status, Monitor::shared_pointer const &monitor, Structure::const_shared_pointer const &structure)
An easy to use alternative to Monitor.
MonitorRequesterImpl(PvaClientMonitorPtr const &pvaClientMonitor, PvaClientPtr const &pvaClient)
std::tr1::shared_ptr< PvaClientMonitor > PvaClientMonitorPtr
std::tr1::shared_ptr< Monitor > MonitorPtr