diff --git a/src/database/pvDatabase.cpp b/src/database/pvDatabase.cpp index d81d16b..e696034 100644 --- a/src/database/pvDatabase.cpp +++ b/src/database/pvDatabase.cpp @@ -21,43 +21,21 @@ using namespace std; namespace epics { namespace pvDatabase { +static PVDatabasePtr pvDatabaseMaster; + PVDatabasePtr PVDatabase::getMaster() { - static PVDatabasePtr master; - static Mutex mutex; - Lock xx(mutex); - if(master.get()==NULL) { - master = PVDatabasePtr(new PVDatabase()); - } - return master; + if(!pvDatabaseMaster) pvDatabaseMaster = PVDatabasePtr(new PVDatabase()); + return pvDatabaseMaster; } PVDatabase::PVDatabase() -: isDestroyed(false) { } PVDatabase::~PVDatabase() { - destroy(); -} - -void PVDatabase::destroy() -{ - { - epicsGuard guard(mutex); - if(isDestroyed) { - return; - } - isDestroyed = true; - } - for(PVRecordMap::iterator iter = recordMap.begin(); iter != recordMap.end(); iter++) { - PVRecordPtr pvRecord = (*iter).second; - if(pvRecord) { - pvRecord->destroy(); - } - } - recordMap.clear(); +cout << "PVDatabase::~PVDatabase()\n"; } void PVDatabase::lock() { @@ -71,23 +49,19 @@ void PVDatabase::unlock() { PVRecordPtr PVDatabase::findRecord(string const& recordName) { epicsGuard guard(mutex); - PVRecordPtr xxx; - if(isDestroyed) { - return xxx; - } PVRecordMap::iterator iter = recordMap.find(recordName); if(iter!=recordMap.end()) { return (*iter).second; } - return xxx; + return PVRecordPtr(); } bool PVDatabase::addRecord(PVRecordPtr const & record) { - epicsGuard guard(mutex); - if(isDestroyed) { - return false; + if(record->getTraceLevel()>0) { + cout << "PVDatabase::addRecord " << record->getRecordName() << endl; } + epicsGuard guard(mutex); string recordName = record->getRecordName(); PVRecordMap::iterator iter = recordMap.find(recordName); if(iter!=recordMap.end()) { @@ -100,10 +74,10 @@ bool PVDatabase::addRecord(PVRecordPtr const & record) bool PVDatabase::removeRecord(PVRecordPtr const & record) { - epicsGuard guard(mutex); - if(isDestroyed) { - return false; + if(record->getTraceLevel()>0) { + cout << "PVDatabase::removeRecord " << record->getRecordName() << endl; } + epicsGuard guard(mutex); string recordName = record->getRecordName(); PVRecordMap::iterator iter = recordMap.find(recordName); if(iter!=recordMap.end()) { @@ -119,9 +93,6 @@ PVStringArrayPtr PVDatabase::getRecordNames() { epicsGuard guard(mutex); PVStringArrayPtr xxx; - if(isDestroyed) { - return xxx; - } PVStringArrayPtr pvStringArray = static_pointer_cast (getPVDataCreate()->createPVScalarArray(pvString)); size_t len = recordMap.size(); diff --git a/src/database/pvRecord.cpp b/src/database/pvRecord.cpp index 9cec381..b86272e 100644 --- a/src/database/pvRecord.cpp +++ b/src/database/pvRecord.cpp @@ -51,7 +51,7 @@ PVRecord::~PVRecord() if(traceLevel>0) { cout << "~PVRecord() " << recordName << endl; } - destroy(); +// destroy(); } void PVRecord::initPVRecord() diff --git a/src/pv/channelProviderLocal.h b/src/pv/channelProviderLocal.h index 5405006..aff902a 100644 --- a/src/pv/channelProviderLocal.h +++ b/src/pv/channelProviderLocal.h @@ -70,10 +70,6 @@ public: * @brief Destructor */ virtual ~MonitorFactory(); - /** - * @brief Destroy the monitor factory. - */ - virtual void destroy(); /** * @brief Create a monitor on a record. * @@ -94,7 +90,6 @@ private: MonitorFactory(); friend class MonitorLocal; friend epicsShareFunc MonitorFactoryPtr getMonitorFactory(); - bool isDestroyed; epics::pvData::Mutex mutex; }; @@ -109,10 +104,15 @@ epicsShareFunc ChannelProviderLocalPtr getChannelProviderLocal(); */ class epicsShareClass ChannelProviderLocal : public epics::pvAccess::ChannelProvider, + public epics::pvAccess::ChannelFind, public std::tr1::enable_shared_from_this { public: POINTER_DEFINITIONS(ChannelProviderLocal); + /** + * @brief Constructor + */ + ChannelProviderLocal(); /** * @brief Destructor */ @@ -120,9 +120,8 @@ public: /** * @brief Destroy the channel provider. * - * Probably never called. */ - virtual void destroy(); + virtual void destroy() EPICS_DEPRECATED {}; /** * @brief Returns the channel provider name. * @return local @@ -185,17 +184,32 @@ public: epics::pvAccess::ChannelRequester::shared_pointer const &channelRequester, short priority, std::string const &address); + /** + * @brief get trace level (0,1,2) means (nothing,lifetime,process) + * @return the level + */ + int getTraceLevel() {return traceLevel;} + /** + * @brief set trace level (0,1,2) means (nothing,lifetime,process) + * @param level The level + */ + void setTraceLevel(int level) {traceLevel = level;} + /** + * @brief ChannelFind method. + * + * @return pointer to self. + */ + virtual std::tr1::shared_ptr getChannelProvider(); + /** + * @brief ChannelFind method. + * + */ + virtual void cancel(); private: - shared_pointer getPtrSelf() - { - return shared_from_this(); - } - ChannelProviderLocal(); friend epicsShareFunc ChannelProviderLocalPtr getChannelProviderLocal(); PVDatabasePtr pvDatabase; epics::pvData::Mutex mutex; - bool beingDestroyed; - epics::pvAccess::ChannelFind::shared_pointer channelFinder; + int traceLevel; friend class ChannelProviderLocalRun; }; @@ -229,12 +243,8 @@ public: /** * @brief Destroy the channel. * - * It cleans up all resources used to access the record. - * Note that this assumes that client has destroyed any objects that - * have been created for the channel like channelGet, etc. - * The remote pvAccess server does this cleanup. */ - virtual void destroy(); + virtual void destroy() EPICS_DEPRECATED {}; /** * @brief Detach from the record. * @@ -404,7 +414,6 @@ private: epics::pvAccess::ChannelRequester::shared_pointer requester; ChannelProviderLocalPtr provider; PVRecordPtr pvRecord; - bool isDestroyed; epics::pvData::Mutex mutex; }; diff --git a/src/pv/pvDatabase.h b/src/pv/pvDatabase.h index 71bb0d9..a03d78d 100644 --- a/src/pv/pvDatabase.h +++ b/src/pv/pvDatabase.h @@ -264,14 +264,6 @@ protected: * Must be called by derived classes. */ void initPVRecord(); - /** - * @brief Get shared pointer to self. - * @return The shared pointer. - */ - PVRecordPtr getPtrSelf() - { - return shared_from_this(); - } private: PVRecordFieldPtr findPVRecordField( PVRecordStructurePtr const & pvrs, @@ -504,12 +496,6 @@ public: * @brief Destructor */ virtual ~PVDatabase(); - /** - * @brief Destroy the PVDatabase. - * - * For each record in the database the record is removed and it's destroy method is called. - */ - virtual void destroy(); /** * Find a record. * An empty pointer is returned if the record is not in the database. @@ -541,7 +527,6 @@ private: void unlock(); PVRecordMap recordMap; epics::pvData::Mutex mutex; - bool isDestroyed; }; }} diff --git a/src/pv/removeRecord.h b/src/pv/removeRecord.h index b4f5679..2c7e3d8 100644 --- a/src/pv/removeRecord.h +++ b/src/pv/removeRecord.h @@ -54,7 +54,6 @@ private: RemoveRecord( std::string const & recordName, epics::pvData::PVStructurePtr const & pvStructure); - PVDatabasePtr pvDatabase; epics::pvData::PVStringPtr pvRecordName; epics::pvData::PVStringPtr pvResult; }; diff --git a/src/pv/traceRecord.h b/src/pv/traceRecord.h index eaf5835..3dc7812 100644 --- a/src/pv/traceRecord.h +++ b/src/pv/traceRecord.h @@ -55,7 +55,6 @@ private: TraceRecord( std::string const & recordName, epics::pvData::PVStructurePtr const & pvStructure); - PVDatabasePtr pvDatabase; epics::pvData::PVStringPtr pvRecordName; epics::pvData::PVIntPtr pvLevel; epics::pvData::PVStringPtr pvResult; diff --git a/src/pvAccess/channelLocal.cpp b/src/pvAccess/channelLocal.cpp index 4f3039c..b97b901 100644 --- a/src/pvAccess/channelLocal.cpp +++ b/src/pvAccess/channelLocal.cpp @@ -103,7 +103,7 @@ public: PVStructurePtr const & pvRequest, PVRecordPtr const &pvRecord); virtual void process(); - virtual void destroy(); + virtual void destroy() EPICS_DEPRECATED {}; virtual std::tr1::shared_ptr getChannel() {return channelLocal;} virtual void cancel(){} @@ -121,14 +121,12 @@ private: PVRecordPtr const &pvRecord, int nProcess) : - isDestroyed(false), channelLocal(channelLocal), channelProcessRequester(channelProcessRequester), pvRecord(pvRecord), nProcess(nProcess) { } - bool isDestroyed; ChannelLocalPtr channelLocal; ChannelProcessRequester::weak_pointer channelProcessRequester; PVRecordPtr pvRecord; @@ -174,30 +172,10 @@ ChannelProcessLocalPtr ChannelProcessLocal::create( return process; } - -void ChannelProcessLocal::destroy() -{ - if(pvRecord->getTraceLevel()>0) - { - cout << "ChannelProcessLocal::destroy"; - cout << " destroyed " << isDestroyed << endl; - } - { - Lock xx(mutex); - if(isDestroyed) return; - isDestroyed = true; - } -} - - void ChannelProcessLocal::process() { ChannelProcessRequester::shared_pointer requester = channelProcessRequester.lock(); if(!requester) return; - if(isDestroyed) { - requester->processDone(channelDestroyedStatus,getPtrSelf()); - return; - } if(pvRecord->getTraceLevel()>1) { cout << "ChannelProcessLocal::process"; @@ -236,7 +214,7 @@ public: PVStructurePtr const & pvRequest, PVRecordPtr const &pvRecord); virtual void get(); - virtual void destroy(); + virtual void destroy() EPICS_DEPRECATED {}; virtual std::tr1::shared_ptr getChannel() {return channelLocal;} virtual void cancel(){} @@ -258,7 +236,6 @@ private: PVRecordPtr const &pvRecord) : firstTime(true), - isDestroyed(false), callProcess(callProcess), channelLocal(channelLocal), channelGetRequester(channelGetRequester), @@ -269,7 +246,6 @@ private: { } bool firstTime; - bool isDestroyed; bool callProcess; ChannelLocalPtr channelLocal; ChannelGetRequester::weak_pointer channelGetRequester; @@ -323,29 +299,10 @@ ChannelGetLocalPtr ChannelGetLocal::create( } -void ChannelGetLocal::destroy() -{ - if(pvRecord->getTraceLevel()>0) - { - cout << "ChannelGetLocal::destroy"; - cout << " destroyed " << isDestroyed << endl; - } - { - Lock xx(mutex); - if(isDestroyed) return; - isDestroyed = true; - } -} - void ChannelGetLocal::get() { ChannelGetRequester::shared_pointer requester = channelGetRequester.lock(); if(!requester) return; - if(isDestroyed) { - requester->getDone( - channelDestroyedStatus,getPtrSelf(),nullPVStructure,nullBitSet); - return; - } try { bitSet->clear(); { @@ -398,7 +355,7 @@ public: PVRecordPtr const &pvRecord); virtual void put(PVStructurePtr const &pvStructure,BitSetPtr const &bitSet); virtual void get(); - virtual void destroy(); + virtual void destroy() EPICS_DEPRECATED {}; virtual std::tr1::shared_ptr getChannel() {return channelLocal;} virtual void cancel(){} @@ -417,7 +374,6 @@ private: PVCopyPtr const &pvCopy, PVRecordPtr const &pvRecord) : - isDestroyed(false), callProcess(callProcess), channelLocal(channelLocal), channelPutRequester(channelPutRequester), @@ -425,7 +381,6 @@ private: pvRecord(pvRecord) { } - bool isDestroyed; bool callProcess; ChannelLocalPtr channelLocal; ChannelPutRequester::weak_pointer channelPutRequester; @@ -474,29 +429,10 @@ ChannelPutLocalPtr ChannelPutLocal::create( return put; } -void ChannelPutLocal::destroy() -{ - if(pvRecord->getTraceLevel()>0) - { - cout << "ChannelPutLocal::destroy"; - cout << " destroyed " << isDestroyed << endl; - } - { - Lock xx(mutex); - if(isDestroyed) return; - isDestroyed = true; - } -} - void ChannelPutLocal::get() { ChannelPutRequester::shared_pointer requester = channelPutRequester.lock(); if(!requester) return; - if(isDestroyed) { - requester->getDone( - channelDestroyedStatus,getPtrSelf(),nullPVStructure,nullBitSet); - return; - } try { PVStructurePtr pvStructure = pvCopy->createPVStructure(); BitSetPtr bitSet(new BitSet(pvStructure->getNumberFields())); @@ -525,10 +461,6 @@ void ChannelPutLocal::put( { ChannelPutRequester::shared_pointer requester = channelPutRequester.lock(); if(!requester) return; - if(isDestroyed) { - requester->putDone(channelDestroyedStatus,getPtrSelf()); - return; - } try { { epicsGuard guard(*pvRecord); @@ -574,7 +506,7 @@ public: BitSetPtr const &putBitSet); virtual void getPut(); virtual void getGet(); - virtual void destroy(); + virtual void destroy() EPICS_DEPRECATED {}; virtual std::tr1::shared_ptr getChannel() {return channelLocal;} virtual void cancel(){} @@ -596,7 +528,6 @@ private: BitSetPtr const & getBitSet, PVRecordPtr const &pvRecord) : - isDestroyed(false), callProcess(callProcess), channelLocal(channelLocal), channelPutGetRequester(channelPutGetRequester), @@ -607,7 +538,6 @@ private: pvRecord(pvRecord) { } - bool isDestroyed; bool callProcess; ChannelLocalPtr channelLocal; ChannelPutGetRequester::weak_pointer channelPutGetRequester; @@ -668,30 +598,11 @@ ChannelPutGetLocalPtr ChannelPutGetLocal::create( } -void ChannelPutGetLocal::destroy() -{ - if(pvRecord->getTraceLevel()>0) - { - cout << "ChannelPutGetLocal::destroy"; - cout << " destroyed " << isDestroyed << endl; - } - { - Lock xx(mutex); - if(isDestroyed) return; - isDestroyed = true; - } -} - void ChannelPutGetLocal::putGet( PVStructurePtr const &pvPutStructure,BitSetPtr const &putBitSet) { ChannelPutGetRequester::shared_pointer requester = channelPutGetRequester.lock(); if(!requester) return; - if(isDestroyed) { - requester->putGetDone( - channelDestroyedStatus,getPtrSelf(),nullPVStructure,nullBitSet); - return; - } try { { epicsGuard guard(*pvRecord); @@ -718,11 +629,6 @@ void ChannelPutGetLocal::getPut() { ChannelPutGetRequester::shared_pointer requester = channelPutGetRequester.lock(); if(!requester) return; - if(isDestroyed) { - requester->getPutDone( - channelDestroyedStatus,getPtrSelf(),nullPVStructure,nullBitSet); - return; - } try { PVStructurePtr pvPutStructure = pvPutCopy->createPVStructure(); BitSetPtr putBitSet(new BitSet(pvPutStructure->getNumberFields())); @@ -748,11 +654,6 @@ void ChannelPutGetLocal::getGet() { ChannelPutGetRequester::shared_pointer requester = channelPutGetRequester.lock(); if(!requester) return; - if(isDestroyed) { - requester->getGetDone( - channelDestroyedStatus,getPtrSelf(),nullPVStructure,nullBitSet); - return; - } try { getBitSet->clear(); { @@ -792,7 +693,6 @@ public: ChannelRPCRequester::shared_pointer const & channelRPCRequester, Service::shared_pointer const & service, PVRecordPtr const & pvRecord) : - isDestroyed(), channelLocal(channelLocal), channelRPCRequester(channelRPCRequester), service(service), @@ -807,7 +707,6 @@ public: { cout << "~ChannelRPCLocal()" << endl; } - destroy(); } void processRequest(RPCService::shared_pointer const & service, @@ -819,9 +718,6 @@ public: ChannelRPCRequester::shared_pointer requester = channelRPCRequester.lock(); if(!requester) return; requester->requestDone(status, getPtrSelf(), result); - - if (isLastRequest.get()) - destroy(); } void processRequest(RPCServiceAsync::shared_pointer const & service, @@ -841,7 +737,7 @@ public: virtual void cancel() {} - virtual void destroy(); + virtual void destroy() EPICS_DEPRECATED {}; virtual void lock() {} @@ -854,7 +750,6 @@ private: return shared_from_this(); } - AtomicBoolean isDestroyed; ChannelLocalPtr channelLocal; ChannelRPCRequester::weak_pointer channelRPCRequester; Service::shared_pointer service; @@ -990,17 +885,6 @@ void ChannelRPCLocal::request(PVStructurePtr const & pvArgument) } -void ChannelRPCLocal::destroy() -{ - if(pvRecord->getTraceLevel()>0) - { - cout << "ChannelRPCLocal::destroy"; - cout << " destroyed " << isDestroyed.get() << endl; - } - isDestroyed.set(); -} - - typedef std::tr1::shared_ptr PVArrayPtr; class ChannelArrayLocal : @@ -1027,7 +911,7 @@ public: size_t offset, size_t count, size_t stride); virtual void getLength(); virtual void setLength(size_t length); - virtual void destroy(); + virtual void destroy() EPICS_DEPRECATED {}; virtual std::tr1::shared_ptr getChannel() {return channelLocal;} virtual void cancel(){} @@ -1046,7 +930,6 @@ private: PVArrayPtr const &pvCopy, PVRecordPtr const &pvRecord) : - isDestroyed(false), channelLocal(channelLocal), channelArrayRequester(channelArrayRequester), pvArray(pvArray), @@ -1054,7 +937,7 @@ private: pvRecord(pvRecord) { } - bool isDestroyed; + ChannelLocalPtr channelLocal; ChannelArrayRequester::weak_pointer channelArrayRequester; PVArrayPtr pvArray; @@ -1147,29 +1030,11 @@ ChannelArrayLocalPtr ChannelArrayLocal::create( return array; } - -void ChannelArrayLocal::destroy() -{ - if(pvRecord->getTraceLevel()>0) - { - cout << "ChannelArrayLocal::destroy"; - cout << " destroyed " << isDestroyed << endl; - } - { - Lock xx(mutex); - if(isDestroyed) return; - isDestroyed = true; - } -} - void ChannelArrayLocal::getArray(size_t offset, size_t count, size_t stride) { ChannelArrayRequester::shared_pointer requester = channelArrayRequester.lock(); if(!requester) return; - if(isDestroyed) { - requester->getArrayDone(channelDestroyedStatus,getPtrSelf(),pvCopy); - return; - } + if(pvRecord->getTraceLevel()>1) { cout << "ChannelArrayLocal::getArray" << endl; @@ -1218,10 +1083,7 @@ void ChannelArrayLocal::putArray( { ChannelArrayRequester::shared_pointer requester = channelArrayRequester.lock(); if(!requester) return; - if(isDestroyed) { - requester->putArrayDone(channelDestroyedStatus,getPtrSelf()); - return; - } + if(pvRecord->getTraceLevel()>1) { cout << "ChannelArrayLocal::putArray" << endl; @@ -1277,10 +1139,7 @@ void ChannelArrayLocal::setLength(size_t length) { ChannelArrayRequester::shared_pointer requester = channelArrayRequester.lock(); if(!requester) return; - if(isDestroyed) { - requester->setLengthDone(channelDestroyedStatus,getPtrSelf()); - return; - } + if(pvRecord->getTraceLevel()>1) { cout << "ChannelArrayLocal::setLength" << endl; @@ -1308,8 +1167,7 @@ ChannelLocal::ChannelLocal( : requester(requester), provider(provider), - pvRecord(pvRecord), - isDestroyed(false) + pvRecord(pvRecord) { if(pvRecord->getTraceLevel()>0) { cout << "ChannelLocal::ChannelLocal()" @@ -1325,26 +1183,10 @@ ChannelLocal::~ChannelLocal() { cout << "~ChannelLocal()" << endl; } - destroy(); -} - -void ChannelLocal::destroy() -{ - if(pvRecord->getTraceLevel()>0) { - cout << "ChannelLocal::destroy()" - << " recordName " << pvRecord->getRecordName() - << " isDestroyed " << isDestroyed - << " requester exists " << (requester ? "true" : "false") - << endl; - } - { - Lock xx(mutex); - if(isDestroyed) return; - isDestroyed = true; - } pvRecord->removePVRecordClient(getPtrSelf()); } + void ChannelLocal::detach(PVRecordPtr const & pvRecord) { if(pvRecord->getTraceLevel()>0) { @@ -1381,10 +1223,6 @@ void ChannelLocal::message( << " requester exists " << (requester ? "true" : "false") << endl; } - { - Lock xx(mutex); - if(isDestroyed) return; - } if(requester) { requester->message(message,messageType); return; @@ -1402,8 +1240,6 @@ string ChannelLocal::getRemoteAddress() Channel::ConnectionState ChannelLocal::getConnectionState() { - Lock xx(mutex); - if(isDestroyed) return Channel::DESTROYED; return Channel::CONNECTED; } @@ -1419,8 +1255,6 @@ ChannelRequester::shared_pointer ChannelLocal::getChannelRequester() bool ChannelLocal::isConnected() { - Lock xx(mutex); - if(isDestroyed) return false; return true; } diff --git a/src/pvAccess/channelProviderLocal.cpp b/src/pvAccess/channelProviderLocal.cpp index a95f5d7..be235b3 100644 --- a/src/pvAccess/channelProviderLocal.cpp +++ b/src/pvAccess/channelProviderLocal.cpp @@ -9,6 +9,9 @@ * @date 2013.04 */ +#include + + #include #include @@ -28,79 +31,66 @@ using std::string; namespace epics { namespace pvDatabase { static string providerName("local"); - +static ChannelProvider::shared_pointer channelProvider; class LocalChannelProviderFactory; typedef std::tr1::shared_ptr LocalChannelProviderFactoryPtr; class LocalChannelProviderFactory : public ChannelProviderFactory -{ - +{ public: POINTER_DEFINITIONS(LocalChannelProviderFactory); virtual string getFactoryName() { return providerName;} - static LocalChannelProviderFactoryPtr create( - ChannelProviderLocalPtr const &channelProvider) - { - LocalChannelProviderFactoryPtr xxx( - new LocalChannelProviderFactory(channelProvider)); - ChannelProviderRegistry::servers()->add(xxx); - return xxx; - } virtual ChannelProvider::shared_pointer sharedInstance() { + if(!channelProvider) channelProvider = ChannelProvider::shared_pointer(new ChannelProviderLocal()); return channelProvider; } virtual ChannelProvider::shared_pointer newInstance() { +cout << "LocalChannelProviderFactory::newInstance()\n"; throw std::logic_error("newInstance not Implemented"); } -private: - LocalChannelProviderFactory( - ChannelProviderLocalPtr const &channelProvider) - : channelProvider(channelProvider) - {} - ChannelProviderLocalPtr channelProvider; }; + ChannelProviderLocalPtr getChannelProviderLocal() { - static ChannelProviderLocalPtr channelProviderLocal; - static Mutex mutex; - Lock xx(mutex); - if(!channelProviderLocal) { - channelProviderLocal = ChannelProviderLocalPtr( - new ChannelProviderLocal()); - ChannelProvider::shared_pointer xxx = - dynamic_pointer_cast(channelProviderLocal); - channelProviderLocal->channelFinder = - SyncChannelFind::shared_pointer(new SyncChannelFind(xxx)); - LocalChannelProviderFactoryPtr factory(LocalChannelProviderFactory::create(channelProviderLocal)); - + static int firstTime = 1; + if (firstTime) { + firstTime = 0; + ChannelProviderFactory::shared_pointer factory( + new LocalChannelProviderFactory()); + ChannelProviderRegistry::servers()->add(factory); } - return channelProviderLocal; + ChannelProvider::shared_pointer channelProvider = + ChannelProviderRegistry::servers()->getProvider(providerName); + return std::tr1::dynamic_pointer_cast(channelProvider); } ChannelProviderLocal::ChannelProviderLocal() : pvDatabase(PVDatabase::getMaster()), - beingDestroyed(false) + traceLevel(0) { } ChannelProviderLocal::~ChannelProviderLocal() { - destroy(); + if(traceLevel>0) { + cout << "ChannelProviderLocal::~ChannelProviderLocal() \n"; + } } -void ChannelProviderLocal::destroy() +std::tr1::shared_ptr ChannelProviderLocal::getChannelProvider() { - Lock xx(mutex); - if(beingDestroyed) return; - beingDestroyed = true; - pvDatabase->destroy(); - pvDatabase.reset(); + return shared_from_this(); } +void ChannelProviderLocal::cancel() +{ +} + + string ChannelProviderLocal::getProviderName() { return providerName; @@ -110,35 +100,41 @@ ChannelFind::shared_pointer ChannelProviderLocal::channelFind( string const & channelName, ChannelFindRequester::shared_pointer const &channelFindRequester) { + if(traceLevel>1) { + cout << "ChannelProviderLocal::channelFind " << "channelName" << endl; + } Lock xx(mutex); PVRecordPtr pvRecord = pvDatabase->findRecord(channelName); if(pvRecord) { channelFindRequester->channelFindResult( Status::Ok, - channelFinder, + shared_from_this(), true); } else { Status notFoundStatus(Status::STATUSTYPE_ERROR,"pv not found"); channelFindRequester->channelFindResult( notFoundStatus, - channelFinder, + shared_from_this(), false); } - return channelFinder; + return shared_from_this(); } ChannelFind::shared_pointer ChannelProviderLocal::channelList( ChannelListRequester::shared_pointer const & channelListRequester) { + if(traceLevel>1) { + cout << "ChannelProviderLocal::channelList\n"; + } PVStringArrayPtr records; { Lock guard(mutex); records = pvDatabase->getRecordNames(); } - channelListRequester->channelListResult(Status::Ok, channelFinder, records->view(), false); - return channelFinder; + channelListRequester->channelListResult(Status::Ok, shared_from_this(), records->view(), false); + return shared_from_this(); } Channel::shared_pointer ChannelProviderLocal::createChannel( @@ -146,11 +142,14 @@ Channel::shared_pointer ChannelProviderLocal::createChannel( ChannelRequester::shared_pointer const &channelRequester, short priority) { + if(traceLevel>1) { + cout << "ChannelProviderLocal::createChannel " << "channelName" << endl; + } Lock xx(mutex); PVRecordPtr pvRecord = pvDatabase->findRecord(channelName); if(pvRecord) { ChannelLocalPtr channel(new ChannelLocal( - getPtrSelf(),channelRequester,pvRecord)); + shared_from_this(),channelRequester,pvRecord)); channelRequester->channelCreated( Status::Ok, channel); diff --git a/src/pvAccess/monitorFactory.cpp b/src/pvAccess/monitorFactory.cpp index 49c0c73..7ac6290 100644 --- a/src/pvAccess/monitorFactory.cpp +++ b/src/pvAccess/monitorFactory.cpp @@ -14,7 +14,6 @@ #include #include #include -#include #include #define epicsExportSharedSymbols @@ -34,16 +33,93 @@ namespace epics { namespace pvDatabase { static MonitorPtr nullMonitor; static MonitorElementPtr NULLMonitorElement; static Status failedToCreateMonitorStatus(Status::STATUSTYPE_ERROR,"failed to create monitor"); -static Status wasDestroyedStatus(Status::STATUSTYPE_ERROR,"was destroyed"); static Status alreadyStartedStatus(Status::STATUSTYPE_ERROR,"already started"); static Status notStartedStatus(Status::STATUSTYPE_ERROR,"not started"); +static Status destroyedStatus(Status::STATUSTYPE_ERROR,"record is destroyed"); - - -typedef Queue MonitorElementQueue; +class MonitorElementQueue; typedef std::tr1::shared_ptr MonitorElementQueuePtr; -typedef std::tr1::shared_ptr MonitorRequesterPtr; +class MonitorElementQueue +{ +private: + MonitorElementPtrArray elements; + // TODO use size_t instead + int size; + int numberFree; + int numberUsed; + int nextGetFree; + int nextSetUsed; + int nextGetUsed; + int nextReleaseUsed; +public: + POINTER_DEFINITIONS(MonitorElementQueue); + + MonitorElementQueue(std::vector monitorElementArray) + : elements(monitorElementArray), + size(monitorElementArray.size()), + numberFree(size), + numberUsed(0), + nextGetFree(0), + nextSetUsed(0), + nextGetUsed(0), + nextReleaseUsed(0) + { + } + + virtual ~MonitorElementQueue() {} + + void clear() + { + numberFree = size; + numberUsed = 0; + nextGetFree = 0; + nextSetUsed = 0; + nextGetUsed = 0; + nextReleaseUsed = 0; + } + + MonitorElementPtr getFree() + { + if(numberFree==0) return MonitorElementPtr(); + numberFree--; + int ind = nextGetFree; + MonitorElementPtr queueElement = elements[nextGetFree++]; + if(nextGetFree>=size) nextGetFree = 0; + return elements[ind]; + } + + void setUsed(MonitorElementPtr const &element) + { + if(element!=elements[nextSetUsed++]) { + throw std::logic_error("not correct queueElement"); + } + numberUsed++; + if(nextSetUsed>=size) nextSetUsed = 0; + } + + MonitorElementPtr getUsed() + { + if(numberUsed==0) return MonitorElementPtr(); + int ind = nextGetUsed; + MonitorElementPtr queueElement = elements[nextGetUsed++]; + if(nextGetUsed>=size) nextGetUsed = 0; + return elements[ind]; + } + void releaseUsed(MonitorElementPtr const &element) + { + if(element!=elements[nextReleaseUsed++]) { + throw std::logic_error( + "not queueElement returned by last call to getUsed"); + } + if(nextReleaseUsed>=size) nextReleaseUsed = 0; + numberUsed--; + numberFree++; + } +}; + + +typedef std::tr1::shared_ptr MonitorRequesterPtr; class MonitorLocal : @@ -51,15 +127,15 @@ class MonitorLocal : public PVListener, public std::tr1::enable_shared_from_this { - enum MonitorState {idle,active, destroyed}; + enum MonitorState {idle,active,destroyed}; public: POINTER_DEFINITIONS(MonitorLocal); virtual ~MonitorLocal(); virtual Status start(); virtual Status stop(); virtual MonitorElementPtr poll(); - virtual void destroy(); - virtual void detach(PVRecordPtr const & pvRecord){destroy();} + virtual void destroy() EPICS_DEPRECATED {}; + virtual void detach(PVRecordPtr const & pvRecord){} virtual void release(MonitorElementPtr const & monitorElement); virtual void dataPut(PVRecordFieldPtr const & pvRecordField); virtual void dataPut( @@ -109,25 +185,8 @@ MonitorLocal::~MonitorLocal() { cout << "MonitorLocal::~MonitorLocal()" << endl; } - destroy(); } -void MonitorLocal::destroy() -{ - if(pvRecord->getTraceLevel()>0) - { - cout << "MonitorLocal::destroy state " << state << endl; - } - { - Lock xx(mutex); - if(state==destroyed) return; - } - if(state==active) stop(); - { - Lock xx(mutex); - state = destroyed; - } -} Status MonitorLocal::start() { @@ -137,8 +196,8 @@ Status MonitorLocal::start() } { Lock xx(mutex); - if(state==destroyed) return wasDestroyedStatus; if(state==active) return alreadyStartedStatus; + if(state==destroyed) return destroyedStatus; } pvRecord->addListener(getPtrSelf(),pvCopy); epicsGuard guard(*pvRecord); @@ -161,10 +220,10 @@ Status MonitorLocal::stop() } { Lock xx(mutex); - if(state==destroyed) return wasDestroyedStatus; if(state==idle) return notStartedStatus; + if(state==destroyed) return destroyedStatus; state = idle; - } + } pvRecord->removeListener(getPtrSelf(),pvCopy); return Status::Ok; } @@ -310,6 +369,10 @@ void MonitorLocal::unlisten(PVRecordPtr const & pvRecord) { cout << "PVCopyMonitor::unlisten\n"; } + { + Lock xx(mutex); + state = destroyed; + } MonitorRequesterPtr requester = monitorRequester.lock(); if(requester) { if(pvRecord->getTraceLevel()>1) @@ -318,7 +381,6 @@ void MonitorLocal::unlisten(PVRecordPtr const & pvRecord) } requester->unlisten(getPtrSelf()); } - pvRecord->removeListener(getPtrSelf(),pvCopy); } @@ -385,18 +447,12 @@ bool MonitorLocal::init(PVStructurePtr const & pvRequest) MonitorFactory::MonitorFactory() -: isDestroyed(false) { } MonitorFactory::~MonitorFactory() { -} -void MonitorFactory::destroy() -{ - Lock lock(mutex); - isDestroyed = true; } MonitorPtr MonitorFactory::createMonitor( @@ -405,10 +461,6 @@ MonitorPtr MonitorFactory::createMonitor( PVStructurePtr const & pvRequest) { Lock xx(mutex); - if(isDestroyed) { - monitorRequester->message("MonitorFactory is destroyed",errorMessage); - return nullMonitor; - } MonitorLocalPtr monitor(new MonitorLocal( monitorRequester,pvRecord)); bool result = monitor->init(pvRequest); @@ -420,8 +472,8 @@ MonitorPtr MonitorFactory::createMonitor( } if(pvRecord->getTraceLevel()>0) { - cout << "MonitorFactory::createMonitor"; - cout << " recordName " << pvRecord->getRecordName() << endl; + cout << "MonitorFactory::createMonitor" + << " recordName " << pvRecord->getRecordName() << endl; } return monitor; } diff --git a/src/pvAccess/registerChannelProviderLocal.cpp b/src/pvAccess/registerChannelProviderLocal.cpp index aeeadef..8497aa4 100644 --- a/src/pvAccess/registerChannelProviderLocal.cpp +++ b/src/pvAccess/registerChannelProviderLocal.cpp @@ -53,18 +53,15 @@ extern "C" void pvdbl(const iocshArgBuf *args) for(size_t i=0; idestroy(); -} static void registerChannelProviderLocal(void) { static int firstTime = 1; +cout << "registerChannelProviderLocal firstTime " << (firstTime ? "true" : "false") << endl; if (firstTime) { firstTime = 0; iocshRegister(&pvdblFuncDef, pvdbl); getChannelProviderLocal(); - epicsAtExit(channelProviderLocalExitHandler, NULL); } } diff --git a/src/special/removeRecord.cpp b/src/special/removeRecord.cpp index 681f74e..e6aab7e 100644 --- a/src/special/removeRecord.cpp +++ b/src/special/removeRecord.cpp @@ -42,8 +42,7 @@ RemoveRecordPtr RemoveRecord::create( RemoveRecord::RemoveRecord( std::string const & recordName, epics::pvData::PVStructurePtr const & pvStructure) -: PVRecord(recordName,pvStructure), - pvDatabase(PVDatabase::getMaster()) +: PVRecord(recordName,pvStructure) { } @@ -61,7 +60,7 @@ bool RemoveRecord::init() void RemoveRecord::process() { string name = pvRecordName->get(); - PVRecordPtr pvRecord = pvDatabase->findRecord(name); + PVRecordPtr pvRecord = PVDatabase::getMaster()->findRecord(name); if(!pvRecord) { pvResult->put(name + " not found"); return; diff --git a/src/special/traceRecord.cpp b/src/special/traceRecord.cpp index 1b58f77..1c9ea66 100644 --- a/src/special/traceRecord.cpp +++ b/src/special/traceRecord.cpp @@ -43,8 +43,7 @@ TraceRecordPtr TraceRecord::create( TraceRecord::TraceRecord( std::string const & recordName, epics::pvData::PVStructurePtr const & pvStructure) -: PVRecord(recordName,pvStructure), - pvDatabase(PVDatabase::getMaster()) +: PVRecord(recordName,pvStructure) { } @@ -65,7 +64,7 @@ bool TraceRecord::init() void TraceRecord::process() { string name = pvRecordName->get(); - PVRecordPtr pvRecord = pvDatabase->findRecord(name); + PVRecordPtr pvRecord = PVDatabase::getMaster()->findRecord(name); if(!pvRecord) { pvResult->put(name + " not found"); return;