17 #define epicsExportSharedSymbols 25 namespace epics {
namespace pvaClient {
34 if(PvaClient::getDebug()) cout <<
"PvaClientGetCache::~PvaClientGetCache\n";
37 void addGet(
string const & request,
PvaClientGetPtr const & pvaClientGet);
41 map<string,PvaClientGetPtr> pvaClientGetMap;
46 map<string,PvaClientGetPtr>::iterator iter = pvaClientGetMap.find(request);
47 if(iter!=pvaClientGetMap.end())
return iter->second;
53 map<string,PvaClientGetPtr>::iterator iter = pvaClientGetMap.find(request);
54 if(iter!=pvaClientGetMap.end()) {
55 throw std::runtime_error(
"pvaClientGetCache::addGet pvaClientGet already cached");
57 pvaClientGetMap.insert(std::pair<string,PvaClientGetPtr>(request,pvaClientGet));
60 void PvaClientGetCache::showCache()
62 map<string,PvaClientGetPtr>::iterator iter;
63 for(iter = pvaClientGetMap.begin(); iter != pvaClientGetMap.end(); ++iter)
65 cout <<
" " << iter->first << endl;
69 size_t PvaClientGetCache::cacheSize()
71 return pvaClientGetMap.size();
81 if(PvaClient::getDebug()) cout <<
"PvaClientPutCache::~PvaClientPutCache\n";
84 void addPut(
string const & request,
PvaClientPutPtr const & pvaClientPut);
88 map<string,PvaClientPutPtr> pvaClientPutMap;
94 map<string,PvaClientPutPtr>::iterator iter = pvaClientPutMap.find(request);
95 if(iter!=pvaClientPutMap.end())
return iter->second;
101 map<string,PvaClientPutPtr>::iterator iter = pvaClientPutMap.find(request);
102 if(iter!=pvaClientPutMap.end()) {
103 throw std::runtime_error(
"pvaClientPutCache::addPut pvaClientPut already cached");
105 pvaClientPutMap.insert(std::pair<string,PvaClientPutPtr>(
106 request,pvaClientPut));
109 void PvaClientPutCache::showCache()
111 map<string,PvaClientPutPtr>::iterator iter;
112 for(iter = pvaClientPutMap.begin(); iter != pvaClientPutMap.end(); ++iter)
114 cout <<
" " << iter->first << endl;
118 size_t PvaClientPutCache::cacheSize()
120 return pvaClientPutMap.size();
126 string const & channelName,
127 string const & providerName)
134 PvaClientChannel::PvaClientChannel(
136 string const & channelName,
137 string const & providerName)
138 : pvaClient(pvaClient),
139 channelName(channelName),
140 providerName(providerName),
141 connectState(connectIdle),
146 if(PvaClient::getDebug()) {
147 cout <<
"PvaClientChannel::PvaClientChannel channelName " << channelName << endl;
151 PvaClientChannel::~PvaClientChannel()
153 if(PvaClient::getDebug()) {
154 cout <<
"PvaClientChannel::~PvaClientChannel() " 155 <<
" channelName " << channelName
158 if(PvaClient::getDebug()) showCache();
161 void PvaClientChannel::channelCreated(
const Status&
status, Channel::shared_pointer
const & channel)
163 if(PvaClient::getDebug()) {
164 cout <<
"PvaClientChannel::channelCreated" 165 <<
" channelName " << channelName
166 <<
" connectState " << connectState
167 <<
" isConnected " << (channel->isConnected() ?
"true" :
"false")
168 <<
" status.isOK " << (status.
isOK() ?
"true" :
"false")
172 this->channel = channel;
173 if(connectState==connected)
return;
174 if(connectState!=connectActive) {
175 string message(
"PvaClientChannel::channelCreated");
176 message +=
" channel " + channelName
177 +
" why was this called when connectState!=ConnectState.connectActive";
178 throw std::runtime_error(message);
181 string message(
"PvaClientChannel::channelCreated");
182 +
" status " + status.
getMessage() +
" why??";
183 throw std::runtime_error(message);
185 if(channel->isConnected()) {
186 connectState = connected;
187 waitForConnect.signal();
191 void PvaClientChannel::channelStateChange(
192 Channel::shared_pointer
const & channel,
195 if(PvaClient::getDebug()) {
196 cout <<
" PvaClientChannel::channelStateChange " 197 <<
" channelName " << channelName
198 <<
" " << Channel::ConnectionStateNames[connectionState]
201 bool waitingForConnect =
false;
202 if(connectState==connectActive) waitingForConnect =
true;
203 if(connectionState!=Channel::CONNECTED) {
205 string mess(channelName +
206 " connection state " + Channel::ConnectionStateNames[connectionState]);
208 connectState = notConnected;
211 this->channel = channel;
212 connectState = connected;
214 if(waitingForConnect) {
216 waitForConnect.signal();
220 bool value = (connectionState==Channel::CONNECTED ?
true :
false);
221 req->channelStateChange(shared_from_this(),value);
225 string PvaClientChannel::getRequesterName()
228 if(!yyy)
return string(
"PvaClientChannel::getRequesterName() PvaClient isDestroyed");
229 return yyy->getRequesterName();
232 void PvaClientChannel::message(
233 string const & message,
238 yyy->message(channelName +
" " + message, messageType);
241 string PvaClientChannel::getChannelName()
246 Channel::shared_pointer PvaClientChannel::getChannel()
251 void PvaClientChannel::setStateChangeRequester(
254 this->stateChangeRequester = stateChangeRequester;
255 bool isConnected =
false;
256 if(channel) isConnected = channel->isConnected();
257 stateChangeRequester->channelStateChange(shared_from_this(),isConnected);
260 void PvaClientChannel::connect(
double timeout)
262 if(PvaClient::getDebug()) {
263 cout <<
"PvaClientChannel::connect" 264 <<
" channelName " << channelName << endl;
268 if(status.
isOK())
return;
269 if(PvaClient::getDebug()) cout <<
"PvaClientChannel::connect waitConnect failed\n";
270 string message = string(
"channel ") + channelName
271 +
" PvaClientChannel::connect " + status.
getMessage();
272 throw std::runtime_error(message);
275 void PvaClientChannel::issueConnect()
277 if(PvaClient::getDebug()) {
278 cout <<
"PvaClientChannel::issueConnect" 279 <<
" channelName " << channelName << endl;
283 if(connectState==connected)
return;
284 if(connectState!=connectIdle) {
285 throw std::runtime_error(
"pvaClientChannel already connected");
287 connectState = connectActive;
290 channelProvider = reg->getProvider(providerName);
291 if(!channelProvider) {
292 throw std::runtime_error(channelName +
" provider " + providerName +
" not registered");
294 if(PvaClient::getDebug()) cout <<
"PvaClientChannel::issueConnect calling provider->createChannel\n";
295 channel = channelProvider->createChannel(channelName,shared_from_this(),ChannelProvider::PRIORITY_DEFAULT);
297 throw std::runtime_error(channelName +
" channelCreate failed ");
303 if(PvaClient::getDebug()) {
304 cout <<
"PvaClientChannel::waitConnect" 305 <<
" channelName " << channelName << endl;
313 waitForConnect.wait(timeout);
315 waitForConnect.wait();
325 if(connectState!=connected) connect(5.0);
326 throw std::runtime_error(
"PvaClientChannel::createField not implemented");
333 string message = string(
"channel ") + channelName
334 +
" PvaClientChannel::createProcess invalid pvRequest: " 336 throw std::runtime_error(message);
338 return createProcess(pvRequest);
343 if(connectState!=connected) connect(5.0);
345 if(!yyy)
throw std::runtime_error(
"PvaClient was destroyed");
346 return PvaClientProcess::create(yyy,shared_from_this(),pvRequest);
354 pvaClientGet = createGet(request);
355 pvaClientGet->connect();
356 pvaClientGetCache->addGet(request,pvaClientGet);
367 string message = string(
"channel ") + channelName
368 +
" PvaClientChannel::createGet invalid pvRequest: " 370 throw std::runtime_error(message);
372 return createGet(pvRequest);
377 if(connectState!=connected) connect(5.0);
379 if(!yyy)
throw std::runtime_error(
"PvaClient was destroyed");
380 return PvaClientGet::create(yyy,shared_from_this(),pvRequest);
383 double PvaClientChannel::getDouble(
string const & request)
385 return get(
request)->getData()->getDouble();
388 string PvaClientChannel::getString(
string const & request)
390 return get(
request)->getData()->getString();
395 return get(
request)->getData()->getDoubleArray();
400 return get(
request)->getData()->getStringArray();
407 if(pvaClientPut)
return pvaClientPut;
409 pvaClientPut = createPut(request);
410 pvaClientPut->connect();
412 pvaClientPutCache->addPut(request,pvaClientPut);
422 string message = string(
"channel ") + channelName
423 +
" PvaClientChannel::createPut invalid pvRequest: " 425 throw std::runtime_error(message);
427 return createPut(pvRequest);
432 if(connectState!=connected) connect(5.0);
434 if(!yyy)
throw std::runtime_error(
"PvaClient was destroyed");
435 return PvaClientPut::create(yyy,shared_from_this(),pvRequest);
438 void PvaClientChannel::putDouble(
double value,
string const & request)
442 putData->putDouble(value); clientPut->put();
445 void PvaClientChannel::putString(std::string
const &
value,
string const & request)
449 putData->putString(value); clientPut->put();
452 void PvaClientChannel::putDoubleArray(
454 string const & request)
458 size_t n = value.
size();
460 for(
size_t i=0;
i<n; ++
i) valueArray[
i] = value[
i];
461 putData->putDoubleArray(freeze(valueArray)); clientPut->put();
464 void PvaClientChannel::putStringArray(
466 string const & request)
470 size_t n = value.
size();
472 for(
size_t i=0;
i<n; ++
i) valueArray[
i] = value[
i];
473 putData->putStringArray(freeze(valueArray)); clientPut->put();
480 string message = string(
"channel ") + channelName
481 +
" PvaClientChannel::createPutGet invalid pvRequest: " 483 throw std::runtime_error(message);
485 return createPutGet(pvRequest);
490 if(connectState!=connected) connect(5.0);
492 if(!yyy)
throw std::runtime_error(
"PvaClient was destroyed");
493 return PvaClientPutGet::create(yyy,shared_from_this(),pvRequest);
502 string message = string(
"channel ") + channelName
503 +
" PvaClientChannel::createArray invalid pvRequest: " 505 throw std::runtime_error(message);
507 return createArray(pvRequest);
512 if(connectState!=connected) connect(5.0);
513 throw std::runtime_error(
"PvaClientChannel::createArray not implemented");
520 pvaClientMonitor->connect();
521 pvaClientMonitor->start();
522 return pvaClientMonitor;
527 return monitor(
"field(value,alarm,timeStamp)",pvaClientMonitorRequester);
534 pvaClientMonitor->connect();
535 pvaClientMonitor->setRequester(pvaClientMonitorRequester);
536 pvaClientMonitor->start();
537 return pvaClientMonitor;
544 string message = string(
"channel ") + channelName
545 +
" PvaClientChannel::createMonitor invalid pvRequest: " 547 throw std::runtime_error(message);
549 return createMonitor(pvRequest);
554 if(connectState!=connected) connect(5.0);
556 if(!yyy)
throw std::runtime_error(
"PvaClient was destroyed");
557 return PvaClientMonitor::create(yyy,shared_from_this(),pvRequest);
566 return rpc->request(pvArgument);
573 return rpc->request(pvArgument);
578 if(connectState!=connected) connect(5.0);
580 if(!yyy)
throw std::runtime_error(
"PvaClient was destroyed");
581 return PvaClientRPC::create(yyy,channel);
586 if(connectState!=connected) connect(5.0);
588 if(!yyy)
throw std::runtime_error(
"PvaClient was destroyed");
589 return PvaClientRPC::create(yyy,channel,pvRequest);
592 void PvaClientChannel::showCache()
594 if(pvaClientGetCache->cacheSize()>=1) {
595 cout <<
" pvaClientGet cache" << endl;
596 pvaClientGetCache->showCache();
598 cout <<
" pvaClientGet cache is empty\n";
600 if(pvaClientPutCache->cacheSize()>=1) {
601 cout <<
" pvaClientPut cache" << endl;
602 pvaClientPutCache->showCache();
604 cout <<
" pvaClientPut cache is empty\n";
608 size_t PvaClientChannel::cacheSize()
610 return pvaClientGetCache->cacheSize() + pvaClientPutCache->cacheSize();
std::tr1::shared_ptr< PvaClient > PvaClientPtr
std::tr1::shared_ptr< detail::SharedPut > put
A holder for a contiguous piece of memory.
static CreateRequest::shared_pointer create()
std::tr1::shared_ptr< PvaClientChannel > PvaClientChannelPtr
TODO only here because of the Lockable.
A lock for multithreading.
const std::string & getMessage() const
PVStructure::shared_pointer createRequest(std::string const &request)
std::tr1::shared_ptr< PvaClientPut > PvaClientPutPtr
std::tr1::shared_ptr< PvaClientMonitorRequester > PvaClientMonitorRequesterPtr
std::tr1::shared_ptr< PvaClientArray > PvaClientArrayPtr
ChannelProviderRegistry::shared_pointer clients
size_t size() const
Number of elements visible through this vector.
std::tr1::shared_ptr< PvaClientField > PvaClientFieldPtr
std::tr1::shared_ptr< PvaClientGet > PvaClientGetPtr
std::tr1::shared_ptr< PVStructure > PVStructurePtr
std::tr1::shared_ptr< PvaClientRPC > PvaClientRPCPtr
std::tr1::shared_ptr< PvaClientChannelStateChangeRequester > PvaClientChannelStateChangeRequesterPtr
An easy to use alternative to directly calling the Channel methods of pvAccess.
std::tr1::shared_ptr< PvaClientProcess > PvaClientProcessPtr
std::tr1::shared_ptr< PvaClientPutGet > PvaClientPutGetPtr
std::tr1::shared_ptr< PvaClientMonitor > PvaClientMonitorPtr
std::tr1::shared_ptr< PvaClientPutData > PvaClientPutDataPtr