diff --git a/src/pv/pvaClient.h b/src/pv/pvaClient.h index e981024..a98e5bf 100644 --- a/src/pv/pvaClient.h +++ b/src/pv/pvaClient.h @@ -93,10 +93,25 @@ public: * Destructor */ ~PvaClient(); - /** Create an instance of PvaClient - * @return shared_ptr to new instance. + /** Get the single instance of PvaClient. + * @param providerNames Space separated list of provider names. + * @return shared pointer to the single instance. */ - static PvaClientPtr create(); + static PvaClientPtr get(std::string const & providerNames); + /** Get the single instance of PvaClient. + * calls get with providerNames "pva ca". + * @return shared pointer to the single instance. + */ + static PvaClientPtr get() {return get("pva ca");} + /** Create an instance of PvaClient with providerName "pva ca". + * \deprecated This method will go away in future versions. Use get instead. + * @return shared pointer to the single instance + */ + static PvaClientPtr create() + { + std::cerr << "create is deprecated. Use get instead\n"; + return get("pva ca"); + } /** Get the requester name. * @return The name. */ @@ -171,11 +186,13 @@ public: return shared_from_this(); } private: - PvaClient(); + PvaClient(std::string const & providerNames); PvaClientChannelCachePtr pvaClientChannelCache; epics::pvData::Requester::weak_pointer requester; bool isDestroyed; + bool pvaStarted; + bool caStarted; epics::pvData::Mutex mutex; }; diff --git a/src/pvaClient.cpp b/src/pvaClient.cpp index 3e9c794..3c88860 100644 --- a/src/pvaClient.cpp +++ b/src/pvaClient.cpp @@ -31,44 +31,6 @@ static const string pvaClientName = "pvaClient"; static const string defaultProvider = "pva"; static UnionConstPtr variantUnion = fieldCreate->createVariantUnion(); -namespace pvaClientPvt { - - static size_t numberPvaClient = 0; - static bool firstTime = true; - static Mutex mutex; - - class StartStopClientFactory { - public: - static void PvaClientBeingConstructed() - { - bool saveFirst = false; - { - Lock xx(mutex); - ++numberPvaClient; - saveFirst = firstTime; - firstTime = false; - } - if(saveFirst) { - ClientFactory::start(); - CAClientFactory::start(); - } - } - - static void PvaClientBeingDestroyed() { - size_t numLeft = 0; - { - Lock xx(mutex); - --numberPvaClient; - numLeft = numberPvaClient; - } - if(numLeft<=0) { - ClientFactory::stop(); - CAClientFactory::stop(); - } - } - }; - -} // namespace pvaClientPvt class PvaClientChannelCache { @@ -141,20 +103,41 @@ size_t PvaClientChannelCache::cacheSize() } -using namespace epics::pvaClient::pvaClientPvt; - -PvaClientPtr PvaClient::create() +PvaClientPtr PvaClient::get(std::string const & providerNames) { - PvaClientPtr xx(new PvaClient()); - StartStopClientFactory::PvaClientBeingConstructed(); - return xx; + static PvaClientPtr master; + static Mutex mutex; + Lock xx(mutex); + if(!master) { + master = PvaClientPtr(new PvaClient(providerNames)); + } + return master; } -PvaClient::PvaClient() -: pvaClientChannelCache(new PvaClientChannelCache()), - isDestroyed(false) +PvaClient::PvaClient(std::string const & providerNames) +: pvaClientChannelCache(new PvaClientChannelCache()), + isDestroyed(false), + pvaStarted(false), + caStarted(false) { + stringstream ss(providerNames); + string providerName; + while (getline(ss, providerName, ' ')) + { + ChannelProviderRegistry::shared_pointer registry(getChannelProviderRegistry()); + if(providerName=="pva") { + ClientFactory::start(); + pvaStarted = true; + } else if(providerName=="ca") { + CAClientFactory::start(); + caStarted = true; + } else { + if(!registry->getProvider(providerName)) { + cerr << "PvaClient::get provider " << providerName << " not known" << endl; + } + } + } } PvaClient::~PvaClient() { @@ -169,7 +152,8 @@ void PvaClient::destroy() isDestroyed = true; } pvaClientChannelCache.reset(); - StartStopClientFactory::PvaClientBeingDestroyed(); + if(pvaStarted) ClientFactory::stop(); + if(caStarted) CAClientFactory::stop(); } string PvaClient:: getRequesterName()