pvaClientCPP 4.8.1
pvaClient.cpp
Go to the documentation of this file.
1/* pvaClient.cpp */
12#include <map>
13#include <pv/createRequest.h>
14#include <pv/clientFactory.h>
15#include <pv/caProvider.h>
16
17#define epicsExportSharedSymbols
18
19#include <pv/pvaClient.h>
20
21using namespace epics::pvData;
22using namespace epics::pvAccess;
23using namespace epics::pvAccess::ca;
24using namespace std;
25
26namespace epics { namespace pvaClient {
27
28
29class epicsShareClass PvaClientChannelCache
30{
31public:
32 PvaClientChannelCache(){}
33 ~PvaClientChannelCache(){
34 if(PvaClient::getDebug()) cout << "PvaClientChannelCache::~PvaClientChannelCache\n";
35 }
36 PvaClientChannelPtr getChannel(
37 string const & channelName,
38 string const & providerName);
39 void addChannel(PvaClientChannelPtr const & pvaClientChannel);
40 void showCache();
41 size_t cacheSize();
42private:
43 map<string,PvaClientChannelPtr> pvaClientChannelMap;
44};
45
46PvaClientChannelPtr PvaClientChannelCache::getChannel(
47 string const & channelName,
48 string const & providerName)
49{
50 string name = channelName + providerName;
51 map<string,PvaClientChannelPtr>::iterator iter = pvaClientChannelMap.find(name);
52 if(iter!=pvaClientChannelMap.end()) return iter->second;
53 return PvaClientChannelPtr();
54}
55
56void PvaClientChannelCache::addChannel(PvaClientChannelPtr const & pvaClientChannel)
57{
58 Channel::shared_pointer channel = pvaClientChannel->getChannel();
59 string name = channel->getChannelName()
60 + channel->getProvider()->getProviderName();
61 map<string,PvaClientChannelPtr>::iterator iter = pvaClientChannelMap.find(name);
62 if(iter!=pvaClientChannelMap.end()) {
63 throw std::runtime_error("pvaClientChannelCache::addChannel channel already cached");
64 }
65 pvaClientChannelMap.insert(std::pair<string,PvaClientChannelPtr>(
66 name,pvaClientChannel));
67}
68
69void PvaClientChannelCache::showCache()
70{
71 map<string,PvaClientChannelPtr>::iterator iter;
72 for(iter = pvaClientChannelMap.begin(); iter != pvaClientChannelMap.end(); ++iter)
73 {
74 PvaClientChannelPtr pvaChannel = iter->second;
75 Channel::shared_pointer channel = pvaChannel->getChannel();
76 string channelName = channel->getChannelName();
77 string providerName = channel->getProvider()->getProviderName();
78 cout << "channel " << channelName << " provider " << providerName << endl;
79 pvaChannel->showCache();
80 }
81}
82
83size_t PvaClientChannelCache::cacheSize()
84{
85 return pvaClientChannelMap.size();
86
87}
88
89// MSVC doesn't like making this a class static data member:
90static bool debug = 0;
91
92void PvaClient::setDebug(bool value)
93{
94 debug = value;
95}
96
98{
99 return debug;
100}
101
102PvaClientPtr PvaClient::get(std::string const & providerNames)
103{
104 static PvaClientPtr master;
105 static Mutex mutex;
106 Lock xx(mutex);
107 if(!master) {
108 master = PvaClientPtr(new PvaClient(providerNames));
109 }
110 return master;
111}
112
114
115PvaClient::PvaClient(std::string const & providerNames)
116: pvaClientChannelCache(new PvaClientChannelCache()),
117 pvaStarted(false),
118 caStarted(false),
119 channelRegistry(ChannelProviderRegistry::clients())
120{
121 stringstream ss(providerNames);
122 string providerName;
123 if(getDebug()) {
124 cout<< "PvaClient::PvaClient()\n";
125 }
126 while (getline(ss, providerName, ' '))
127 {
128 if(providerName=="pva") {
129 if(getDebug()) {
130 cout<< "calling ClientFactory::start()\n";
131 }
132 ClientFactory::start();
133 pvaStarted = true;
134 } else if(providerName=="ca") {
135 if(getDebug()) {
136 cout<< "calling CAClientFactory::start()\n";
137 }
138 CAClientFactory::start();
139 caStarted = true;
140 } else {
141 if(!channelRegistry->getProvider(providerName)) {
142 cerr << "PvaClient::get provider " << providerName << " not known" << endl;
143 }
144 }
145 }
146}
147
149 if(getDebug()) {
150 cout<< "PvaClient::~PvaClient()\n"
151 << "pvaChannel cache:\n";
152 showCache();
153 }
154 if(pvaStarted){
155 if(getDebug()) cout<< "calling ClientFactory::stop()\n";
156 ClientFactory::stop();
157 if(getDebug()) cout<< "after calling ClientFactory::stop()\n";
158 }
159 if(caStarted) {
160 if(getDebug()) cout<< "calling CAClientFactory::stop()\n";
161 CAClientFactory::stop();
162 if(getDebug()) cout<< "after calling CAClientFactory::stop()\n";
163 }
164channelRegistry.reset();
165}
166
168{
169 static string name("pvaClient");
170 RequesterPtr req = requester.lock();
171 if(req) {
172 return req->getRequesterName();
173 }
174 return name;
175}
176
178 string const & message,
179 MessageType messageType)
180{
181 RequesterPtr req = requester.lock();
182 if(req) {
183 req->message(message,messageType);
184 return;
185 }
186 cout << getMessageTypeName(messageType) << " " << message << endl;
187}
188
190 std::string const & channelName,
191 std::string const & providerName,
192 double timeOut)
193{
194 PvaClientChannelPtr pvaClientChannel =
195 pvaClientChannelCache->getChannel(channelName,providerName);
196 if(pvaClientChannel) return pvaClientChannel;
197 pvaClientChannel = createChannel(channelName,providerName);
198 pvaClientChannel->connect(timeOut);
199 pvaClientChannelCache->addChannel(pvaClientChannel);
200 return pvaClientChannel;
201}
202
203PvaClientChannelPtr PvaClient::createChannel(string const & channelName, string const & providerName)
204{
205 return PvaClientChannel::create(shared_from_this(),channelName,providerName);
206}
207
208void PvaClient::setRequester(RequesterPtr const & requester)
209{
210 this->requester = requester;
211}
212
214{
215 requester.reset();
216}
217
219{
220 if(pvaClientChannelCache->cacheSize()>=1) {
221 pvaClientChannelCache->showCache();
222 } else {
223 cout << "pvaClientChannelCache is empty\n";
224 }
225}
226
227
229{
230 return pvaClientChannelCache->cacheSize();
231}
232
233}}
pvaClient is a synchronous wrapper for the pvAccess API, which is a callback based API.
Definition pvaClient.h:104
static bool getDebug()
Is debug set?
Definition pvaClient.cpp:97
void setRequester(epics::pvData::RequesterPtr const &requester)
Set a requester.
static PvaClientPtr create() EPICS_DEPRECATED
Create an instance of PvaClient with providerName "pva ca".
static void setDebug(bool value)
Should debug info be shown?
Definition pvaClient.cpp:92
size_t cacheSize()
Get the number of cached channels.
PvaClientChannelPtr createChannel(std::string const &channelName, std::string const &providerName="pva")
Create an PvaClientChannel with the specified provider.
std::string getRequesterName()
Get the requester name.
void clearRequester()
Clear the requester. PvaClient will handle messages.
void showCache()
Show the list of cached channels.
PvaClientChannelPtr channel(std::string const &channelName, std::string const &providerName="pva", double timeOut=5.0)
Get a cached channel or create and connect to a new channel.
static PvaClientPtr get(std::string const &providerNames="pva ca")
Get the single instance of PvaClient.
void message(std::string const &message, epics::pvData::MessageType messageType)
A new message.
std::tr1::shared_ptr< PvaClientChannel > PvaClientChannelPtr
Definition pvaClient.h:60
std::tr1::shared_ptr< PvaClient > PvaClientPtr
Definition pvaClient.h:47