From 3cc13e2c5ae40aaf4caf5dc3e02fa94119c302bf Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Fri, 13 May 2016 12:50:47 -0400 Subject: [PATCH 01/12] replace destroy by RAII; many implementation changes --- src/pv/pvaClient.h | 319 ++++++++++++++++------------ src/pv/pvaClientMultiChannel.h | 75 +++---- src/pvaClient.cpp | 35 ++- src/pvaClientChannel.cpp | 205 ++++++++++-------- src/pvaClientGet.cpp | 85 ++++---- src/pvaClientMonitor.cpp | 36 +++- src/pvaClientMultiChannel.cpp | 18 +- src/pvaClientMultiGetDouble.cpp | 12 +- src/pvaClientMultiMonitorDouble.cpp | 12 +- src/pvaClientMultiPutDouble.cpp | 13 +- src/pvaClientNTMultiData.cpp | 13 +- src/pvaClientNTMultiGet.cpp | 12 +- src/pvaClientNTMultiMonitor.cpp | 12 +- src/pvaClientNTMultiPut.cpp | 12 +- src/pvaClientProcess.cpp | 28 ++- src/pvaClientPut.cpp | 60 +++--- src/pvaClientPutData.cpp | 1 - src/pvaClientPutGet.cpp | 28 ++- 18 files changed, 531 insertions(+), 445 deletions(-) diff --git a/src/pv/pvaClient.h b/src/pv/pvaClient.h index 22e539f..c70edf5 100644 --- a/src/pv/pvaClient.h +++ b/src/pv/pvaClient.h @@ -125,18 +125,27 @@ public: void message( std::string const & message, epics::pvData::MessageType messageType); - /** Destroy all the channels and multiChannels. - */ - void destroy(); /** Get a cached channel or create and connect to a new channel. * - * The provider is pva. The timeout is 0 seconds. + * The provider is pva. The timeout is 5 seconds. * @param channelName The channelName. * @return The interface. * @throw runtime_error if connection fails. */ PvaClientChannelPtr channel(std::string const & channelName) { return channel(channelName,"pva", 5.0); } + /** Get a cached channel or create and connect to a new channel. + * + * The timeout is 5 seconds. + * @param channelName The channelName. + * @param providerName The providerName. + * @return The interface. + * @throw runtime_error if connection fails. + */ + PvaClientChannelPtr channel( + std::string const & channelName, + std::string const &providerName) + { return channel(channelName,providerName, 5.0); } /** Get a cached channel or create and connect to a new channel. * @param channelName The channelName. * @param providerName The providerName. @@ -179,16 +188,29 @@ public: /** Get the number of cached channels. */ size_t cacheSize(); + /** Should debug info be shown? + * @param value true or false + */ + static void setDebug(bool value) {debug = value;} + /** Is debug set? + * @return true or false + */ + static bool getDebug() {return debug;} /** Get shared pointer to this */ PvaClientPtr getPtrSelf() { return shared_from_this(); } + /** Deprecated method + * \deprecated This method will go away in future versions. + */ + void destroy() EPICS_DEPRECATED {} + private: + static bool debug; PvaClient(std::string const & providerNames); PvaClientChannelCachePtr pvaClientChannelCache; - epics::pvData::Requester::weak_pointer requester; bool isDestroyed; bool pvaStarted; @@ -209,23 +231,37 @@ class ChannelRequesterImpl; * @author mrk */ class epicsShareClass PvaClientChannel : + public epics::pvAccess::ChannelRequester, public std::tr1::enable_shared_from_this { public: POINTER_DEFINITIONS(PvaClientChannel); - /** Create a PvaClientChannel. - * @param channelName The name of the channel. - * @param providerName The name of the provider. - * @return The interface to the PvaClientChannel. - */ - static PvaClientChannelPtr create( - PvaClientPtr const &pvaClient, - std::string const & channelName, - std::string const & providerName); ~PvaClientChannel(); - /** Destroy the pvAccess connection. + /** ChannelRequester method + * @param status The status + * @param channel The channel */ - void destroy(); + void channelCreated( + const epics::pvData::Status& status, + epics::pvAccess::Channel::shared_pointer const & channel); + /** ChannelRequester method + * @param channel The channel + * @param connectionState The connection state. + */ + void channelStateChange( + epics::pvAccess::Channel::shared_pointer const & channel, + epics::pvAccess::Channel::ConnectionState connectionState); + /** ChannelRequester method + * @return The name + */ + std::string getRequesterName(); + /** ChannelRequester method + * @param message The message. + * @param messageType The message type. + */ + void message( + std::string const & message, + epics::pvData::MessageType messageType); /** Get the name of the channel to which PvaClientChannel is connected. * @return The channel name. */ @@ -368,7 +404,7 @@ public: * @throw runtime_error if failure. */ PvaClientMonitorPtr monitor(); - /** Get a cached PvaClientMonitor or create and connect to a new PvaClientMonitor. + /** Create and connect to a new PvaClientMonitor. * Then call it's start method. * If connection can not be made an exception is thrown. * @param request The request as described in package org.epics.pvdata.copy @@ -382,7 +418,7 @@ public: */ PvaClientMonitorPtr monitor(PvaClientMonitorRequesterPtr const & pvaClientMonitorRequester); - /** get a cached PvaClientMonitor or create and connect to a new PvaClientMonitor. + /** Create and connect to a new PvaClientMonitor. * Then call it's start method. * If connection can not be made an exception is thrown. * @param request The request as described in package org.epics.pvdata.copy @@ -420,21 +456,20 @@ public: { return shared_from_this(); } + /** Deprecated method + * \deprecated This method will go away in future versions. + */ + void destroy() EPICS_DEPRECATED {} private: + + static PvaClientChannelPtr create( + PvaClientPtr const &pvaClient, + std::string const & channelName, + std::string const & providerName); PvaClientChannel( PvaClientPtr const &pvaClient, std::string const & channelName, std::string const & providerName); - void channelCreated( - const epics::pvData::Status& status, - epics::pvAccess::Channel::shared_pointer const & channel); - void channelStateChange( - epics::pvAccess::Channel::shared_pointer const & channel, - epics::pvAccess::Channel::ConnectionState connectionState); - std::string getRequesterName(); - void message( - std::string const & message, - epics::pvData::MessageType messageType); enum ConnectState {connectIdle,connectActive,notConnected,connected}; @@ -443,16 +478,15 @@ private: std::string providerName; ConnectState connectState; bool isDestroyed; + epics::pvData::CreateRequest::shared_pointer createRequest; PvaClientGetCachePtr pvaClientGetCache; PvaClientPutCachePtr pvaClientPutCache; - epics::pvData::Status channelConnectStatus; epics::pvData::Mutex mutex; epics::pvData::Event waitForConnect; epics::pvAccess::Channel::shared_pointer channel; - epics::pvAccess::ChannelRequester::shared_pointer channelRequester; - friend class ChannelRequesterImpl; + friend class PvaClient; }; /** @@ -463,9 +497,6 @@ class epicsShareClass PvaClientGetData { public: POINTER_DEFINITIONS(PvaClientGetData); - /** Factory method for creating an instance of PvaClientGetData. - */ - static PvaClientGetDataPtr create(epics::pvData::StructureConstPtr const & structure); ~PvaClientGetData() {} /** Set a prefix for throw messages. * @param value The prefix. @@ -559,6 +590,11 @@ public: * @return The timeStamp. */ epics::pvData::TimeStamp getTimeStamp(); + /** Factory method for creating an instance of PvaClientGetData. + * NOTE: Not normally called by clients + * @param structure Introspection interface + */ + static PvaClientGetDataPtr create(epics::pvData::StructureConstPtr const & structure); private: PvaClientGetData(epics::pvData::StructureConstPtr const & structure); void checkValue(); @@ -570,6 +606,8 @@ private: epics::pvData::PVFieldPtr pvValue; epics::pvData::PVAlarm pvAlarm; epics::pvData::PVTimeStamp pvTimeStamp; + friend class PvaClientGet; + friend class PvaClientPutGet; }; class PvaClientPostHandlerPvt; // private to PvaClientPutData @@ -577,13 +615,11 @@ class PvaClientPostHandlerPvt; // private to PvaClientPutData * @brief A class that holds data given to by PvaClientPut or PvaClientPutGet * */ -class epicsShareClass PvaClientPutData +class epicsShareClass PvaClientPutData { public: POINTER_DEFINITIONS(PvaClientPutData); - /** Factory method for creating an instance of PvaClientPutData. - */ - static PvaClientPutDataPtr create(epics::pvData::StructureConstPtr const & structure); + ~PvaClientPutData() {} /** Set a prefix for throw messages. * @param value The prefix. @@ -684,6 +720,11 @@ public: * @throw runtime_error if failure. */ void putStringArray(std::vector const & value); + /** Factory method for creating an instance of PvaClientGetData. + * NOTE: Not normally called by clients + * @param structure Introspection interface + */ + static PvaClientPutDataPtr create(epics::pvData::StructureConstPtr const & structure); private: PvaClientPutData(epics::pvData::StructureConstPtr const &structure); void checkValue(); @@ -697,6 +738,8 @@ private: std::string messagePrefix; epics::pvData::PVFieldPtr pvValue; + friend class PvaClientPut; + friend class PvaClientPutGet; }; /** @@ -707,10 +750,7 @@ class epicsShareClass PvaClientMonitorData { public: POINTER_DEFINITIONS(PvaClientMonitorData); - /** - * @brief Factory method for creating an instance of PvaClientMonitorData. - */ - static PvaClientMonitorDataPtr create(epics::pvData::StructureConstPtr const & structure); + ~PvaClientMonitorData() {} /** Set a prefix for throw messages. * @param value The prefix. @@ -814,12 +854,16 @@ public: * @return The timeStamp. */ epics::pvData::TimeStamp getTimeStamp(); - /* - * This is called by pvaClientMonitor when it gets a monitor. - * @param monitorElement The new data. - * @param monitorElement The new data. + /** Factory method for creating an instance of PvaClientGetData. + * NOTE: Not normally called by clients + * @param structure Introspection interface */ - void setData(epics::pvData::MonitorElementPtr const & monitorElement); + static PvaClientMonitorDataPtr create(epics::pvData::StructureConstPtr const & structure); + /** Put data into PVStructure from monitorElement + * NOTE: Not normally called by clients + * @param monitorElement the monitorElement that has new data. + */ + void setData(epics::pvData::MonitorElementPtr const & monitorElement); private: PvaClientMonitorData(epics::pvData::StructureConstPtr const & structure); void checkValue(); @@ -836,13 +880,13 @@ private: friend class PvaClientMonitor; }; -class ChannelProcessRequesterImpl; // private to PvaClientProcess /** * @brief An easy to use alternative to ChannelProcess. * * @author mrk */ -class epicsShareClass PvaClientProcess +class epicsShareClass PvaClientProcess : + public epics::pvAccess::ChannelProcessRequester { public: POINTER_DEFINITIONS(PvaClientProcess); @@ -860,9 +904,14 @@ public: /** Destructor */ ~PvaClientProcess(); - /** Destroy all resources used. - */ - void destroy(); + std::string getRequesterName(); + void message(std::string const & message,epics::pvData::MessageType messageType); + void channelProcessConnect( + const epics::pvData::Status& status, + epics::pvAccess::ChannelProcess::shared_pointer const & channelProcess); + void processDone( + const epics::pvData::Status& status, + epics::pvAccess::ChannelProcess::shared_pointer const & channelProcess); /** Call issueConnect and then waitConnect. * An exception is thrown if connect fails. * @throw runtime_error if failure. @@ -887,24 +936,20 @@ public: * @return status. */ epics::pvData::Status waitProcess(); + /** Deprecated method + * \deprecated This method will go away in future versions. + */ + void destroy() EPICS_DEPRECATED {} private: PvaClientProcess( PvaClientPtr const &pvaClient, epics::pvAccess::Channel::shared_pointer const & channel, epics::pvData::PVStructurePtr const &pvRequest); - std::string getRequesterName(); - void message(std::string const & message,epics::pvData::MessageType messageType); - void channelProcessConnect( - const epics::pvData::Status& status, - epics::pvAccess::ChannelProcess::shared_pointer const & channelProcess); - void processDone( - const epics::pvData::Status& status, - epics::pvAccess::ChannelProcess::shared_pointer const & channelProcess); + enum ProcessConnectState {connectIdle,connectActive,connected}; PvaClient::weak_pointer pvaClient; epics::pvAccess::Channel::shared_pointer channel; - epics::pvAccess::ChannelProcessRequester::shared_pointer processRequester; epics::pvData::PVStructurePtr pvRequest; epics::pvData::Mutex mutex; epics::pvData::Event waitForConnect; @@ -919,16 +964,15 @@ private: enum ProcessState {processIdle,processActive,processComplete}; ProcessState processState; - friend class ChannelProcessRequesterImpl; }; -class ChannelGetRequesterImpl; // private to PvaClientGet /** * @brief An easy to use alternative to ChannelGet. * * @author mrk */ -class epicsShareClass PvaClientGet +class epicsShareClass PvaClientGet : + public epics::pvAccess::ChannelGetRequester { public: POINTER_DEFINITIONS(PvaClientGet); @@ -946,10 +990,17 @@ public: /** Destructor */ ~PvaClientGet(); - /** - * @brief destroy an resources used. - */ - void destroy(); + std::string getRequesterName(); + void message(std::string const & message,epics::pvData::MessageType messageType); + void channelGetConnect( + const epics::pvData::Status& status, + epics::pvAccess::ChannelGet::shared_pointer const & channelGet, + epics::pvData::StructureConstPtr const & structure); + void getDone( + const epics::pvData::Status& status, + epics::pvAccess::ChannelGet::shared_pointer const & channelGet, + epics::pvData::PVStructurePtr const & pvStructure, + epics::pvData::BitSetPtr const & bitSet); /** Call issueConnect and then waitConnect. * An exception is thrown if connect fails. * @throw runtime_error if failure. @@ -979,29 +1030,22 @@ public: * @brief Get the data/ * @return The interface. */ - PvaClientGetDataPtr getData(); + PvaClientGetDataPtr getData(); + /** Deprecated method + * \deprecated This method will go away in future versions. + */ + void destroy() EPICS_DEPRECATED {} private: PvaClientGet( PvaClientPtr const &pvaClient, epics::pvAccess::Channel::shared_pointer const & channel, epics::pvData::PVStructurePtr const &pvRequest); - std::string getRequesterName(); - void message(std::string const & message,epics::pvData::MessageType messageType); - void channelGetConnect( - const epics::pvData::Status& status, - epics::pvAccess::ChannelGet::shared_pointer const & channelGet, - epics::pvData::StructureConstPtr const & structure); - void getDone( - const epics::pvData::Status& status, - epics::pvAccess::ChannelGet::shared_pointer const & channelGet, - epics::pvData::PVStructurePtr const & pvStructure, - epics::pvData::BitSetPtr const & bitSet); + void checkGetState(); enum GetConnectState {connectIdle,connectActive,connected}; PvaClient::weak_pointer pvaClient; epics::pvAccess::Channel::shared_pointer channel; - epics::pvAccess::ChannelGetRequester::shared_pointer getRequester; epics::pvData::PVStructurePtr pvRequest; epics::pvData::Mutex mutex; epics::pvData::Event waitForConnect; @@ -1021,13 +1065,13 @@ private: friend class ChannelGetRequesterImpl; }; -class ChannelPutRequesterImpl; // private to PvaClientPut /** * @brief An easy to use alternative to ChannelPut. * * @author mrk */ -class epicsShareClass PvaClientPut +class epicsShareClass PvaClientPut : + public epics::pvAccess::ChannelPutRequester { public: POINTER_DEFINITIONS(PvaClientPut); @@ -1045,10 +1089,20 @@ public: /** Destructor */ ~PvaClientPut(); - /** - * @brief destroy all resources used. - */ - void destroy(); + std::string getRequesterName(); + void message(std::string const & message,epics::pvData::MessageType messageType); + void channelPutConnect( + const epics::pvData::Status& status, + epics::pvAccess::ChannelPut::shared_pointer const & channelPut, + epics::pvData::StructureConstPtr const & structure); + void getDone( + const epics::pvData::Status& status, + epics::pvAccess::ChannelPut::shared_pointer const & channelPut, + epics::pvData::PVStructurePtr const & pvStructure, + epics::pvData::BitSetPtr const & bitSet); + void putDone( + const epics::pvData::Status& status, + epics::pvAccess::ChannelPut::shared_pointer const & channelPut); /** Call issueConnect and then waitConnect. * An exception is thrown if connect fails. * @throw runtime_error if failure. @@ -1089,32 +1143,22 @@ public: * @brief Get the data/ * @return The interface. */ - PvaClientPutDataPtr getData(); + PvaClientPutDataPtr getData(); + /** Deprecated method + * \deprecated This method will go away in future versions. + */ + void destroy() EPICS_DEPRECATED {} private : PvaClientPut( PvaClientPtr const &pvaClient, epics::pvAccess::Channel::shared_pointer const & channel, epics::pvData::PVStructurePtr const &pvRequest); - std::string getRequesterName(); - void message(std::string const & message,epics::pvData::MessageType messageType); - void channelPutConnect( - const epics::pvData::Status& status, - epics::pvAccess::ChannelPut::shared_pointer const & channelPut, - epics::pvData::StructureConstPtr const & structure); - void getDone( - const epics::pvData::Status& status, - epics::pvAccess::ChannelPut::shared_pointer const & channelPut, - epics::pvData::PVStructurePtr const & pvStructure, - epics::pvData::BitSetPtr const & bitSet); - void putDone( - const epics::pvData::Status& status, - epics::pvAccess::ChannelPut::shared_pointer const & channelPut); + void checkPutState(); enum PutConnectState {connectIdle,connectActive,connected}; PvaClient::weak_pointer pvaClient; epics::pvAccess::Channel::shared_pointer channel; - epics::pvAccess::ChannelPutRequester::shared_pointer putRequester; epics::pvData::PVStructurePtr pvRequest; epics::pvData::Mutex mutex; epics::pvData::Event waitForConnect; @@ -1127,18 +1171,18 @@ private : epics::pvAccess::ChannelPut::shared_pointer channelPut; PutConnectState connectState; - enum PutState {putIdle,getActive,putActive,putComplete}; + enum PutState {putIdle,getActive,putActive}; PutState putState; friend class ChannelPutRequesterImpl; }; -class ChannelPutGetRequesterImpl; // private to PvaClientPutGet /** * @brief An easy to use alternative to ChannelPutGet. * * @author mrk */ -class epicsShareClass PvaClientPutGet +class epicsShareClass PvaClientPutGet : + public epics::pvAccess::ChannelPutGetRequester { public: POINTER_DEFINITIONS(PvaClientPutGet); @@ -1156,9 +1200,28 @@ public: /** Destructor */ ~PvaClientPutGet(); - /** Destroy all resources used. - */ - void destroy(); + std::string getRequesterName(); + void message(std::string const & message,epics::pvData::MessageType messageType); + void channelPutGetConnect( + const epics::pvData::Status& status, + epics::pvAccess::ChannelPutGet::shared_pointer const & channelPutGet, + epics::pvData::StructureConstPtr const & putStructure, + epics::pvData::StructureConstPtr const & getStructure); + void putGetDone( + const epics::pvData::Status& status, + epics::pvAccess::ChannelPutGet::shared_pointer const & channelPutGet, + epics::pvData::PVStructurePtr const & getPVStructure, + epics::pvData::BitSetPtr const & getBitSet); + void getPutDone( + const epics::pvData::Status& status, + epics::pvAccess::ChannelPutGet::shared_pointer const & channelPutGet, + epics::pvData::PVStructurePtr const & putPVStructure, + epics::pvData::BitSet::shared_pointer const & putBitSet); + void getGetDone( + const epics::pvData::Status& status, + epics::pvAccess::ChannelPutGet::shared_pointer const & channelPutGet, + epics::pvData::PVStructurePtr const & getPVStructure, + epics::pvData::BitSet::shared_pointer const & getBitSet); /** Call issueConnect and then waitConnect. * An exception is thrown if connect fails. * @throw runtime_error if failure. @@ -1215,40 +1278,21 @@ public: /** Get the get data. * @return The interface. */ - PvaClientGetDataPtr getGetData(); + PvaClientGetDataPtr getGetData(); + /** Deprecated method + * \deprecated This method will go away in future versions. + */ + void destroy() EPICS_DEPRECATED {} private : PvaClientPutGet( PvaClientPtr const &pvaClient, epics::pvAccess::Channel::shared_pointer const & channel, epics::pvData::PVStructurePtr const &pvRequest); - std::string getRequesterName(); - void message(std::string const & message,epics::pvData::MessageType messageType); - void channelPutGetConnect( - const epics::pvData::Status& status, - epics::pvAccess::ChannelPutGet::shared_pointer const & channelPutGet, - epics::pvData::StructureConstPtr const & putStructure, - epics::pvData::StructureConstPtr const & getStructure); - void putGetDone( - const epics::pvData::Status& status, - epics::pvAccess::ChannelPutGet::shared_pointer const & channelPutGet, - epics::pvData::PVStructurePtr const & getPVStructure, - epics::pvData::BitSetPtr const & getBitSet); - void getPutDone( - const epics::pvData::Status& status, - epics::pvAccess::ChannelPutGet::shared_pointer const & channelPutGet, - epics::pvData::PVStructurePtr const & putPVStructure, - epics::pvData::BitSet::shared_pointer const & putBitSet); - void getGetDone( - const epics::pvData::Status& status, - epics::pvAccess::ChannelPutGet::shared_pointer const & channelPutGet, - epics::pvData::PVStructurePtr const & getPVStructure, - epics::pvData::BitSet::shared_pointer const & getBitSet); void checkPutGetState(); enum PutGetConnectState {connectIdle,connectActive,connected}; PvaClient::weak_pointer pvaClient; epics::pvAccess::Channel::shared_pointer channel; - epics::pvAccess::ChannelPutGetRequester::shared_pointer putGetRequester; epics::pvData::PVStructurePtr pvRequest; epics::pvData::Mutex mutex; epics::pvData::Event waitForConnect; @@ -1267,7 +1311,7 @@ private : friend class ChannelPutGetRequesterImpl; }; -class ChannelMonitorRequester; // private to PvaClientMonitor +//class ChannelMonitorRequester; // private to PvaClientMonitor /** * @brief Optional client callback. * @@ -1339,9 +1383,6 @@ public: * @param monitor The monitor. */ virtual void monitorEvent(epics::pvData::MonitorPtr const & monitor); - /** Destroy all resources used. - */ - void destroy(); /** Call issueConnect and then waitConnect. * An exception is thrown if connect fails. */ @@ -1390,6 +1431,10 @@ public: { return shared_from_this(); } + /** Deprecated method + * \deprecated This method will go away in future versions. + */ + void destroy() EPICS_DEPRECATED {} private: PvaClientMonitor( PvaClientPtr const &pvaClient, diff --git a/src/pv/pvaClientMultiChannel.h b/src/pv/pvaClientMultiChannel.h index cadb90b..8e30285 100644 --- a/src/pv/pvaClientMultiChannel.h +++ b/src/pv/pvaClientMultiChannel.h @@ -79,9 +79,7 @@ public: * Destructor */ ~PvaClientMultiChannel(); - /** Destroy the pvAccess connections. - */ - void destroy(); + /** Get the channelNames. * @return The names. */ @@ -164,13 +162,16 @@ public: { return shared_from_this(); } + /** Deprecated method + * \deprecated This method will go away in future versions. + */ + void destroy() EPICS_DEPRECATED {} private: PvaClientMultiChannel( PvaClientPtr const &pvaClient, epics::pvData::shared_vector const & channelName, std::string const & providerName, size_t maxNotConnected); - void checkConnected(); PvaClientPtr pvaClient; @@ -211,9 +212,6 @@ public: ~PvaClientMultiGetDouble(); - /** Destroy the pvAccess connection. - */ - void destroy(); /** * Create a channelGet for each channel. */ @@ -230,6 +228,10 @@ public: { return shared_from_this(); } + /** Deprecated method + * \deprecated This method will go away in future versions. + */ + void destroy() EPICS_DEPRECATED {} private: PvaClientMultiGetDouble( PvaClientMultiChannelPtr const &pvaClientMultiChannel, @@ -266,10 +268,6 @@ public: PvaClientMultiChannelPtr const &pvaMultiChannel, PvaClientChannelArray const &pvaClientChannelArray); ~PvaClientMultiPutDouble(); - - /** Destroy the pvAccess connection. - */ - void destroy(); /** * Create a channelPut for each channel. */ @@ -285,6 +283,10 @@ public: { return shared_from_this(); } + /** Deprecated method + * \deprecated This method will go away in future versions. + */ + void destroy() EPICS_DEPRECATED {} private: PvaClientMultiPutDouble( PvaClientMultiChannelPtr const &pvaClientMultiChannel, @@ -320,10 +322,6 @@ public: PvaClientMultiChannelPtr const &pvaMultiChannel, PvaClientChannelArray const &pvaClientChannelArray); ~PvaClientMultiMonitorDouble(); - - /** Destroy the pvAccess connection. - */ - void destroy(); /** * Create a channel monitor for each channel. */ @@ -336,11 +334,11 @@ public: bool poll(); /** * Wait until poll returns true. - * @param waitForEvent The time to keep trying. + * @param secondsToWait The time to keep trying. * A thread sleep of .1 seconds occurs between each call to poll. * @return (false,true) if (timeOut, poll returned true). */ - bool waitEvent(double waitForEvent); + bool waitEvent(double secondsToWait); /** * get the data. * @return The double[] where each element is the value field of the corresponding channel. @@ -353,6 +351,10 @@ public: { return shared_from_this(); } + /** Deprecated method + * \deprecated This method will go away in future versions. + */ + void destroy() EPICS_DEPRECATED {} private: PvaClientMultiMonitorDouble( PvaClientMultiChannelPtr const &pvaClientMultiChannel, @@ -391,10 +393,6 @@ public: epics::pvData::PVStructurePtr const & pvRequest); ~PvaClientNTMultiGet(); - - /** Destroy the pvAccess connection. - */ - void destroy(); /** * Create a channelGet for each channel. */ @@ -415,6 +413,10 @@ public: { return shared_from_this(); } + /** Deprecated method + * \deprecated This method will go away in future versions. + */ + void destroy() EPICS_DEPRECATED {} private: PvaClientNTMultiGet( epics::pvData::UnionConstPtr const & u, @@ -453,11 +455,8 @@ public: static PvaClientNTMultiPutPtr create( PvaClientMultiChannelPtr const &pvaClientMultiChannel, PvaClientChannelArray const &pvaClientChannelArray); + ~PvaClientNTMultiPut(); - - /** Destroy the pvAccess connection. - */ - void destroy(); /** * Create a channelPut for each channel. */ @@ -478,6 +477,10 @@ public: { return shared_from_this(); } + /** Deprecated method + * \deprecated This method will go away in future versions. + */ + void destroy() EPICS_DEPRECATED {} private: PvaClientNTMultiPut( PvaClientMultiChannelPtr const &pvaClientMultiChannel, @@ -516,10 +519,6 @@ public: PvaClientChannelArray const &pvaClientChannelArray, epics::pvData::PVStructurePtr const & pvRequest); ~PvaClientNTMultiMonitor(); - - /** Destroy the pvAccess connection. - */ - void destroy(); /** * Create a channel monitor for each channel. */ @@ -532,11 +531,11 @@ public: bool poll(); /** * Wait until poll returns true. - * @param waitForEvent The time to keep trying. + * @param secondsToWait The time to keep trying. * A thread sleep of .1 seconds occurs between each call to poll. * @return (false,true) if (timeOut, poll returned true). */ - bool waitEvent(double waitForEvent); + bool waitEvent(double secondsToWait); /** * get the data. * @return the pvaClientNTMultiData. @@ -549,6 +548,10 @@ public: { return shared_from_this(); } + /** Deprecated method + * \deprecated This method will go away in future versions. + */ + void destroy() EPICS_DEPRECATED {} private: PvaClientNTMultiMonitor( epics::pvData::UnionConstPtr const & u, @@ -590,10 +593,7 @@ public: PvaClientChannelArray const &pvaClientChannelArray, epics::pvData::PVStructurePtr const & pvRequest); ~PvaClientNTMultiData(); - /** Destroy the pvAccess connection. - */ - void destroy(); - + /** * Get the number of channels. * @return The number of channels. @@ -626,7 +626,10 @@ public: { return shared_from_this(); } - + /** Deprecated method + * \deprecated This method will go away in future versions. + */ + void destroy() EPICS_DEPRECATED {} private: PvaClientNTMultiData( epics::pvData::UnionConstPtr const & u, diff --git a/src/pvaClient.cpp b/src/pvaClient.cpp index 3c88860..3305d3c 100644 --- a/src/pvaClient.cpp +++ b/src/pvaClient.cpp @@ -37,11 +37,9 @@ class PvaClientChannelCache public: PvaClientChannelCache(){} ~PvaClientChannelCache(){ - destroy(); + if(PvaClient::getDebug()) cout << "PvaClientChannelCache::~PvaClientChannelCache\n"; + pvaClientChannelMap.clear(); } - void destroy() { - pvaClientChannelMap.clear(); - } PvaClientChannelPtr getChannel( string const & channelName, string const & providerName); @@ -68,17 +66,12 @@ void PvaClientChannelCache::addChannel(PvaClientChannelPtr const & pvaClientChan Channel::shared_pointer channel = pvaClientChannel->getChannel(); string name = channel->getChannelName() + channel->getProvider()->getProviderName(); - pvaClientChannelMap.insert(std::pair( - name,pvaClientChannel)); -} - -void PvaClientChannelCache::removeChannel( - string const & channelName, - string const & providerName) -{ - string name = channelName + providerName; map::iterator iter = pvaClientChannelMap.find(name); - if(iter!=pvaClientChannelMap.end()) pvaClientChannelMap.erase(iter); + if(iter!=pvaClientChannelMap.end()) { + throw std::runtime_error("pvaClientChannelCache::addChannel channel already cached"); + } + pvaClientChannelMap.insert(std::pair( + name,pvaClientChannel)); } void PvaClientChannelCache::showCache() @@ -103,6 +96,8 @@ size_t PvaClientChannelCache::cacheSize() } +bool PvaClient::debug = false; + PvaClientPtr PvaClient::get(std::string const & providerNames) { static PvaClientPtr master; @@ -141,16 +136,16 @@ PvaClient::PvaClient(std::string const & providerNames) } PvaClient::~PvaClient() { - destroy(); -} - -void PvaClient::destroy() -{ + if(PvaClient::debug) cout<< "PvaClient::~PvaClient()\n"; { Lock xx(mutex); - if(isDestroyed) return; + if(isDestroyed) { + cerr<< "Why was PvaClient::~PvaClient() called more then once????\n"; + return; + } isDestroyed = true; } + if(PvaClient::debug) showCache(); pvaClientChannelCache.reset(); if(pvaStarted) ClientFactory::stop(); if(caStarted) CAClientFactory::stop(); diff --git a/src/pvaClientChannel.cpp b/src/pvaClientChannel.cpp index 8a0645a..a08c332 100644 --- a/src/pvaClientChannel.cpp +++ b/src/pvaClientChannel.cpp @@ -30,9 +30,9 @@ class PvaClientGetCache { public: PvaClientGetCache(){} - ~PvaClientGetCache(); - void destroy() { - pvaClientGetMap.clear(); + ~PvaClientGetCache() + { + pvaClientGetMap.clear(); } PvaClientGetPtr getGet(string const & request); void addGet(string const & request,PvaClientGetPtr const & pvaClientGet); @@ -42,11 +42,6 @@ private: map pvaClientGetMap; }; -PvaClientGetCache::~PvaClientGetCache() -{ - destroy(); -} - PvaClientGetPtr PvaClientGetCache::getGet(string const & request) { map::iterator iter = pvaClientGetMap.find(request); @@ -56,8 +51,11 @@ PvaClientGetPtr PvaClientGetCache::getGet(string const & request) void PvaClientGetCache::addGet(string const & request,PvaClientGetPtr const & pvaClientGet) { - pvaClientGetMap.insert(std::pair( - request,pvaClientGet)); + map::iterator iter = pvaClientGetMap.find(request); + if(iter!=pvaClientGetMap.end()) { + throw std::runtime_error("pvaClientGetCache::addGet pvaClientGet already cached"); + } + pvaClientGetMap.insert(std::pair(request,pvaClientGet)); } void PvaClientGetCache::showCache() @@ -79,9 +77,9 @@ class PvaClientPutCache { public: PvaClientPutCache(){} - ~PvaClientPutCache(); - void destroy() { - pvaClientPutMap.clear(); + ~PvaClientPutCache() + { + pvaClientPutMap.clear(); } PvaClientPutPtr getPut(string const & request); void addPut(string const & request,PvaClientPutPtr const & pvaClientPut); @@ -91,10 +89,6 @@ private: map pvaClientPutMap; }; -PvaClientPutCache::~PvaClientPutCache() -{ - destroy(); -} PvaClientPutPtr PvaClientPutCache::getPut(string const & request) { @@ -105,6 +99,10 @@ PvaClientPutPtr PvaClientPutCache::getPut(string const & request) void PvaClientPutCache::addPut(string const & request,PvaClientPutPtr const & pvaClientPut) { + map::iterator iter = pvaClientPutMap.find(request); + if(iter!=pvaClientPutMap.end()) { + throw std::runtime_error("pvaClientPutCache::addPut pvaClientPut already cached"); + } pvaClientPutMap.insert(std::pair( request,pvaClientPut)); } @@ -124,30 +122,6 @@ size_t PvaClientPutCache::cacheSize() } -class ChannelRequesterImpl : public ChannelRequester -{ - PvaClientChannel *pvaClientChannel; -public: - ChannelRequesterImpl(PvaClientChannel *pvaClientChannel) - : pvaClientChannel(pvaClientChannel) {} - void channelCreated( - const Status& status, - Channel::shared_pointer const & channel) - { pvaClientChannel->channelCreated(status,channel); } - void channelStateChange( - Channel::shared_pointer const & channel, - Channel::ConnectionState connectionState) - {pvaClientChannel->channelStateChange(channel,connectionState);} - tr1::shared_ptr getChannel() {return pvaClientChannel->getChannel();} - string getRequesterName() - {return pvaClientChannel->getRequesterName();} - void message( - string const & message, - MessageType messageType) - { pvaClientChannel->message(message,messageType); } - void destroy() {pvaClientChannel->destroy();} -}; - PvaClientChannel::PvaClientChannel( PvaClientPtr const &pvaClient, @@ -161,35 +135,75 @@ PvaClientChannel::PvaClientChannel( createRequest(CreateRequest::create()), pvaClientGetCache(new PvaClientGetCache()), pvaClientPutCache(new PvaClientPutCache()) -{} +{ + if(PvaClient::getDebug()) { + cout << "PvaClientChannel::PvaClientChannel channelName " << channelName << endl; + } +} PvaClientChannel::~PvaClientChannel() { - destroy(); + if(PvaClient::getDebug()) { + cout << "PvaClientChannel::~PvaClientChannel() " + << " channelName " << channelName + << " this " << this << " channel " << channel + << endl; + } + { + Lock xx(mutex); + if(isDestroyed) return; + isDestroyed = true; + } + if(PvaClient::getDebug()) showCache(); + if(channel) channel->destroy(); +if(channel) channel.reset(); + pvaClientGetCache.reset(); + pvaClientPutCache.reset(); + } + void PvaClientChannel::channelCreated(const Status& status, Channel::shared_pointer const & channel) { + if(PvaClient::getDebug()) { + cout << "PvaClientChannel::channelCreated" + << " channelName " << channelName + << " isConnected " << (channel->isConnected() ? "true" : "false") + << " status.isOK " << (status.isOK() ? "true" : "false") + << " this " << this + << endl; + } Lock xx(mutex); if(isDestroyed) throw std::runtime_error("pvaClientChannel was destroyed"); - if(status.isOK()) { - this->channel = channel; - if(channel->isConnected()) { - bool waitingForConnect = false; - if(connectState==connectActive) waitingForConnect = true; - connectState = connected; - channelConnectStatus = Status::Ok; - if(waitingForConnect) waitForConnect.signal(); - } - return; + if(connectState!=connectActive) { + string message("PvaClientChannel::channelCreated"); + message += " channel " + channelName + + " why was this called when connectState!=ConnectState.connectActive"; + throw std::runtime_error(message); + } + if(!status.isOK()) { + string message("PvaClientChannel::channelCreated"); + + " status " + status.getMessage() + " why??"; + throw std::runtime_error(message); + } + if(channel->isConnected()) { + connectState = connected; + waitForConnect.signal(); } - cout << "PvaClientChannel::channelCreated status " << status.getMessage() << " why??\n"; } void PvaClientChannel::channelStateChange( Channel::shared_pointer const & channel, Channel::ConnectionState connectionState) { + if(PvaClient::getDebug()) { + cout << " PvaClientChannel::channelStateChange " + << " channelName " << channelName + << " is connected " << (connectionState==Channel::CONNECTED ? "true" : "false") + << " isDestroyed " << isDestroyed + << " this " << this + << endl; + } Lock xx(mutex); if(isDestroyed) return; bool waitingForConnect = false; @@ -197,12 +211,11 @@ void PvaClientChannel::channelStateChange( if(connectionState!=Channel::CONNECTED) { string mess(channelName + " connection state " + Channel::ConnectionStateNames[connectionState]); - message(mess,errorMessage); - channelConnectStatus = Status(Status::STATUSTYPE_ERROR,mess); - connectState = notConnected; + message(mess,errorMessage); + connectState = notConnected; + return; } else { - connectState = connected; - channelConnectStatus = Status::Ok; + connectState = connected; } if(waitingForConnect) waitForConnect.signal(); } @@ -210,7 +223,8 @@ void PvaClientChannel::channelStateChange( string PvaClientChannel::getRequesterName() { PvaClientPtr yyy = pvaClient.lock(); - if(!yyy) throw std::runtime_error("PvaClient was destroyed"); + if(!yyy) throw std::runtime_error( + "PvaClientChannel::getRequesterName() PvaClientChannel isDestroyed"); return yyy->getRequesterName(); } @@ -218,76 +232,80 @@ void PvaClientChannel::message( string const & message, MessageType messageType) { - if(isDestroyed) throw std::runtime_error("pvaClientChannel was destroyed"); PvaClientPtr yyy = pvaClient.lock(); - if(!yyy) throw std::runtime_error("PvaClient was destroyed"); + if(isDestroyed) throw std::runtime_error( + "PvaClientChannel::message() pvaClientChannel isDestroyed"); yyy->message(channelName + " " + message, messageType); } -void PvaClientChannel::destroy() -{ - { - Lock xx(mutex); - if(isDestroyed) return; - isDestroyed = true; - } - if(channel) channel->destroy(); - channel.reset(); - pvaClientGetCache.reset(); - pvaClientPutCache.reset(); -} - string PvaClientChannel::getChannelName() { - if(isDestroyed) throw std::runtime_error("pvaClientChannel was destroyed"); + if(isDestroyed) throw std::runtime_error( + "PvaClientChannel::getChannelName() pvaClientChannel was destroyed"); return channelName; } Channel::shared_pointer PvaClientChannel::getChannel() { - if(isDestroyed) throw std::runtime_error("pvaClientChannel was destroyed"); + if(isDestroyed) throw std::runtime_error( + "PvaClientChannel::getChannel() pvaClientChannel was destroyed"); return channel; } void PvaClientChannel::connect(double timeout) { - if(isDestroyed) throw std::runtime_error("pvaClientChannel was destroyed"); + if(isDestroyed) throw std::runtime_error( + "PvaClientChannel::connect() pvaClientChannel was destroyed"); + if(PvaClient::getDebug()) { + cout << "PvaClientChannel::connect" + << " channelName " << channelName << endl; + } issueConnect(); Status status = waitConnect(timeout); if(status.isOK()) return; - string message = string("channel ") + getChannelName() + if(PvaClient::getDebug()) cout << "PvaClientChannel::connect waitConnect failed\n"; + string message = string("channel ") + channelName + " PvaClientChannel::connect " + status.getMessage(); throw std::runtime_error(message); } void PvaClientChannel::issueConnect() { + if(isDestroyed) throw std::runtime_error( + "PvaClientChannel::issueConnect() pvaClientChannel was destroyed"); + if(PvaClient::getDebug()) { + cout << "PvaClientChannel::issueConnect" + << " channelName " << channelName << endl; + } { Lock xx(mutex); if(isDestroyed) throw std::runtime_error("pvaClientChannel was destroyed"); if(connectState!=connectIdle) { throw std::runtime_error("pvaClientChannel already connected"); } - - channelConnectStatus = Status( - Status::STATUSTYPE_ERROR, - getChannelName() + " createChannel failed"); connectState = connectActive; } ChannelProviderRegistry::shared_pointer reg = getChannelProviderRegistry(); ChannelProvider::shared_pointer provider = reg->getProvider(providerName); if(!provider) { - throw std::runtime_error(getChannelName() + " provider " + providerName + " not registered"); + throw std::runtime_error(channelName + " provider " + providerName + " not registered"); } - channelRequester = ChannelRequester::shared_pointer(new ChannelRequesterImpl(this)); + ChannelRequester::shared_pointer channelRequester(ChannelRequester::shared_pointer(this)); + if(PvaClient::getDebug()) cout << "PvaClientChannel::issueConnect calling provider->createChannel\n"; channel = provider->createChannel(channelName,channelRequester,ChannelProvider::PRIORITY_DEFAULT); if(!channel) { - throw std::runtime_error(getChannelName() + " channelCreate failed "); + throw std::runtime_error(channelName + " channelCreate failed "); } } Status PvaClientChannel::waitConnect(double timeout) { + if(isDestroyed) throw std::runtime_error( + "PvaClientChannel::waitConnect() pvaClientChannel was destroyed"); + if(PvaClient::getDebug()) { + cout << "PvaClientChannel::waitConnect" + << " channelName " << channelName << endl; + } { Lock xx(mutex); if(isDestroyed) throw std::runtime_error("pvaClientChannel was destroyed"); @@ -298,7 +316,8 @@ Status PvaClientChannel::waitConnect(double timeout) } else { waitForConnect.wait(); } - return channelConnectStatus; + if(channel->isConnected()) return Status::Ok; + return Status(Status::STATUSTYPE_ERROR,channelName + " not connected"); } PvaClientFieldPtr PvaClientChannel::createField() @@ -321,7 +340,7 @@ PvaClientProcessPtr PvaClientChannel::createProcess(string const & request) { PVStructurePtr pvRequest = createRequest->createRequest(request); if(!pvRequest) { - string message = string("channel ") + getChannelName() + string message = string("channel ") + channelName + " PvaClientChannel::createProcess invalid pvRequest: " + createRequest->getMessage(); throw std::runtime_error(message); @@ -358,7 +377,7 @@ PvaClientGetPtr PvaClientChannel::createGet(string const & request) { PVStructurePtr pvRequest = createRequest->createRequest(request); if(!pvRequest) { - string message = string("channel ") + getChannelName() + string message = string("channel ") + channelName + " PvaClientChannel::createGet invalid pvRequest: " + createRequest->getMessage(); throw std::runtime_error(message); @@ -396,7 +415,7 @@ PvaClientPutPtr PvaClientChannel::createPut(string const & request) { PVStructurePtr pvRequest = createRequest->createRequest(request); if(!pvRequest) { - string message = string("channel ") + getChannelName() + string message = string("channel ") + channelName + " PvaClientChannel::createPut invalid pvRequest: " + createRequest->getMessage(); throw std::runtime_error(message); @@ -421,7 +440,7 @@ PvaClientPutGetPtr PvaClientChannel::createPutGet(string const & request) { PVStructurePtr pvRequest = createRequest->createRequest(request); if(!pvRequest) { - string message = string("channel ") + getChannelName() + string message = string("channel ") + channelName + " PvaClientChannel::createPutGet invalid pvRequest: " + createRequest->getMessage(); throw std::runtime_error(message); @@ -447,7 +466,7 @@ PvaClientArrayPtr PvaClientChannel::createArray(string const & request) { PVStructurePtr pvRequest = createRequest->createRequest(request); if(!pvRequest) { - string message = string("channel ") + getChannelName() + string message = string("channel ") + channelName + " PvaClientChannel::createArray invalid pvRequest: " + createRequest->getMessage(); throw std::runtime_error(message); @@ -499,7 +518,7 @@ PvaClientMonitorPtr PvaClientChannel::createMonitor(string const & request) { PVStructurePtr pvRequest = createRequest->createRequest(request); if(!pvRequest) { - string message = string("channel ") + getChannelName() + string message = string("channel ") + channelName + " PvaClientChannel::createMonitor invalid pvRequest: " + createRequest->getMessage(); throw std::runtime_error(message); diff --git a/src/pvaClientGet.cpp b/src/pvaClientGet.cpp index ce1a945..0542704 100644 --- a/src/pvaClientGet.cpp +++ b/src/pvaClientGet.cpp @@ -57,11 +57,18 @@ PvaClientGet::PvaClientGet( connectState(connectIdle), getState(getIdle) { + if(PvaClient::getDebug()) cout<< "PvaClientGet::PvaClientGet\n"; } PvaClientGet::~PvaClientGet() { - destroy(); + if(PvaClient::getDebug()) cout<< "PvaClientGet::~PvaClientGet()\n"; + { + Lock xx(mutex); + if(isDestroyed) return; + isDestroyed = true; + } +// if(channelGet) channelGet->destroy(); } void PvaClientGet::checkGetState() @@ -75,7 +82,7 @@ void PvaClientGet::checkGetState() string PvaClientGet::getRequesterName() { PvaClientPtr yyy = pvaClient.lock(); - if(!yyy) throw std::runtime_error("pvaClient was destroyed"); + if(!yyy) return string(); return yyy->getRequesterName(); } @@ -83,7 +90,7 @@ void PvaClientGet::message(string const & message,MessageType messageType) { if(isDestroyed) throw std::runtime_error("pvaClientGet was destroyed"); PvaClientPtr yyy = pvaClient.lock(); - if(!yyy) throw std::runtime_error("pvaClient was destroyed"); + if(!yyy) return; yyy->message(message, messageType); } @@ -93,12 +100,15 @@ void PvaClientGet::channelGetConnect( StructureConstPtr const & structure) { if(isDestroyed) throw std::runtime_error("pvaClientGet was destroyed"); - channelGetConnectStatus = status; - this->channelGet = channelGet; - if(status.isOK()) { - pvaClientData = PvaClientGetData::create(structure); - pvaClientData->setMessagePrefix(channel->getChannelName()); + { + Lock xx(mutex); + channelGetConnectStatus = status; connectState = connected; + this->channelGet = channelGet; + if(status.isOK()) { + pvaClientData = PvaClientGetData::create(structure); + pvaClientData->setMessagePrefix(channel->getChannelName()); + } } waitForConnect.signal(); @@ -111,24 +121,15 @@ void PvaClientGet::getDone( BitSetPtr const & bitSet) { if(isDestroyed) throw std::runtime_error("pvaClientGet was destroyed"); - channelGetStatus = status; - if(status.isOK()) { - pvaClientData->setData(pvStructure,bitSet); - } - waitForGet.signal(); -} - - -// from PvaClientGet -void PvaClientGet::destroy() -{ { Lock xx(mutex); - if(isDestroyed) return; - isDestroyed = true; + channelGetStatus = status; + getState = getComplete; + if(status.isOK()) { + pvaClientData->setData(pvStructure,bitSet); + } } - if(channelGet) channelGet->destroy(); - channelGet.reset(); + waitForGet.signal(); } void PvaClientGet::connect() @@ -150,7 +151,7 @@ void PvaClientGet::issueConnect() + " pvaClientGet already connected "; throw std::runtime_error(message); } - getRequester = ChannelGetRequester::shared_pointer(new ChannelGetRequesterImpl(this)); + ChannelGetRequester::shared_pointer getRequester(ChannelGetRequester::shared_pointer(this)); connectState = connectActive; channelGet = channel->createChannelGet(getRequester,pvRequest); } @@ -158,14 +159,20 @@ void PvaClientGet::issueConnect() Status PvaClientGet::waitConnect() { if(isDestroyed) throw std::runtime_error("pvaClientGet was destroyed"); - if(connectState==connected) return channelGetConnectStatus; - if(connectState!=connectActive) { - string message = string("channel ") + channel->getChannelName() - + " pvaClientGet illegal connect state "; - throw std::runtime_error(message); + { + Lock xx(mutex); + if(connectState==connected) { + if(!channelGetConnectStatus.isOK()) connectState = connectIdle; + return channelGetConnectStatus; + } + if(connectState!=connectActive) { + string message = string("channel ") + channel->getChannelName() + + " pvaClientGet illegal connect state "; + throw std::runtime_error(message); + } } waitForConnect.wait(); - connectState = channelGetConnectStatus.isOK() ? connected : connectIdle; + if(!channelGetConnectStatus.isOK()) connectState = connectIdle; return channelGetConnectStatus; } @@ -196,16 +203,20 @@ void PvaClientGet::issueGet() Status PvaClientGet::waitGet() { if(isDestroyed) throw std::runtime_error("pvaClientGet was destroyed"); - if(getState!=getActive){ - string message = string("channel ") + channel->getChannelName() - + " PvaClientGet::waitGet llegal get state"; - throw std::runtime_error(message); + { + Lock xx(mutex); + if(getState==getComplete) { + getState =getIdle; + return channelGetStatus; + } + if(getState!=getActive){ + string message = string("channel ") + channel->getChannelName() + + " PvaClientGet::waitGet llegal get state"; + throw std::runtime_error(message); + } } waitForGet.wait(); getState = getIdle; - if(channelGetStatus.isOK()) { - return Status::Ok; - } return channelGetStatus; } PvaClientGetDataPtr PvaClientGet::getData() diff --git a/src/pvaClientMonitor.cpp b/src/pvaClientMonitor.cpp index de7d520..29d0ed1 100644 --- a/src/pvaClientMonitor.cpp +++ b/src/pvaClientMonitor.cpp @@ -37,11 +37,23 @@ PvaClientMonitor::PvaClientMonitor( userPoll(false), userWait(false) { + if(PvaClient::getDebug()) cout<< "PvaClientMonitor::PvaClientMonitor()\n"; } PvaClientMonitor::~PvaClientMonitor() { - destroy(); + if(PvaClient::getDebug()) cout<< "PvaClientMonitor::~PvaClientMonitor()\n"; + { + Lock xx(mutex); + if(isDestroyed) { + cerr<< "Why was PvaClientMonitor::~PvaClientMonitor() called more then once????\n"; + return; + } + isDestroyed = true; + } + if(monitor) monitor->destroy(); + monitor.reset(); + monitorElement.reset(); } void PvaClientMonitor::checkMonitorState() @@ -74,6 +86,7 @@ void PvaClientMonitor::monitorConnect( { if(isDestroyed) throw std::runtime_error("pvaClientMonitor was destroyed"); connectStatus = status; + connectState = connected; this->monitor = monitor; if(status.isOK()) { pvaClientData = PvaClientMonitorData::create(structure); @@ -93,19 +106,16 @@ void PvaClientMonitor::monitorEvent(MonitorPtr const & monitor) void PvaClientMonitor::unlisten(MonitorPtr const & monitor) { - destroy(); -} - -void PvaClientMonitor::destroy() -{ + if(PvaClient::getDebug()) cout << "PvaClientMonitor::unlisten\n"; { Lock xx(mutex); - if(isDestroyed) return; - isDestroyed = true; + if(isDestroyed) { + cerr<< "Why was PvaClientMonitor::unlisten called when PvaClientMonitor was destroyed?\n"; + return; + } } - if(monitor) monitor->destroy(); - monitor.reset(); - monitorElement.reset(); + this->monitor.reset(); + this->monitorElement.reset(); } void PvaClientMonitor::connect() @@ -137,6 +147,10 @@ void PvaClientMonitor::issueConnect() Status PvaClientMonitor::waitConnect() { if(isDestroyed) throw std::runtime_error("pvaClientMonitor was destroyed"); + if(connectState==connected) { + if(connectStatus.isOK()) connectState = connectIdle; + return connectStatus; + } if(connectState!=connectActive) { string message = string("channel ") + channel->getChannelName() + " pvaClientMonitor illegal connect state "; diff --git a/src/pvaClientMultiChannel.cpp b/src/pvaClientMultiChannel.cpp index 0c2e173..a9589a9 100644 --- a/src/pvaClientMultiChannel.cpp +++ b/src/pvaClientMultiChannel.cpp @@ -56,18 +56,18 @@ PvaClientMultiChannel::PvaClientMultiChannel( createRequest(CreateRequest::create()), isDestroyed(false) { + if(PvaClient::getDebug()) cout<< "PvaClientMultiChannel::PvaClientMultiChannel()\n"; } PvaClientMultiChannel::~PvaClientMultiChannel() { - destroy(); -} - -void PvaClientMultiChannel::destroy() -{ + if(PvaClient::getDebug()) cout<< "PvaClientMultiChannel::~PvaClientMultiChannel()\n"; { Lock xx(mutex); - if(isDestroyed) return; + if(isDestroyed) { + cerr<< "Why was PvaClientMultiChannel::~PvaClientMultiChannel() called more then once????\n"; + return; + } isDestroyed = true; } pvaClientChannelArray.clear(); @@ -75,11 +75,7 @@ void PvaClientMultiChannel::destroy() void PvaClientMultiChannel::checkConnected() { - if(numConnected==0){ - Status status = connect(3.0); - if(status.isOK()) return; - throw std::runtime_error("pvaClientMultiChannel connect failure"); - } + if(numConnected==0) connect(); } epics::pvData::shared_vector PvaClientMultiChannel::getChannelNames() diff --git a/src/pvaClientMultiGetDouble.cpp b/src/pvaClientMultiGetDouble.cpp index 68c6e96..05b3aef 100644 --- a/src/pvaClientMultiGetDouble.cpp +++ b/src/pvaClientMultiGetDouble.cpp @@ -51,18 +51,18 @@ PvaClientMultiGetDouble::PvaClientMultiGetDouble( isGetConnected(false), isDestroyed(false) { + if(PvaClient::getDebug()) cout<< "PvaClientMultiGetDouble::PvaClientMultiGetDouble()\n"; } PvaClientMultiGetDouble::~PvaClientMultiGetDouble() { - destroy(); -} - -void PvaClientMultiGetDouble::destroy() -{ + if(PvaClient::getDebug()) cout<< "PvaClientMultiGetDouble::~PvaClientMultiGetDouble()\n"; { Lock xx(mutex); - if(isDestroyed) return; + if(isDestroyed) { + cerr<< "Why was PvaClientMultiGetDouble::~PvaClientMultiGetDouble() called more then once????\n"; + return; + } isDestroyed = true; } pvaClientChannelArray.clear(); diff --git a/src/pvaClientMultiMonitorDouble.cpp b/src/pvaClientMultiMonitorDouble.cpp index 6ef70b3..813a2b9 100644 --- a/src/pvaClientMultiMonitorDouble.cpp +++ b/src/pvaClientMultiMonitorDouble.cpp @@ -52,18 +52,18 @@ PvaClientMultiMonitorDouble::PvaClientMultiMonitorDouble( isMonitorConnected(false), isDestroyed(false) { + if(PvaClient::getDebug()) cout<< "PvaClientMultiMonitorDouble::PvaClientMultiMonitorDouble()\n"; } PvaClientMultiMonitorDouble::~PvaClientMultiMonitorDouble() { - destroy(); -} - -void PvaClientMultiMonitorDouble::destroy() -{ + if(PvaClient::getDebug()) cout<< "PvaClientMultiMonitorDouble::~PvaClientMultiMonitorDouble()\n"; { Lock xx(mutex); - if(isDestroyed) return; + if(isDestroyed) { + cerr<< "Why was PvaClientMultiMonitorDouble::~PvaClientMultiMonitorDouble() called more then once????\n"; + return; + } isDestroyed = true; } pvaClientChannelArray.clear(); diff --git a/src/pvaClientMultiPutDouble.cpp b/src/pvaClientMultiPutDouble.cpp index 29a1758..1c52c7a 100644 --- a/src/pvaClientMultiPutDouble.cpp +++ b/src/pvaClientMultiPutDouble.cpp @@ -51,25 +51,26 @@ PvaClientMultiPutDouble::PvaClientMultiPutDouble( isPutConnected(false), isDestroyed(false) { + if(PvaClient::getDebug()) cout<< "PvaClientMultiPutDouble::PvaClientMultiPutDouble()\n"; } PvaClientMultiPutDouble::~PvaClientMultiPutDouble() { - destroy(); -} - -void PvaClientMultiPutDouble::destroy() -{ + if(PvaClient::getDebug()) cout<< "PvaClientMultiPutDouble::~PvaClientMultiPutDouble()\n"; { Lock xx(mutex); - if(isDestroyed) return; + if(isDestroyed) { + cerr<< "Why was PvaClientMultiPutDouble::~PvaClientMultiPutDouble() called more then once????\n"; + return; + } isDestroyed = true; } pvaClientChannelArray.clear(); } + void PvaClientMultiPutDouble::connect() { shared_vector isConnected = pvaClientMultiChannel->getIsConnected(); diff --git a/src/pvaClientNTMultiData.cpp b/src/pvaClientNTMultiData.cpp index daaf6f0..c67d382 100644 --- a/src/pvaClientNTMultiData.cpp +++ b/src/pvaClientNTMultiData.cpp @@ -48,6 +48,7 @@ PvaClientNTMultiData::PvaClientNTMultiData( gotTimeStamp(false), isDestroyed(false) { + if(PvaClient::getDebug()) cout<< "PvaClientNTMultiData::PvaClientNTMultiData()\n"; PVFieldPtr pvValue = pvRequest->getSubField("field.value"); if(!pvValue) { throw std::runtime_error("pvRequest did not specify value"); @@ -88,19 +89,19 @@ PvaClientNTMultiData::PvaClientNTMultiData( PvaClientNTMultiData::~PvaClientNTMultiData() { - destroy(); -} - -void PvaClientNTMultiData::destroy() -{ + if(PvaClient::getDebug()) cout<< "PvaClientNTMultiData::~PvaClientNTMultiData()\n"; { Lock xx(mutex); - if(isDestroyed) return; + if(isDestroyed) { + cerr<< "Why was PvaClientNTMultiData::~PvaClientNTMultiData() called more then once????\n"; + return; + } isDestroyed = true; } pvaClientChannelArray.clear(); } + void PvaClientNTMultiData::setStructure(StructureConstPtr const & structure,size_t index) { FieldConstPtr field = structure->getField("value"); diff --git a/src/pvaClientNTMultiGet.cpp b/src/pvaClientNTMultiGet.cpp index 4d13c75..8da1248 100644 --- a/src/pvaClientNTMultiGet.cpp +++ b/src/pvaClientNTMultiGet.cpp @@ -60,18 +60,18 @@ PvaClientNTMultiGet::PvaClientNTMultiGet( isConnected(false), isDestroyed(false) { + if(PvaClient::getDebug()) cout<< "PvaClientNTMultiGet::PvaClientNTMultiGet()\n"; } PvaClientNTMultiGet::~PvaClientNTMultiGet() { - destroy(); -} - -void PvaClientNTMultiGet::destroy() -{ + if(PvaClient::getDebug()) cout<< "PvaClientNTMultiGet::~PvaClientNTMultiGet()\n"; { Lock xx(mutex); - if(isDestroyed) return; + if(isDestroyed) { + cerr<< "Why was PvaClientNTMultiGet::~PvaClientNTMultiGet() called more then once????\n"; + return; + } isDestroyed = true; } pvaClientChannelArray.clear(); diff --git a/src/pvaClientNTMultiMonitor.cpp b/src/pvaClientNTMultiMonitor.cpp index 0de4d2b..efcbec0 100644 --- a/src/pvaClientNTMultiMonitor.cpp +++ b/src/pvaClientNTMultiMonitor.cpp @@ -57,19 +57,19 @@ PvaClientNTMultiMonitor::PvaClientNTMultiMonitor( isConnected(false), isDestroyed(false) { + if(PvaClient::getDebug()) cout<< "PvaClientNTMultiMonitor::PvaClientNTMultiMonitor()\n"; } PvaClientNTMultiMonitor::~PvaClientNTMultiMonitor() { - destroy(); -} - -void PvaClientNTMultiMonitor::destroy() -{ + if(PvaClient::getDebug()) cout<< "PvaClientNTMultiMonitor::~PvaClientNTMultiMonitor()\n"; { Lock xx(mutex); - if(isDestroyed) return; + if(isDestroyed) { + cerr<< "Why was PvaClientNTMultiMonitor::~PvaClientNTMultiMonitor() called more then once????\n"; + return; + } isDestroyed = true; } pvaClientChannelArray.clear(); diff --git a/src/pvaClientNTMultiPut.cpp b/src/pvaClientNTMultiPut.cpp index 66f086a..7317e45 100644 --- a/src/pvaClientNTMultiPut.cpp +++ b/src/pvaClientNTMultiPut.cpp @@ -48,19 +48,19 @@ PvaClientNTMultiPut::PvaClientNTMultiPut( isConnected(false), isDestroyed(false) { + if(PvaClient::getDebug()) cout<< "PvaClientNTMultiPut::PvaClientNTMultiPut()\n"; } PvaClientNTMultiPut::~PvaClientNTMultiPut() { - destroy(); -} - -void PvaClientNTMultiPut::destroy() -{ + if(PvaClient::getDebug()) cout<< "PvaClientNTMultiPut::~PvaClientNTMultiPut()\n"; { Lock xx(mutex); - if(isDestroyed) return; + if(isDestroyed) { + cerr<< "Why was PvaClientNTMultiPut::~PvaClientNTMultiPut() called more then once????\n"; + return; + } isDestroyed = true; } pvaClientChannelArray.clear(); diff --git a/src/pvaClientProcess.cpp b/src/pvaClientProcess.cpp index fefda9f..3bffa15 100644 --- a/src/pvaClientProcess.cpp +++ b/src/pvaClientProcess.cpp @@ -54,11 +54,21 @@ PvaClientProcess::PvaClientProcess( connectState(connectIdle), processState(processIdle) { + if(PvaClient::getDebug()) cout<< "PvaClientProcess::PvaClientProcess()\n"; } PvaClientProcess::~PvaClientProcess() { - destroy(); + if(PvaClient::getDebug()) cout<< "PvaClientProcess::~PvaClientProcess()\n"; + { + Lock xx(mutex); + if(isDestroyed) { + cerr<< "Why was PvaClientProcess::~PvaClientProcess() called more then once????\n"; + return; + } + isDestroyed = true; + } + channelProcess->destroy(); } // from ChannelProcessRequester @@ -97,19 +107,6 @@ void PvaClientProcess::processDone( waitForProcess.signal(); } - -// from PvaClientProcess -void PvaClientProcess::destroy() -{ - { - Lock xx(mutex); - if(isDestroyed) return; - isDestroyed = true; - } - if(channelProcess) channelProcess->destroy(); - channelProcess.reset(); -} - void PvaClientProcess::connect() { if(isDestroyed) throw std::runtime_error("pvaClientProcess was destroyed"); @@ -129,7 +126,8 @@ void PvaClientProcess::issueConnect() + " pvaClientProcess already connected "; throw std::runtime_error(message); } - processRequester = ChannelProcessRequester::shared_pointer(new ChannelProcessRequesterImpl(this)); + ChannelProcessRequester::shared_pointer processRequester( + ChannelProcessRequester::shared_pointer(this)); connectState = connectActive; channelProcess = channel->createChannelProcess(processRequester,pvRequest); } diff --git a/src/pvaClientPut.cpp b/src/pvaClientPut.cpp index aa061e4..b2c74c0 100644 --- a/src/pvaClientPut.cpp +++ b/src/pvaClientPut.cpp @@ -60,11 +60,21 @@ PvaClientPut::PvaClientPut( connectState(connectIdle), putState(putIdle) { + if(PvaClient::getDebug()) cout<< "PvaClientPut::PvaClientPut()\n"; } PvaClientPut::~PvaClientPut() { - destroy(); + if(PvaClient::getDebug()) cout<< "PvaClientPut::~PvaClientPut()\n"; + { + Lock xx(mutex); + if(isDestroyed) { + cerr<< "Why was PvaClientPut::~PvaClientPut() called more then once????\n"; + return; + } + isDestroyed = true; + } + if(channelPut) channelPut->destroy(); } void PvaClientPut::checkPutState() @@ -116,6 +126,7 @@ void PvaClientPut::getDone( { if(isDestroyed) throw std::runtime_error("pvaClientPut was destroyed"); channelGetPutStatus = status; + connectState = connected; if(status.isOK()) { PVStructurePtr pvs = pvaClientData->getPVStructure(); pvs->copyUnchecked(*pvStructure,*bitSet); @@ -135,27 +146,16 @@ void PvaClientPut::putDone( waitForGetPut.signal(); } - -// from PvaClientPut -void PvaClientPut::destroy() -{ - { - Lock xx(mutex); - if(isDestroyed) return; - isDestroyed = true; - } - if(channelPut) channelPut->destroy(); - channelPut.reset(); -} - void PvaClientPut::connect() { if(isDestroyed) throw std::runtime_error("pvaClientPut was destroyed"); issueConnect(); Status status = waitConnect(); if(status.isOK()) return; - string message = string("channel ") + channel->getChannelName() - + " PvaClientPut::connect " + status.getMessage(); + string message = string("channel ") + + channel->getChannelName() + + " PvaClientPut::connect " + + status.getMessage(); throw std::runtime_error(message); } @@ -167,7 +167,7 @@ void PvaClientPut::issueConnect() + " pvaClientPut already connected "; throw std::runtime_error(message); } - putRequester = ChannelPutRequester::shared_pointer(new ChannelPutRequesterImpl(this)); + ChannelPutRequester::shared_pointer putRequester(ChannelPutRequester::shared_pointer(this)); connectState = connectActive; channelPut = channel->createChannelPut(putRequester,pvRequest); } @@ -175,13 +175,17 @@ void PvaClientPut::issueConnect() Status PvaClientPut::waitConnect() { if(isDestroyed) throw std::runtime_error("pvaClientPut was destroyed"); + if(connectState==connected) { + if(!channelPutConnectStatus.isOK()) connectState = connectIdle; + return channelPutConnectStatus; + } if(connectState!=connectActive) { string message = string("channel ") + channel->getChannelName() + " pvaClientPut illegal connect state "; throw std::runtime_error(message); } waitForConnect.wait(); - connectState = channelPutConnectStatus.isOK() ? connected : connectIdle; + if(!channelPutConnectStatus.isOK()) connectState = connectIdle; return channelPutConnectStatus; } @@ -191,8 +195,10 @@ void PvaClientPut::get() issueGet(); Status status = waitGet(); if(status.isOK()) return; - string message = string("channel ") + channel->getChannelName() - + " PvaClientPut::get " + status.getMessage(); + string message = string("channel ") + + channel->getChannelName() + + " PvaClientPut::get " + + status.getMessage(); throw std::runtime_error(message); } @@ -201,12 +207,12 @@ void PvaClientPut::issueGet() if(isDestroyed) throw std::runtime_error("pvaClientPut was destroyed"); if(connectState==connectIdle) connect(); if(putState!=putIdle) { - string message = string("channel ") + channel->getChannelName() + string message = string("channel ") + + channel->getChannelName() + "PvaClientPut::issueGet get or put aleady active "; throw std::runtime_error(message); } putState = getActive; - pvaClientData->getChangedBitSet()->clear(); channelPut->get(); } @@ -215,7 +221,7 @@ Status PvaClientPut::waitGet() if(isDestroyed) throw std::runtime_error("pvaClientPut was destroyed"); if(putState!=getActive){ string message = string("channel ") + channel->getChannelName() - + " PvaClientPut::waitGet llegal put state"; + + " PvaClientPut::waitGet illegal put state"; throw std::runtime_error(message); } waitForGetPut.wait(); @@ -229,8 +235,10 @@ void PvaClientPut::put() issuePut(); Status status = waitPut(); if(status.isOK()) return; - string message = string("channel ") + channel->getChannelName() - + " PvaClientPut::put " + status.getMessage(); + string message = string("channel ") + + channel->getChannelName() + + " PvaClientPut::put " + + status.getMessage(); throw std::runtime_error(message); } @@ -252,7 +260,7 @@ Status PvaClientPut::waitPut() if(isDestroyed) throw std::runtime_error("pvaClientPut was destroyed"); if(putState!=putActive){ string message = string("channel ") + channel->getChannelName() - + " PvaClientPut::waitPut llegal put state"; + + " PvaClientPut::waitPut illegal put state"; throw std::runtime_error(message); } waitForGetPut.wait(); diff --git a/src/pvaClientPutData.cpp b/src/pvaClientPutData.cpp index 04a9afd..59208fa 100644 --- a/src/pvaClientPutData.cpp +++ b/src/pvaClientPutData.cpp @@ -36,7 +36,6 @@ public: void postPut() { easyData->postPut(fieldNumber);} }; - typedef std::tr1::shared_ptr PVArrayPtr; static ConvertPtr convert = getConvert(); static string noValue("no value field"); diff --git a/src/pvaClientPutGet.cpp b/src/pvaClientPutGet.cpp index 07d4574..fe11e7b 100644 --- a/src/pvaClientPutGet.cpp +++ b/src/pvaClientPutGet.cpp @@ -76,11 +76,21 @@ PvaClientPutGet::PvaClientPutGet( connectState(connectIdle), putGetState(putGetIdle) { + if(PvaClient::getDebug()) cout<< "PvaClientPutGet::PvaClientPutGet()\n"; } PvaClientPutGet::~PvaClientPutGet() { - destroy(); + if(PvaClient::getDebug()) cout<< "PvaClientPutGet::~PvaClientPutGet()\n"; + { + Lock xx(mutex); + if(isDestroyed) { + cerr<< "Why was PvaClientPutGet::~PvaClientPutGet() called more then once????\n"; + return; + } + isDestroyed = true; + } + channelPutGet->destroy(); } void PvaClientPutGet::checkPutGetState() @@ -173,20 +183,6 @@ void PvaClientPutGet::getGetDone( waitForPutGet.signal(); } - - -// from PvaClientPutGet -void PvaClientPutGet::destroy() -{ - { - Lock xx(mutex); - if(isDestroyed) return; - isDestroyed = true; - } - if(channelPutGet) channelPutGet->destroy(); - channelPutGet.reset(); -} - void PvaClientPutGet::connect() { if(isDestroyed) throw std::runtime_error("pvaClientPutGet was destroyed"); @@ -206,7 +202,7 @@ void PvaClientPutGet::issueConnect() + " pvaClientPutGet already connected "; throw std::runtime_error(message); } - putGetRequester = ChannelPutGetRequester::shared_pointer(new ChannelPutGetRequesterImpl(this)); + ChannelPutGetRequester::shared_pointer putGetRequester(ChannelPutGetRequester::shared_pointer(this)); connectState = connectActive; channelPutGet = channel->createChannelPutGet(putGetRequester,pvRequest); } From cd9bdec84ecc7ab584ad3314da1d0083fd572b4f Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Tue, 17 May 2016 09:24:38 -0400 Subject: [PATCH 02/12] replace shared_pointer by shared_from_this --- src/pv/pvaClient.h | 17 ++++++++++------- src/pvaClientChannel.cpp | 2 +- src/pvaClientGet.cpp | 2 +- src/pvaClientProcess.cpp | 3 +-- src/pvaClientPut.cpp | 2 +- src/pvaClientPutGet.cpp | 2 +- 6 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/pv/pvaClient.h b/src/pv/pvaClient.h index c70edf5..11e839a 100644 --- a/src/pv/pvaClient.h +++ b/src/pv/pvaClient.h @@ -223,7 +223,6 @@ class PvaClientGetCache; typedef std::tr1::shared_ptr PvaClientGetCachePtr; class PvaClientPutCache; typedef std::tr1::shared_ptr PvaClientPutCachePtr; -class ChannelRequesterImpl; /** * @brief An easy to use alternative to directly calling the Channel methods of pvAccess. @@ -288,12 +287,12 @@ public: * @return The interface. */ PvaClientFieldPtr createField(); - /** Create an PvaClientField for the specified subField. + /** Calls the next method with request = ""; * @param subField The syntax for subField is defined in package org.epics.pvdata.copy * @return The interface. */ PvaClientFieldPtr createField(std::string const & subField); - /** Calls the next method with request = ""; + /** Create an PvaClientField for the specified subField. * @return The interface. * @throw runtime_error if failure. */ @@ -886,7 +885,8 @@ private: * @author mrk */ class epicsShareClass PvaClientProcess : - public epics::pvAccess::ChannelProcessRequester + public epics::pvAccess::ChannelProcessRequester, + public std::tr1::enable_shared_from_this { public: POINTER_DEFINITIONS(PvaClientProcess); @@ -972,7 +972,8 @@ private: * @author mrk */ class epicsShareClass PvaClientGet : - public epics::pvAccess::ChannelGetRequester + public epics::pvAccess::ChannelGetRequester, + public std::tr1::enable_shared_from_this { public: POINTER_DEFINITIONS(PvaClientGet); @@ -1071,7 +1072,8 @@ private: * @author mrk */ class epicsShareClass PvaClientPut : - public epics::pvAccess::ChannelPutRequester + public epics::pvAccess::ChannelPutRequester, + public std::tr1::enable_shared_from_this { public: POINTER_DEFINITIONS(PvaClientPut); @@ -1182,7 +1184,8 @@ private : * @author mrk */ class epicsShareClass PvaClientPutGet : - public epics::pvAccess::ChannelPutGetRequester + public epics::pvAccess::ChannelPutGetRequester, + public std::tr1::enable_shared_from_this { public: POINTER_DEFINITIONS(PvaClientPutGet); diff --git a/src/pvaClientChannel.cpp b/src/pvaClientChannel.cpp index a08c332..ed6467a 100644 --- a/src/pvaClientChannel.cpp +++ b/src/pvaClientChannel.cpp @@ -290,7 +290,7 @@ void PvaClientChannel::issueConnect() if(!provider) { throw std::runtime_error(channelName + " provider " + providerName + " not registered"); } - ChannelRequester::shared_pointer channelRequester(ChannelRequester::shared_pointer(this)); + ChannelRequester::shared_pointer channelRequester(shared_from_this()); if(PvaClient::getDebug()) cout << "PvaClientChannel::issueConnect calling provider->createChannel\n"; channel = provider->createChannel(channelName,channelRequester,ChannelProvider::PRIORITY_DEFAULT); if(!channel) { diff --git a/src/pvaClientGet.cpp b/src/pvaClientGet.cpp index 0542704..a3515c2 100644 --- a/src/pvaClientGet.cpp +++ b/src/pvaClientGet.cpp @@ -151,7 +151,7 @@ void PvaClientGet::issueConnect() + " pvaClientGet already connected "; throw std::runtime_error(message); } - ChannelGetRequester::shared_pointer getRequester(ChannelGetRequester::shared_pointer(this)); + ChannelGetRequester::shared_pointer getRequester(shared_from_this()); connectState = connectActive; channelGet = channel->createChannelGet(getRequester,pvRequest); } diff --git a/src/pvaClientProcess.cpp b/src/pvaClientProcess.cpp index 3bffa15..cb46b3b 100644 --- a/src/pvaClientProcess.cpp +++ b/src/pvaClientProcess.cpp @@ -126,8 +126,7 @@ void PvaClientProcess::issueConnect() + " pvaClientProcess already connected "; throw std::runtime_error(message); } - ChannelProcessRequester::shared_pointer processRequester( - ChannelProcessRequester::shared_pointer(this)); + ChannelProcessRequester::shared_pointer processRequester(shared_from_this()); connectState = connectActive; channelProcess = channel->createChannelProcess(processRequester,pvRequest); } diff --git a/src/pvaClientPut.cpp b/src/pvaClientPut.cpp index b2c74c0..e8760f0 100644 --- a/src/pvaClientPut.cpp +++ b/src/pvaClientPut.cpp @@ -167,7 +167,7 @@ void PvaClientPut::issueConnect() + " pvaClientPut already connected "; throw std::runtime_error(message); } - ChannelPutRequester::shared_pointer putRequester(ChannelPutRequester::shared_pointer(this)); + ChannelPutRequester::shared_pointer putRequester(shared_from_this()); connectState = connectActive; channelPut = channel->createChannelPut(putRequester,pvRequest); } diff --git a/src/pvaClientPutGet.cpp b/src/pvaClientPutGet.cpp index fe11e7b..35a84b5 100644 --- a/src/pvaClientPutGet.cpp +++ b/src/pvaClientPutGet.cpp @@ -202,7 +202,7 @@ void PvaClientPutGet::issueConnect() + " pvaClientPutGet already connected "; throw std::runtime_error(message); } - ChannelPutGetRequester::shared_pointer putGetRequester(ChannelPutGetRequester::shared_pointer(this)); + ChannelPutGetRequester::shared_pointer putGetRequester(shared_from_this()); connectState = connectActive; channelPutGet = channel->createChannelPutGet(putGetRequester,pvRequest); } From 40fb22ebd916ea7614d6da245d9aabd1996fcfa5 Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Tue, 17 May 2016 14:26:41 -0400 Subject: [PATCH 03/12] add destroy to pvaClientChannel; in pvaClientGet channel is weak_pointer --- src/pv/pvaClient.h | 15 +++++++++------ src/pvaClient.cpp | 8 +++++++- src/pvaClientChannel.cpp | 16 +++++++++++++--- src/pvaClientGet.cpp | 40 ++++++++++++++++++++++++++++++++-------- 4 files changed, 61 insertions(+), 18 deletions(-) diff --git a/src/pv/pvaClient.h b/src/pv/pvaClient.h index 11e839a..1ff9806 100644 --- a/src/pv/pvaClient.h +++ b/src/pv/pvaClient.h @@ -236,6 +236,10 @@ class epicsShareClass PvaClientChannel : public: POINTER_DEFINITIONS(PvaClientChannel); ~PvaClientChannel(); + /** Destroy the connection to the server. + * + */ + void destroy(); /** ChannelRequester method * @param status The status * @param channel The channel @@ -455,10 +459,6 @@ public: { return shared_from_this(); } - /** Deprecated method - * \deprecated This method will go away in future versions. - */ - void destroy() EPICS_DEPRECATED {} private: static PvaClientChannelPtr create( @@ -1035,7 +1035,10 @@ public: /** Deprecated method * \deprecated This method will go away in future versions. */ - void destroy() EPICS_DEPRECATED {} + void destroy() EPICS_DEPRECATED + { +channelGet->destroy(); + } private: PvaClientGet( PvaClientPtr const &pvaClient, @@ -1046,7 +1049,7 @@ private: enum GetConnectState {connectIdle,connectActive,connected}; PvaClient::weak_pointer pvaClient; - epics::pvAccess::Channel::shared_pointer channel; + epics::pvAccess::Channel::weak_pointer channel; epics::pvData::PVStructurePtr pvRequest; epics::pvData::Mutex mutex; epics::pvData::Event waitForConnect; diff --git a/src/pvaClient.cpp b/src/pvaClient.cpp index 3305d3c..8cc1a75 100644 --- a/src/pvaClient.cpp +++ b/src/pvaClient.cpp @@ -38,7 +38,13 @@ public: PvaClientChannelCache(){} ~PvaClientChannelCache(){ if(PvaClient::getDebug()) cout << "PvaClientChannelCache::~PvaClientChannelCache\n"; - pvaClientChannelMap.clear(); + map::iterator iter; + for(iter = pvaClientChannelMap.begin(); iter != pvaClientChannelMap.end(); ++iter) + { + PvaClientChannelPtr pvaChannel = iter->second; + pvaChannel->destroy(); + } +// pvaClientChannelMap.clear(); } PvaClientChannelPtr getChannel( string const & channelName, diff --git a/src/pvaClientChannel.cpp b/src/pvaClientChannel.cpp index ed6467a..542a466 100644 --- a/src/pvaClientChannel.cpp +++ b/src/pvaClientChannel.cpp @@ -149,17 +149,27 @@ PvaClientChannel::~PvaClientChannel() << " this " << this << " channel " << channel << endl; } - { + destroy(); +} + +void PvaClientChannel::destroy() +{ + { Lock xx(mutex); if(isDestroyed) return; isDestroyed = true; } + if(PvaClient::getDebug()) { + cout << "PvaClientChannel::destroy() " + << " channelName " << channelName + << " this " << this << " channel " << channel + << endl; + } if(PvaClient::getDebug()) showCache(); if(channel) channel->destroy(); -if(channel) channel.reset(); + if(channel) channel.reset(); pvaClientGetCache.reset(); pvaClientPutCache.reset(); - } diff --git a/src/pvaClientGet.cpp b/src/pvaClientGet.cpp index a3515c2..500b46f 100644 --- a/src/pvaClientGet.cpp +++ b/src/pvaClientGet.cpp @@ -107,7 +107,8 @@ void PvaClientGet::channelGetConnect( this->channelGet = channelGet; if(status.isOK()) { pvaClientData = PvaClientGetData::create(structure); - pvaClientData->setMessagePrefix(channel->getChannelName()); + Channel::shared_pointer chan(channel.lock()); + if(chan) pvaClientData->setMessagePrefix(chan->getChannelName()); } } waitForConnect.signal(); @@ -138,7 +139,10 @@ void PvaClientGet::connect() issueConnect(); Status status = waitConnect(); if(status.isOK()) return; - string message = string("channel ") + channel->getChannelName() + Channel::shared_pointer chan(channel.lock()); + string channelName("disconnected"); + if(chan) channelName = chan->getChannelName(); + string message = string("channel ") + channelName + " PvaClientGet::connect " + status.getMessage(); throw std::runtime_error(message); } @@ -147,13 +151,21 @@ void PvaClientGet::issueConnect() { if(isDestroyed) throw std::runtime_error("pvaClientGet was destroyed"); if(connectState!=connectIdle) { - string message = string("channel ") + channel->getChannelName() + Channel::shared_pointer chan(channel.lock()); + string channelName("disconnected"); + if(chan) channelName = chan->getChannelName(); + string message = string("channel ") + channelName + " pvaClientGet already connected "; throw std::runtime_error(message); } ChannelGetRequester::shared_pointer getRequester(shared_from_this()); connectState = connectActive; - channelGet = channel->createChannelGet(getRequester,pvRequest); + Channel::shared_pointer chan(channel.lock()); + if(chan) { + channelGet = chan->createChannelGet(getRequester,pvRequest); + return; + } + throw std::runtime_error("PvaClientGet::issueConnect channel was destroyed"); } Status PvaClientGet::waitConnect() @@ -166,7 +178,10 @@ Status PvaClientGet::waitConnect() return channelGetConnectStatus; } if(connectState!=connectActive) { - string message = string("channel ") + channel->getChannelName() + Channel::shared_pointer chan(channel.lock()); + string channelName("disconnected"); + if(chan) channelName = chan->getChannelName(); + string message = string("channel ") + channelName + " pvaClientGet illegal connect state "; throw std::runtime_error(message); } @@ -182,7 +197,10 @@ void PvaClientGet::get() issueGet(); Status status = waitGet(); if(status.isOK()) return; - string message = string("channel ") + channel->getChannelName() + Channel::shared_pointer chan(channel.lock()); + string channelName("disconnected"); + if(chan) channelName = chan->getChannelName(); + string message = string("channel ") + channelName + " PvaClientGet::get " + status.getMessage(); throw std::runtime_error(message); } @@ -192,7 +210,10 @@ void PvaClientGet::issueGet() if(isDestroyed) throw std::runtime_error("pvaClientGet was destroyed"); if(connectState==connectIdle) connect(); if(getState!=getIdle) { - string message = string("channel ") + channel->getChannelName() + Channel::shared_pointer chan(channel.lock()); + string channelName("disconnected"); + if(chan) channelName = chan->getChannelName(); + string message = string("channel ") + channelName + " PvaClientGet::issueGet get aleady active "; throw std::runtime_error(message); } @@ -210,7 +231,10 @@ Status PvaClientGet::waitGet() return channelGetStatus; } if(getState!=getActive){ - string message = string("channel ") + channel->getChannelName() + Channel::shared_pointer chan(channel.lock()); + string channelName("disconnected"); + if(chan) channelName = chan->getChannelName(); + string message = string("channel ") + channelName + " PvaClientGet::waitGet llegal get state"; throw std::runtime_error(message); } From adc008dee67d2028164edf3e04e6a13e1223783c Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Tue, 17 May 2016 15:04:02 -0400 Subject: [PATCH 04/12] handle weak_pointer.lock() properly --- src/pvaClientChannel.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pvaClientChannel.cpp b/src/pvaClientChannel.cpp index 542a466..d4730d3 100644 --- a/src/pvaClientChannel.cpp +++ b/src/pvaClientChannel.cpp @@ -233,8 +233,8 @@ void PvaClientChannel::channelStateChange( string PvaClientChannel::getRequesterName() { PvaClientPtr yyy = pvaClient.lock(); - if(!yyy) throw std::runtime_error( - "PvaClientChannel::getRequesterName() PvaClientChannel isDestroyed"); + if(!yyy) throw std::runtime_error( + "PvaClientChannel::getRequesterName() PvaClient isDestroyed"); return yyy->getRequesterName(); } @@ -243,8 +243,8 @@ void PvaClientChannel::message( MessageType messageType) { PvaClientPtr yyy = pvaClient.lock(); - if(isDestroyed) throw std::runtime_error( - "PvaClientChannel::message() pvaClientChannel isDestroyed"); + if(!yyy) throw std::runtime_error( + "PvaClientChannel::message() pvaClient isDestroyed"); yyy->message(channelName + " " + message, messageType); } From a0cc581d3f15ae63a07eb3a8080fa9aa2368705c Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Thu, 19 May 2016 12:01:21 -0400 Subject: [PATCH 05/12] still working on RAII --- src/pv/pvaClient.h | 13 +++++-------- src/pvaClient.cpp | 19 ++++++++++--------- src/pvaClientChannel.cpp | 21 +++------------------ src/pvaClientGet.cpp | 18 +++++++++++++----- 4 files changed, 31 insertions(+), 40 deletions(-) diff --git a/src/pv/pvaClient.h b/src/pv/pvaClient.h index 1ff9806..ffa3229 100644 --- a/src/pv/pvaClient.h +++ b/src/pv/pvaClient.h @@ -236,10 +236,6 @@ class epicsShareClass PvaClientChannel : public: POINTER_DEFINITIONS(PvaClientChannel); ~PvaClientChannel(); - /** Destroy the connection to the server. - * - */ - void destroy(); /** ChannelRequester method * @param status The status * @param channel The channel @@ -459,6 +455,10 @@ public: { return shared_from_this(); } + /** Deprecated method + * \deprecated This method will go away in future versions. + */ + void destroy() EPICS_DEPRECATED {} private: static PvaClientChannelPtr create( @@ -1035,10 +1035,7 @@ public: /** Deprecated method * \deprecated This method will go away in future versions. */ - void destroy() EPICS_DEPRECATED - { -channelGet->destroy(); - } + void destroy() EPICS_DEPRECATED {} private: PvaClientGet( PvaClientPtr const &pvaClient, diff --git a/src/pvaClient.cpp b/src/pvaClient.cpp index 8cc1a75..e52747c 100644 --- a/src/pvaClient.cpp +++ b/src/pvaClient.cpp @@ -38,13 +38,6 @@ public: PvaClientChannelCache(){} ~PvaClientChannelCache(){ if(PvaClient::getDebug()) cout << "PvaClientChannelCache::~PvaClientChannelCache\n"; - map::iterator iter; - for(iter = pvaClientChannelMap.begin(); iter != pvaClientChannelMap.end(); ++iter) - { - PvaClientChannelPtr pvaChannel = iter->second; - pvaChannel->destroy(); - } -// pvaClientChannelMap.clear(); } PvaClientChannelPtr getChannel( string const & channelName, @@ -153,8 +146,16 @@ PvaClient::~PvaClient() { } if(PvaClient::debug) showCache(); pvaClientChannelCache.reset(); - if(pvaStarted) ClientFactory::stop(); - if(caStarted) CAClientFactory::stop(); + if(pvaStarted){ + if(PvaClient::debug) cout<< "calling ClientFactory::stop()\n"; + ClientFactory::stop(); + if(PvaClient::debug) cout<< "after calling ClientFactory::stop()\n"; + } + if(caStarted) { + if(PvaClient::debug) cout<< "calling CAClientFactory::stop()\n"; + CAClientFactory::stop(); + if(PvaClient::debug) cout<< "after calling CAClientFactory::stop()\n"; + } } string PvaClient:: getRequesterName() diff --git a/src/pvaClientChannel.cpp b/src/pvaClientChannel.cpp index d4730d3..1d3351a 100644 --- a/src/pvaClientChannel.cpp +++ b/src/pvaClientChannel.cpp @@ -149,25 +149,12 @@ PvaClientChannel::~PvaClientChannel() << " this " << this << " channel " << channel << endl; } - destroy(); -} - -void PvaClientChannel::destroy() -{ - { + { Lock xx(mutex); if(isDestroyed) return; isDestroyed = true; } - if(PvaClient::getDebug()) { - cout << "PvaClientChannel::destroy() " - << " channelName " << channelName - << " this " << this << " channel " << channel - << endl; - } if(PvaClient::getDebug()) showCache(); - if(channel) channel->destroy(); - if(channel) channel.reset(); pvaClientGetCache.reset(); pvaClientPutCache.reset(); } @@ -233,8 +220,7 @@ void PvaClientChannel::channelStateChange( string PvaClientChannel::getRequesterName() { PvaClientPtr yyy = pvaClient.lock(); - if(!yyy) throw std::runtime_error( - "PvaClientChannel::getRequesterName() PvaClient isDestroyed"); + if(!yyy) return string("PvaClientChannel::getRequesterName() PvaClient isDestroyed"); return yyy->getRequesterName(); } @@ -243,8 +229,7 @@ void PvaClientChannel::message( MessageType messageType) { PvaClientPtr yyy = pvaClient.lock(); - if(!yyy) throw std::runtime_error( - "PvaClientChannel::message() pvaClient isDestroyed"); + if(!yyy) return; yyy->message(channelName + " " + message, messageType); } diff --git a/src/pvaClientGet.cpp b/src/pvaClientGet.cpp index 500b46f..4e1242c 100644 --- a/src/pvaClientGet.cpp +++ b/src/pvaClientGet.cpp @@ -68,7 +68,6 @@ PvaClientGet::~PvaClientGet() if(isDestroyed) return; isDestroyed = true; } -// if(channelGet) channelGet->destroy(); } void PvaClientGet::checkGetState() @@ -81,14 +80,13 @@ void PvaClientGet::checkGetState() // from ChannelGetRequester string PvaClientGet::getRequesterName() { - PvaClientPtr yyy = pvaClient.lock(); - if(!yyy) return string(); - return yyy->getRequesterName(); + PvaClientPtr yyy = pvaClient.lock(); + if(!yyy) return string("PvaClientGet::getRequesterName() PvaClient isDestroyed"); + return yyy->getRequesterName(); } void PvaClientGet::message(string const & message,MessageType messageType) { - if(isDestroyed) throw std::runtime_error("pvaClientGet was destroyed"); PvaClientPtr yyy = pvaClient.lock(); if(!yyy) return; yyy->message(message, messageType); @@ -99,6 +97,11 @@ void PvaClientGet::channelGetConnect( ChannelGet::shared_pointer const & channelGet, StructureConstPtr const & structure) { + if(PvaClient::getDebug()) { + cout << "PvaClientGet::channelGetConnect" + << " status.isOK " << (status.isOK() ? "true" : "false") + << endl; + } if(isDestroyed) throw std::runtime_error("pvaClientGet was destroyed"); { Lock xx(mutex); @@ -121,6 +124,11 @@ void PvaClientGet::getDone( PVStructurePtr const & pvStructure, BitSetPtr const & bitSet) { + if(PvaClient::getDebug()) { + cout << "PvaClientGet::getDone" + << " status.isOK " << (status.isOK() ? "true" : "false") + << endl; + } if(isDestroyed) throw std::runtime_error("pvaClientGet was destroyed"); { Lock xx(mutex); From 3920215182680a74087b5e58157f097c8de1379b Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Thu, 19 May 2016 12:45:15 -0400 Subject: [PATCH 06/12] change message for channelStateChange --- src/pvaClientChannel.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/pvaClientChannel.cpp b/src/pvaClientChannel.cpp index 1d3351a..7b692b2 100644 --- a/src/pvaClientChannel.cpp +++ b/src/pvaClientChannel.cpp @@ -167,7 +167,6 @@ void PvaClientChannel::channelCreated(const Status& status, Channel::shared_poin << " channelName " << channelName << " isConnected " << (channel->isConnected() ? "true" : "false") << " status.isOK " << (status.isOK() ? "true" : "false") - << " this " << this << endl; } Lock xx(mutex); @@ -196,9 +195,7 @@ void PvaClientChannel::channelStateChange( if(PvaClient::getDebug()) { cout << " PvaClientChannel::channelStateChange " << " channelName " << channelName - << " is connected " << (connectionState==Channel::CONNECTED ? "true" : "false") - << " isDestroyed " << isDestroyed - << " this " << this + << " " << Channel::ConnectionStateNames[connectionState] << endl; } Lock xx(mutex); From 643fa9b40bfdd0892db90ff40404be21212b4962 Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Fri, 20 May 2016 06:22:13 -0400 Subject: [PATCH 07/12] still working on RAII --- src/pv/pvaClient.h | 26 +++++++------- src/pvaClientChannel.cpp | 67 +++++++++++++++++++++++++++++----- src/pvaClientGet.cpp | 77 +++++++++++++++++++++++++++------------- src/pvaClientProcess.cpp | 21 ----------- src/pvaClientPut.cpp | 27 -------------- src/pvaClientPutGet.cpp | 44 ----------------------- 6 files changed, 123 insertions(+), 139 deletions(-) diff --git a/src/pv/pvaClient.h b/src/pv/pvaClient.h index ffa3229..a78284b 100644 --- a/src/pv/pvaClient.h +++ b/src/pv/pvaClient.h @@ -223,15 +223,17 @@ class PvaClientGetCache; typedef std::tr1::shared_ptr PvaClientGetCachePtr; class PvaClientPutCache; typedef std::tr1::shared_ptr PvaClientPutCachePtr; +class ChannelRequesterImpl; +typedef std::tr1::shared_ptr ChannelRequesterImplPtr; /** * @brief An easy to use alternative to directly calling the Channel methods of pvAccess. * * @author mrk */ -class epicsShareClass PvaClientChannel : - public epics::pvAccess::ChannelRequester, - public std::tr1::enable_shared_from_this +class epicsShareClass PvaClientChannel //: +// public epics::pvAccess::ChannelRequester, +// public std::tr1::enable_shared_from_this { public: POINTER_DEFINITIONS(PvaClientChannel); @@ -451,10 +453,6 @@ public: /** Get the number of cached gets and puts. */ size_t cacheSize(); - PvaClientChannelPtr getPtrSelf() - { - return shared_from_this(); - } /** Deprecated method * \deprecated This method will go away in future versions. */ @@ -485,6 +483,7 @@ private: epics::pvData::Mutex mutex; epics::pvData::Event waitForConnect; epics::pvAccess::Channel::shared_pointer channel; + ChannelRequesterImplPtr channelRequester; friend class PvaClient; }; @@ -971,9 +970,11 @@ private: * * @author mrk */ -class epicsShareClass PvaClientGet : - public epics::pvAccess::ChannelGetRequester, - public std::tr1::enable_shared_from_this +class ChannelGetRequesterImpl; +typedef std::tr1::shared_ptr ChannelGetRequesterImplPtr; +class epicsShareClass PvaClientGet //: +// public epics::pvAccess::ChannelGetRequester, +// public std::tr1::enable_shared_from_this { public: POINTER_DEFINITIONS(PvaClientGet); @@ -1063,7 +1064,7 @@ private: enum GetState {getIdle,getActive,getComplete}; GetState getState; - friend class ChannelGetRequesterImpl; + ChannelGetRequesterImplPtr channelGetRequester; }; /** @@ -1175,7 +1176,6 @@ private : enum PutState {putIdle,getActive,putActive}; PutState putState; - friend class ChannelPutRequesterImpl; }; /** @@ -1311,7 +1311,6 @@ private : enum PutGetState {putGetIdle,putGetActive,putGetComplete}; PutGetState putGetState; - friend class ChannelPutGetRequesterImpl; }; //class ChannelMonitorRequester; // private to PvaClientMonitor @@ -1464,7 +1463,6 @@ private: MonitorConnectState connectState; bool userPoll; bool userWait; - friend class ChannelMonitorRequester; }; }} diff --git a/src/pvaClientChannel.cpp b/src/pvaClientChannel.cpp index 7b692b2..22ce712 100644 --- a/src/pvaClientChannel.cpp +++ b/src/pvaClientChannel.cpp @@ -122,6 +122,63 @@ size_t PvaClientPutCache::cacheSize() } +class ChannelRequesterImpl : public ChannelRequester +{ + PvaClientChannel::weak_pointer pvaClientChannel; + PvaClient::weak_pointer pvaClient; +public: + ChannelRequesterImpl( + PvaClientChannelPtr const & pvaClientChannel, + PvaClientPtr const &pvaClient) + : pvaClientChannel(pvaClientChannel), + pvaClient(pvaClient) + {} + virtual ~ChannelRequesterImpl() { + if(PvaClient::getDebug()) std::cout << "~ChannelRequesterImpl" << std::endl; + } + + virtual std::string getRequesterName() { + PvaClientChannelPtr clientChannel(pvaClientChannel.lock()); + if(!clientChannel) return string("clientChannel is null"); + return clientChannel->getRequesterName(); + } + + virtual void message(std::string const & message, epics::pvData::MessageType messageType) { + PvaClientChannelPtr clientChannel(pvaClientChannel.lock()); + if(!clientChannel) return; + clientChannel->message(message,messageType); + } + + virtual void channelCreated( + const epics::pvData::Status& status, + Channel::shared_pointer const & channel) + { + PvaClientChannelPtr clientChannel(pvaClientChannel.lock()); + if(!clientChannel) return; + clientChannel->channelCreated(status,channel); + } + + virtual void channelStateChange( + Channel::shared_pointer const & channel, + Channel::ConnectionState connectionState) + { + PvaClientChannelPtr clientChannel(pvaClientChannel.lock()); + if(!clientChannel) return; + clientChannel->channelStateChange(channel,connectionState); + } +}; + +PvaClientChannelPtr PvaClientChannel::create( + PvaClientPtr const &pvaClient, + string const & channelName, + string const & providerName) +{ + PvaClientChannelPtr channel(new PvaClientChannel(pvaClient,channelName,providerName)); + channel->channelRequester = ChannelRequesterImplPtr( + new ChannelRequesterImpl(channel,pvaClient)); + return channel; +} + PvaClientChannel::PvaClientChannel( PvaClientPtr const &pvaClient, @@ -282,7 +339,7 @@ void PvaClientChannel::issueConnect() if(!provider) { throw std::runtime_error(channelName + " provider " + providerName + " not registered"); } - ChannelRequester::shared_pointer channelRequester(shared_from_this()); +// ChannelRequester::shared_pointer channelRequester(shared_from_this()); if(PvaClient::getDebug()) cout << "PvaClientChannel::issueConnect calling provider->createChannel\n"; channel = provider->createChannel(channelName,channelRequester,ChannelProvider::PRIORITY_DEFAULT); if(!channel) { @@ -540,13 +597,5 @@ size_t PvaClientChannel::cacheSize() } -PvaClientChannelPtr PvaClientChannel::create( - PvaClientPtr const &pvaClient, - string const & channelName, - string const & providerName) -{ - PvaClientChannelPtr channel(new PvaClientChannel(pvaClient,channelName,providerName)); - return channel; -} }} diff --git a/src/pvaClientGet.cpp b/src/pvaClientGet.cpp index 4e1242c..5e5e6f0 100644 --- a/src/pvaClientGet.cpp +++ b/src/pvaClientGet.cpp @@ -22,30 +22,67 @@ using namespace std; namespace epics { namespace pvaClient { - class ChannelGetRequesterImpl : public ChannelGetRequester { - PvaClientGet * pvaClientGet; + PvaClientGet::weak_pointer pvaClientGet; + PvaClient::weak_pointer pvaClient; public: - ChannelGetRequesterImpl(PvaClientGet * pvaClientGet) - : pvaClientGet(pvaClientGet) {} - string getRequesterName() - {return pvaClientGet->getRequesterName();} - void message(string const & message,MessageType messageType) - {pvaClientGet->message(message,messageType);} - void channelGetConnect( + ChannelGetRequesterImpl( + PvaClientGetPtr const & pvaClientGet, + PvaClientPtr const &pvaClient) + : pvaClientGet(pvaClientGet), + pvaClient(pvaClient) + {} + virtual ~ChannelGetRequesterImpl() { + if(PvaClient::getDebug()) std::cout << "~ChannelGetRequesterImpl" << std::endl; + } + + virtual std::string getRequesterName() { + PvaClientGetPtr clientGet(pvaClientGet.lock()); + if(!clientGet) return string("clientGet is null"); + return clientGet->getRequesterName(); + } + + virtual void message(std::string const & message, epics::pvData::MessageType messageType) { + PvaClientGetPtr clientGet(pvaClientGet.lock()); + if(!clientGet) return; + clientGet->message(message,messageType); + } + + virtual void channelGetConnect( const Status& status, ChannelGet::shared_pointer const & channelGet, - StructureConstPtr const & structure) - {pvaClientGet->channelGetConnect(status,channelGet,structure);} - void getDone( + Structure::const_shared_pointer const & structure) + { + PvaClientGetPtr clientGet(pvaClientGet.lock()); + if(!clientGet) return; + clientGet->channelGetConnect(status,channelGet,structure); + } + + virtual void getDone( const Status& status, ChannelGet::shared_pointer const & channelGet, PVStructurePtr const & pvStructure, - BitSetPtr const & bitSet) - {pvaClientGet->getDone(status,channelGet,pvStructure,bitSet);} + BitSet::shared_pointer const & bitSet) + { + PvaClientGetPtr clientGet(pvaClientGet.lock()); + if(!clientGet) return; + clientGet->getDone(status,channelGet,pvStructure,bitSet); + } }; +PvaClientGetPtr PvaClientGet::create( + PvaClientPtr const &pvaClient, + Channel::shared_pointer const & channel, + PVStructurePtr const &pvRequest) +{ + PvaClientGetPtr epv(new PvaClientGet(pvaClient,channel,pvRequest)); + epv->channelGetRequester = ChannelGetRequesterImplPtr( + new ChannelGetRequesterImpl(epv,pvaClient)); + return epv; +} + + PvaClientGet::PvaClientGet( PvaClientPtr const &pvaClient, Channel::shared_pointer const & channel, @@ -166,11 +203,11 @@ void PvaClientGet::issueConnect() + " pvaClientGet already connected "; throw std::runtime_error(message); } - ChannelGetRequester::shared_pointer getRequester(shared_from_this()); +// ChannelGetRequester::shared_pointer channelGetRequester(shared_from_this()); connectState = connectActive; Channel::shared_pointer chan(channel.lock()); if(chan) { - channelGet = chan->createChannelGet(getRequester,pvRequest); + channelGet = chan->createChannelGet(channelGetRequester,pvRequest); return; } throw std::runtime_error("PvaClientGet::issueConnect channel was destroyed"); @@ -257,13 +294,5 @@ PvaClientGetDataPtr PvaClientGet::getData() return pvaClientData; } -PvaClientGetPtr PvaClientGet::create( - PvaClientPtr const &pvaClient, - Channel::shared_pointer const & channel, - PVStructurePtr const &pvRequest) -{ - PvaClientGetPtr epv(new PvaClientGet(pvaClient,channel,pvRequest)); - return epv; -} }} diff --git a/src/pvaClientProcess.cpp b/src/pvaClientProcess.cpp index cb46b3b..bbe7195 100644 --- a/src/pvaClientProcess.cpp +++ b/src/pvaClientProcess.cpp @@ -22,27 +22,6 @@ using namespace std; namespace epics { namespace pvaClient { - -class ChannelProcessRequesterImpl : public ChannelProcessRequester -{ - PvaClientProcess * pvaClientProcess; -public: - ChannelProcessRequesterImpl(PvaClientProcess * pvaClientProcess) - : pvaClientProcess(pvaClientProcess) {} - string getRequesterName() - {return pvaClientProcess->getRequesterName();} - void message(string const & message,MessageType messageType) - {pvaClientProcess->message(message,messageType);} - void channelProcessConnect( - const Status& status, - ChannelProcess::shared_pointer const & channelProcess) - {pvaClientProcess->channelProcessConnect(status,channelProcess);} - void processDone( - const Status& status, - ChannelProcess::shared_pointer const & channelProcess) - {pvaClientProcess->processDone(status,channelProcess);} -}; - PvaClientProcess::PvaClientProcess( PvaClientPtr const &pvaClient, Channel::shared_pointer const & channel, diff --git a/src/pvaClientPut.cpp b/src/pvaClientPut.cpp index e8760f0..7cec325 100644 --- a/src/pvaClientPut.cpp +++ b/src/pvaClientPut.cpp @@ -22,33 +22,6 @@ using namespace std; namespace epics { namespace pvaClient { -class ChannelPutRequesterImpl : public ChannelPutRequester -{ - PvaClientPut * pvaClientPut; -public: - ChannelPutRequesterImpl(PvaClientPut * pvaClientPut) - : pvaClientPut(pvaClientPut) {} - string getRequesterName() - {return pvaClientPut->getRequesterName();} - void message(string const & message,MessageType messageType) - {pvaClientPut->message(message,messageType);} - void channelPutConnect( - const Status& status, - ChannelPut::shared_pointer const & channelPut, - StructureConstPtr const & structure) - {pvaClientPut->channelPutConnect(status,channelPut,structure);} - void getDone( - const Status& status, - ChannelPut::shared_pointer const & channelPut, - PVStructurePtr const & pvStructure, - BitSetPtr const & bitSet) - {pvaClientPut->getDone(status,channelPut,pvStructure,bitSet);} - void putDone( - const Status& status, - ChannelPut::shared_pointer const & channelPut) - {pvaClientPut->putDone(status,channelPut);} -}; - PvaClientPut::PvaClientPut( PvaClientPtr const &pvaClient, Channel::shared_pointer const & channel, diff --git a/src/pvaClientPutGet.cpp b/src/pvaClientPutGet.cpp index 35a84b5..974bfc9 100644 --- a/src/pvaClientPutGet.cpp +++ b/src/pvaClientPutGet.cpp @@ -21,50 +21,6 @@ using namespace std; namespace epics { namespace pvaClient { -class ChannelPutGetRequesterImpl : public ChannelPutGetRequester -{ - PvaClientPutGet * pvaClientPutGet; -public: - ChannelPutGetRequesterImpl(PvaClientPutGet * pvaClientPutGet) - : pvaClientPutGet(pvaClientPutGet) {} - string getRequesterName() - {return pvaClientPutGet->getRequesterName();} - void message(string const & message,MessageType messageType) - {pvaClientPutGet->message(message,messageType);} - void channelPutGetConnect( - const epics::pvData::Status& status, - epics::pvAccess::ChannelPutGet::shared_pointer const & channelPutGet, - epics::pvData::StructureConstPtr const & putStructure, - epics::pvData::StructureConstPtr const & getStructure) - { - pvaClientPutGet->channelPutGetConnect(status,channelPutGet,putStructure,getStructure); - } - void putGetDone( - const epics::pvData::Status& status, - epics::pvAccess::ChannelPutGet::shared_pointer const & channelPutGet, - epics::pvData::PVStructurePtr const & getPVStructure, - epics::pvData::BitSetPtr const & getChangedBitSet) - { - pvaClientPutGet->putGetDone(status,channelPutGet,getPVStructure,getChangedBitSet); - } - void getPutDone( - const epics::pvData::Status& status, - epics::pvAccess::ChannelPutGet::shared_pointer const & channelPutGet, - epics::pvData::PVStructurePtr const & putPVStructure, - epics::pvData::BitSet::shared_pointer const & putBitSet) - { - pvaClientPutGet->getPutDone(status,channelPutGet,putPVStructure,putBitSet); - } - void getGetDone( - const epics::pvData::Status& status, - epics::pvAccess::ChannelPutGet::shared_pointer const & channelPutGet, - epics::pvData::PVStructurePtr const & getPVStructure, - epics::pvData::BitSet::shared_pointer const & getChangedBitSet) - { - pvaClientPutGet->getGetDone(status,channelPutGet,getPVStructure,getChangedBitSet); - } -}; - PvaClientPutGet::PvaClientPutGet( PvaClientPtr const &pvaClient, Channel::shared_pointer const & channel, From 3008825587a8e2e5cb2b2a9c20474c8564e1856c Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Tue, 24 May 2016 10:35:10 -0400 Subject: [PATCH 08/12] still working on RAII --- src/pv/pvaClient.h | 242 +++++++++++++--------------- src/pvaClient.cpp | 26 ++- src/pvaClientChannel.cpp | 37 ++--- src/pvaClientGet.cpp | 12 +- src/pvaClientMonitor.cpp | 121 +++++++++----- src/pvaClientMultiChannel.cpp | 12 +- src/pvaClientMultiGetDouble.cpp | 5 +- src/pvaClientMultiMonitorDouble.cpp | 5 +- src/pvaClientMultiPutDouble.cpp | 5 +- src/pvaClientNTMultiData.cpp | 5 +- src/pvaClientNTMultiGet.cpp | 5 +- src/pvaClientNTMultiMonitor.cpp | 5 +- src/pvaClientNTMultiPut.cpp | 5 +- src/pvaClientProcess.cpp | 84 +++++++--- src/pvaClientPut.cpp | 103 ++++++++---- src/pvaClientPutGet.cpp | 121 ++++++++++---- 16 files changed, 446 insertions(+), 347 deletions(-) diff --git a/src/pv/pvaClient.h b/src/pv/pvaClient.h index a78284b..9bf05a6 100644 --- a/src/pv/pvaClient.h +++ b/src/pv/pvaClient.h @@ -125,27 +125,6 @@ public: void message( std::string const & message, epics::pvData::MessageType messageType); - /** Get a cached channel or create and connect to a new channel. - * - * The provider is pva. The timeout is 5 seconds. - * @param channelName The channelName. - * @return The interface. - * @throw runtime_error if connection fails. - */ - PvaClientChannelPtr channel(std::string const & channelName) - { return channel(channelName,"pva", 5.0); } - /** Get a cached channel or create and connect to a new channel. - * - * The timeout is 5 seconds. - * @param channelName The channelName. - * @param providerName The providerName. - * @return The interface. - * @throw runtime_error if connection fails. - */ - PvaClientChannelPtr channel( - std::string const & channelName, - std::string const &providerName) - { return channel(channelName,providerName, 5.0); } /** Get a cached channel or create and connect to a new channel. * @param channelName The channelName. * @param providerName The providerName. @@ -155,8 +134,8 @@ public: */ PvaClientChannelPtr channel( std::string const & channelName, - std::string const &providerName, - double timeOut); + std::string const &providerName = "pva", + double timeOut = 5.0); /** Create an PvaClientChannel. The provider is pva. * @param channelName The channelName. * @return The interface. @@ -223,6 +202,9 @@ class PvaClientGetCache; typedef std::tr1::shared_ptr PvaClientGetCachePtr; class PvaClientPutCache; typedef std::tr1::shared_ptr PvaClientPutCachePtr; + +// NOTE: must use seprate class that implements ChannelRequester, +// because pvAccess holds a shared_ptr to ChannelRequester instead of weak_pointer class ChannelRequesterImpl; typedef std::tr1::shared_ptr ChannelRequesterImplPtr; @@ -231,9 +213,8 @@ typedef std::tr1::shared_ptr ChannelRequesterImplPtr; * * @author mrk */ -class epicsShareClass PvaClientChannel //: -// public epics::pvAccess::ChannelRequester, -// public std::tr1::enable_shared_from_this + +class epicsShareClass PvaClientChannel { public: POINTER_DEFINITIONS(PvaClientChannel); @@ -883,9 +864,11 @@ private: * * @author mrk */ -class epicsShareClass PvaClientProcess : - public epics::pvAccess::ChannelProcessRequester, - public std::tr1::enable_shared_from_this +// NOTE: must use seprate class that implements ChannelProcessRequester, +// because pvAccess holds a shared_ptr to ChannelProcessRequester instead of weak_pointer +class ChannelProcessRequesterImpl; +typedef std::tr1::shared_ptr ChannelProcessRequesterImplPtr; +class epicsShareClass PvaClientProcess { public: POINTER_DEFINITIONS(PvaClientProcess); @@ -903,14 +886,7 @@ public: /** Destructor */ ~PvaClientProcess(); - std::string getRequesterName(); - void message(std::string const & message,epics::pvData::MessageType messageType); - void channelProcessConnect( - const epics::pvData::Status& status, - epics::pvAccess::ChannelProcess::shared_pointer const & channelProcess); - void processDone( - const epics::pvData::Status& status, - epics::pvAccess::ChannelProcess::shared_pointer const & channelProcess); + /** Call issueConnect and then waitConnect. * An exception is thrown if connect fails. * @throw runtime_error if failure. @@ -940,6 +916,15 @@ public: */ void destroy() EPICS_DEPRECATED {} private: + std::string getRequesterName(); + void message(std::string const & message,epics::pvData::MessageType messageType); + void channelProcessConnect( + const epics::pvData::Status& status, + epics::pvAccess::ChannelProcess::shared_pointer const & channelProcess); + void processDone( + const epics::pvData::Status& status, + epics::pvAccess::ChannelProcess::shared_pointer const & channelProcess); + PvaClientProcess( PvaClientPtr const &pvaClient, epics::pvAccess::Channel::shared_pointer const & channel, @@ -963,6 +948,8 @@ private: enum ProcessState {processIdle,processActive,processComplete}; ProcessState processState; + ChannelProcessRequesterImplPtr channelProcessRequester; + friend class ChannelProcessRequesterImpl; }; /** @@ -970,11 +957,11 @@ private: * * @author mrk */ +// NOTE: must use seprate class that implements ChannelGetRequester, +// because pvAccess holds a shared_ptr to ChannelGetRequester instead of weak_pointer class ChannelGetRequesterImpl; typedef std::tr1::shared_ptr ChannelGetRequesterImplPtr; -class epicsShareClass PvaClientGet //: -// public epics::pvAccess::ChannelGetRequester, -// public std::tr1::enable_shared_from_this +class epicsShareClass PvaClientGet { public: POINTER_DEFINITIONS(PvaClientGet); @@ -992,17 +979,6 @@ public: /** Destructor */ ~PvaClientGet(); - std::string getRequesterName(); - void message(std::string const & message,epics::pvData::MessageType messageType); - void channelGetConnect( - const epics::pvData::Status& status, - epics::pvAccess::ChannelGet::shared_pointer const & channelGet, - epics::pvData::StructureConstPtr const & structure); - void getDone( - const epics::pvData::Status& status, - epics::pvAccess::ChannelGet::shared_pointer const & channelGet, - epics::pvData::PVStructurePtr const & pvStructure, - epics::pvData::BitSetPtr const & bitSet); /** Call issueConnect and then waitConnect. * An exception is thrown if connect fails. * @throw runtime_error if failure. @@ -1038,6 +1014,18 @@ public: */ void destroy() EPICS_DEPRECATED {} private: + std::string getRequesterName(); + void message(std::string const & message,epics::pvData::MessageType messageType); + void channelGetConnect( + const epics::pvData::Status& status, + epics::pvAccess::ChannelGet::shared_pointer const & channelGet, + epics::pvData::StructureConstPtr const & structure); + void getDone( + const epics::pvData::Status& status, + epics::pvAccess::ChannelGet::shared_pointer const & channelGet, + epics::pvData::PVStructurePtr const & pvStructure, + epics::pvData::BitSetPtr const & bitSet); + PvaClientGet( PvaClientPtr const &pvaClient, epics::pvAccess::Channel::shared_pointer const & channel, @@ -1065,6 +1053,7 @@ private: enum GetState {getIdle,getActive,getComplete}; GetState getState; ChannelGetRequesterImplPtr channelGetRequester; + friend class ChannelGetRequesterImpl; }; /** @@ -1072,9 +1061,11 @@ private: * * @author mrk */ -class epicsShareClass PvaClientPut : - public epics::pvAccess::ChannelPutRequester, - public std::tr1::enable_shared_from_this +// NOTE: must use seprate class that implements ChannelPutRequester, +// because pvAccess holds a shared_ptr to ChannelPutRequester instead of weak_pointer +class ChannelPutRequesterImpl; +typedef std::tr1::shared_ptr ChannelPutRequesterImplPtr; +class epicsShareClass PvaClientPut { public: POINTER_DEFINITIONS(PvaClientPut); @@ -1092,20 +1083,7 @@ public: /** Destructor */ ~PvaClientPut(); - std::string getRequesterName(); - void message(std::string const & message,epics::pvData::MessageType messageType); - void channelPutConnect( - const epics::pvData::Status& status, - epics::pvAccess::ChannelPut::shared_pointer const & channelPut, - epics::pvData::StructureConstPtr const & structure); - void getDone( - const epics::pvData::Status& status, - epics::pvAccess::ChannelPut::shared_pointer const & channelPut, - epics::pvData::PVStructurePtr const & pvStructure, - epics::pvData::BitSetPtr const & bitSet); - void putDone( - const epics::pvData::Status& status, - epics::pvAccess::ChannelPut::shared_pointer const & channelPut); + /** Call issueConnect and then waitConnect. * An exception is thrown if connect fails. * @throw runtime_error if failure. @@ -1152,6 +1130,20 @@ public: */ void destroy() EPICS_DEPRECATED {} private : + std::string getRequesterName(); + void message(std::string const & message,epics::pvData::MessageType messageType); + void channelPutConnect( + const epics::pvData::Status& status, + epics::pvAccess::ChannelPut::shared_pointer const & channelPut, + epics::pvData::StructureConstPtr const & structure); + void getDone( + const epics::pvData::Status& status, + epics::pvAccess::ChannelPut::shared_pointer const & channelPut, + epics::pvData::PVStructurePtr const & pvStructure, + epics::pvData::BitSetPtr const & bitSet); + void putDone( + const epics::pvData::Status& status, + epics::pvAccess::ChannelPut::shared_pointer const & channelPut); PvaClientPut( PvaClientPtr const &pvaClient, epics::pvAccess::Channel::shared_pointer const & channel, @@ -1176,6 +1168,8 @@ private : enum PutState {putIdle,getActive,putActive}; PutState putState; + ChannelPutRequesterImplPtr channelPutRequester; + friend class ChannelPutRequesterImpl; }; /** @@ -1183,9 +1177,11 @@ private : * * @author mrk */ -class epicsShareClass PvaClientPutGet : - public epics::pvAccess::ChannelPutGetRequester, - public std::tr1::enable_shared_from_this +// NOTE: must use seprate class that implements ChannelPutGetRequester, +// because pvAccess holds a shared_ptr to ChannelPutGetRequester instead of weak_pointer +class ChannelPutGetRequesterImpl; +typedef std::tr1::shared_ptr ChannelPutGetRequesterImplPtr; +class epicsShareClass PvaClientPutGet { public: POINTER_DEFINITIONS(PvaClientPutGet); @@ -1203,28 +1199,7 @@ public: /** Destructor */ ~PvaClientPutGet(); - std::string getRequesterName(); - void message(std::string const & message,epics::pvData::MessageType messageType); - void channelPutGetConnect( - const epics::pvData::Status& status, - epics::pvAccess::ChannelPutGet::shared_pointer const & channelPutGet, - epics::pvData::StructureConstPtr const & putStructure, - epics::pvData::StructureConstPtr const & getStructure); - void putGetDone( - const epics::pvData::Status& status, - epics::pvAccess::ChannelPutGet::shared_pointer const & channelPutGet, - epics::pvData::PVStructurePtr const & getPVStructure, - epics::pvData::BitSetPtr const & getBitSet); - void getPutDone( - const epics::pvData::Status& status, - epics::pvAccess::ChannelPutGet::shared_pointer const & channelPutGet, - epics::pvData::PVStructurePtr const & putPVStructure, - epics::pvData::BitSet::shared_pointer const & putBitSet); - void getGetDone( - const epics::pvData::Status& status, - epics::pvAccess::ChannelPutGet::shared_pointer const & channelPutGet, - epics::pvData::PVStructurePtr const & getPVStructure, - epics::pvData::BitSet::shared_pointer const & getBitSet); + /** Call issueConnect and then waitConnect. * An exception is thrown if connect fails. * @throw runtime_error if failure. @@ -1287,6 +1262,29 @@ public: */ void destroy() EPICS_DEPRECATED {} private : + std::string getRequesterName(); + void message(std::string const & message,epics::pvData::MessageType messageType); + void channelPutGetConnect( + const epics::pvData::Status& status, + epics::pvAccess::ChannelPutGet::shared_pointer const & channelPutGet, + epics::pvData::StructureConstPtr const & putStructure, + epics::pvData::StructureConstPtr const & getStructure); + void putGetDone( + const epics::pvData::Status& status, + epics::pvAccess::ChannelPutGet::shared_pointer const & channelPutGet, + epics::pvData::PVStructurePtr const & getPVStructure, + epics::pvData::BitSetPtr const & getBitSet); + void getPutDone( + const epics::pvData::Status& status, + epics::pvAccess::ChannelPutGet::shared_pointer const & channelPutGet, + epics::pvData::PVStructurePtr const & putPVStructure, + epics::pvData::BitSet::shared_pointer const & putBitSet); + void getGetDone( + const epics::pvData::Status& status, + epics::pvAccess::ChannelPutGet::shared_pointer const & channelPutGet, + epics::pvData::PVStructurePtr const & getPVStructure, + epics::pvData::BitSet::shared_pointer const & getBitSet); + PvaClientPutGet( PvaClientPtr const &pvaClient, epics::pvAccess::Channel::shared_pointer const & channel, @@ -1311,6 +1309,8 @@ private : enum PutGetState {putGetIdle,putGetActive,putGetComplete}; PutGetState putGetState; + ChannelPutGetRequesterImplPtr channelPutGetRequester; + friend class ChannelPutGetRequesterImpl; }; //class ChannelMonitorRequester; // private to PvaClientMonitor @@ -1333,8 +1333,11 @@ public: * @brief An easy to use alternative to Monitor. * */ +// NOTE: must use seprate class that implements MonitorRequester, +// because pvAccess holds a shared_ptr to MonitorRequester instead of weak_pointer +class MonitorRequesterImpl; +typedef std::tr1::shared_ptr MonitorRequesterImplPtr; class epicsShareClass PvaClientMonitor : - public epics::pvData::MonitorRequester, public std::tr1::enable_shared_from_this { public: @@ -1353,38 +1356,8 @@ public: /** Destructor */ ~PvaClientMonitor(); - /** epics::pvData::MonitorRequester method - * The requester must have a name. - * @return The requester's name. - */ - virtual std::string getRequesterName(); - /** epics::pvData::MonitorRequester method - * A message for the requester. - * @param message The message. - * @param messageType The type of message: - */ - virtual void message(std::string const & message,epics::pvData::MessageType messageType); - /** epics::pvData::MonitorRequester method - * @param status Completion status. - * @param monitor The monitor - * @param structure The structure defining the data. - */ - virtual void monitorConnect( - const epics::pvData::Status& status, - epics::pvData::MonitorPtr const & monitor, - epics::pvData::StructureConstPtr const & structure); - /** epics::pvData::MonitorRequester method - * The client and server have both completed the createMonitor request. - * The data source is no longer available. - * @param monitor The monitor. - */ - virtual void unlisten(epics::pvData::MonitorPtr const & monitor); - /** epics::pvData::MonitorRequester method - * A monitor event has occurred. - * The requester must call Monitor.poll to get data. - * @param monitor The monitor. - */ - virtual void monitorEvent(epics::pvData::MonitorPtr const & monitor); + + /** Call issueConnect and then waitConnect. * An exception is thrown if connect fails. */ @@ -1427,17 +1400,20 @@ public: * @return The interface. */ PvaClientMonitorDataPtr getData(); - /** Get shared pointer to this - */ - PvaClientMonitorPtr getPtrSelf() - { - return shared_from_this(); - } /** Deprecated method * \deprecated This method will go away in future versions. */ void destroy() EPICS_DEPRECATED {} private: + virtual std::string getRequesterName(); + virtual void message(std::string const & message,epics::pvData::MessageType messageType); + virtual void monitorConnect( + const epics::pvData::Status& status, + epics::pvData::MonitorPtr const & monitor, + epics::pvData::StructureConstPtr const & structure); + virtual void unlisten(epics::pvData::MonitorPtr const & monitor); + virtual void monitorEvent(epics::pvData::MonitorPtr const & monitor); + PvaClientMonitor( PvaClientPtr const &pvaClient, epics::pvAccess::Channel::shared_pointer const & channel, @@ -1463,6 +1439,8 @@ private: MonitorConnectState connectState; bool userPoll; bool userWait; + MonitorRequesterImplPtr monitorRequester; + friend class MonitorRequesterImpl; }; }} diff --git a/src/pvaClient.cpp b/src/pvaClient.cpp index e52747c..4567070 100644 --- a/src/pvaClient.cpp +++ b/src/pvaClient.cpp @@ -26,11 +26,6 @@ using namespace std; namespace epics { namespace pvaClient { -static FieldCreatePtr fieldCreate = getFieldCreate(); -static const string pvaClientName = "pvaClient"; -static const string defaultProvider = "pva"; -static UnionConstPtr variantUnion = fieldCreate->createVariantUnion(); - class PvaClientChannelCache { @@ -43,7 +38,6 @@ public: string const & channelName, string const & providerName); void addChannel(PvaClientChannelPtr const & pvaClientChannel); - void removeChannel(string const & channelName,string const & providerName); void showCache(); size_t cacheSize(); private: @@ -83,7 +77,6 @@ void PvaClientChannelCache::showCache() string channelName = channel->getChannelName(); string providerName = channel->getProvider()->getProviderName(); cout << "channel " << channelName << " provider " << providerName << endl; - cout << " get and put cacheSize " << pvaChannel->cacheSize() << endl; pvaChannel->showCache(); } @@ -138,14 +131,13 @@ PvaClient::~PvaClient() { if(PvaClient::debug) cout<< "PvaClient::~PvaClient()\n"; { Lock xx(mutex); - if(isDestroyed) { - cerr<< "Why was PvaClient::~PvaClient() called more then once????\n"; - return; - } + if(isDestroyed) throw std::runtime_error("pvaClient was destroyed"); isDestroyed = true; } - if(PvaClient::debug) showCache(); - pvaClientChannelCache.reset(); + if(PvaClient::debug) { + cout << "pvaChannel cache:\n"; + showCache(); + } if(pvaStarted){ if(PvaClient::debug) cout<< "calling ClientFactory::stop()\n"; ClientFactory::stop(); @@ -206,12 +198,16 @@ void PvaClient::setRequester(RequesterPtr const & requester) void PvaClient::clearRequester() { - requester = Requester::weak_pointer(); + requester.reset(); } void PvaClient::showCache() { - pvaClientChannelCache->showCache(); + if(pvaClientChannelCache->cacheSize()>=1) { + pvaClientChannelCache->showCache(); + } else { + cout << "pvaClientChannelCache is empty\n"; + } } diff --git a/src/pvaClientChannel.cpp b/src/pvaClientChannel.cpp index 22ce712..542e29e 100644 --- a/src/pvaClientChannel.cpp +++ b/src/pvaClientChannel.cpp @@ -32,7 +32,7 @@ public: PvaClientGetCache(){} ~PvaClientGetCache() { - pvaClientGetMap.clear(); + if(PvaClient::getDebug()) cout << "PvaClientGetCache::~PvaClientGetCache\n"; } PvaClientGetPtr getGet(string const & request); void addGet(string const & request,PvaClientGetPtr const & pvaClientGet); @@ -79,7 +79,7 @@ public: PvaClientPutCache(){} ~PvaClientPutCache() { - pvaClientPutMap.clear(); + if(PvaClient::getDebug()) cout << "PvaClientPutCache::~PvaClientPutCache\n"; } PvaClientPutPtr getPut(string const & request); void addPut(string const & request,PvaClientPutPtr const & pvaClientPut); @@ -208,7 +208,7 @@ PvaClientChannel::~PvaClientChannel() } { Lock xx(mutex); - if(isDestroyed) return; + if(isDestroyed) throw std::runtime_error("pvaClientChannel was destroyed"); isDestroyed = true; } if(PvaClient::getDebug()) showCache(); @@ -227,7 +227,6 @@ void PvaClientChannel::channelCreated(const Status& status, Channel::shared_poin << endl; } Lock xx(mutex); - if(isDestroyed) throw std::runtime_error("pvaClientChannel was destroyed"); if(connectState!=connectActive) { string message("PvaClientChannel::channelCreated"); message += " channel " + channelName @@ -256,7 +255,6 @@ void PvaClientChannel::channelStateChange( << endl; } Lock xx(mutex); - if(isDestroyed) return; bool waitingForConnect = false; if(connectState==connectActive) waitingForConnect = true; if(connectionState!=Channel::CONNECTED) { @@ -289,22 +287,16 @@ void PvaClientChannel::message( string PvaClientChannel::getChannelName() { - if(isDestroyed) throw std::runtime_error( - "PvaClientChannel::getChannelName() pvaClientChannel was destroyed"); return channelName; } Channel::shared_pointer PvaClientChannel::getChannel() { - if(isDestroyed) throw std::runtime_error( - "PvaClientChannel::getChannel() pvaClientChannel was destroyed"); return channel; } void PvaClientChannel::connect(double timeout) { - if(isDestroyed) throw std::runtime_error( - "PvaClientChannel::connect() pvaClientChannel was destroyed"); if(PvaClient::getDebug()) { cout << "PvaClientChannel::connect" << " channelName " << channelName << endl; @@ -320,15 +312,12 @@ void PvaClientChannel::connect(double timeout) void PvaClientChannel::issueConnect() { - if(isDestroyed) throw std::runtime_error( - "PvaClientChannel::issueConnect() pvaClientChannel was destroyed"); if(PvaClient::getDebug()) { cout << "PvaClientChannel::issueConnect" << " channelName " << channelName << endl; } { Lock xx(mutex); - if(isDestroyed) throw std::runtime_error("pvaClientChannel was destroyed"); if(connectState!=connectIdle) { throw std::runtime_error("pvaClientChannel already connected"); } @@ -339,7 +328,6 @@ void PvaClientChannel::issueConnect() if(!provider) { throw std::runtime_error(channelName + " provider " + providerName + " not registered"); } -// ChannelRequester::shared_pointer channelRequester(shared_from_this()); if(PvaClient::getDebug()) cout << "PvaClientChannel::issueConnect calling provider->createChannel\n"; channel = provider->createChannel(channelName,channelRequester,ChannelProvider::PRIORITY_DEFAULT); if(!channel) { @@ -349,15 +337,12 @@ void PvaClientChannel::issueConnect() Status PvaClientChannel::waitConnect(double timeout) { - if(isDestroyed) throw std::runtime_error( - "PvaClientChannel::waitConnect() pvaClientChannel was destroyed"); if(PvaClient::getDebug()) { cout << "PvaClientChannel::waitConnect" << " channelName " << channelName << endl; } { Lock xx(mutex); - if(isDestroyed) throw std::runtime_error("pvaClientChannel was destroyed"); if(channel->isConnected()) return Status::Ok; } if(timeout>0.0) { @@ -585,10 +570,18 @@ PvaClientMonitorPtr PvaClientChannel::createMonitor(PVStructurePtr const & pvR void PvaClientChannel::showCache() { - cout << " pvaClientGet" << endl; - pvaClientGetCache->showCache(); - cout << " pvaClientPut" << endl; - pvaClientPutCache->showCache(); + if(pvaClientGetCache->cacheSize()>=1) { + cout << " pvaClientGet cache" << endl; + pvaClientGetCache->showCache(); + } else { + cout << " pvaClientGet cache is empty\n"; + } + if(pvaClientPutCache->cacheSize()>=1) { + cout << " pvaClientPut cache" << endl; + pvaClientPutCache->showCache(); + } else { + cout << " pvaClientPut cache is empty\n"; + } } size_t PvaClientChannel::cacheSize() diff --git a/src/pvaClientGet.cpp b/src/pvaClientGet.cpp index 5e5e6f0..5ed4438 100644 --- a/src/pvaClientGet.cpp +++ b/src/pvaClientGet.cpp @@ -102,14 +102,13 @@ PvaClientGet::~PvaClientGet() if(PvaClient::getDebug()) cout<< "PvaClientGet::~PvaClientGet()\n"; { Lock xx(mutex); - if(isDestroyed) return; + if(isDestroyed) throw std::runtime_error("pvaClientGet was destroyed"); isDestroyed = true; } } void PvaClientGet::checkGetState() { - if(isDestroyed) throw std::runtime_error("pvaClientGet was destroyed"); if(connectState==connectIdle) connect(); if(getState==getIdle) get(); } @@ -139,7 +138,6 @@ void PvaClientGet::channelGetConnect( << " status.isOK " << (status.isOK() ? "true" : "false") << endl; } - if(isDestroyed) throw std::runtime_error("pvaClientGet was destroyed"); { Lock xx(mutex); channelGetConnectStatus = status; @@ -166,7 +164,6 @@ void PvaClientGet::getDone( << " status.isOK " << (status.isOK() ? "true" : "false") << endl; } - if(isDestroyed) throw std::runtime_error("pvaClientGet was destroyed"); { Lock xx(mutex); channelGetStatus = status; @@ -180,7 +177,6 @@ void PvaClientGet::getDone( void PvaClientGet::connect() { - if(isDestroyed) throw std::runtime_error("pvaClientGet was destroyed"); issueConnect(); Status status = waitConnect(); if(status.isOK()) return; @@ -194,7 +190,6 @@ void PvaClientGet::connect() void PvaClientGet::issueConnect() { - if(isDestroyed) throw std::runtime_error("pvaClientGet was destroyed"); if(connectState!=connectIdle) { Channel::shared_pointer chan(channel.lock()); string channelName("disconnected"); @@ -203,7 +198,6 @@ void PvaClientGet::issueConnect() + " pvaClientGet already connected "; throw std::runtime_error(message); } -// ChannelGetRequester::shared_pointer channelGetRequester(shared_from_this()); connectState = connectActive; Channel::shared_pointer chan(channel.lock()); if(chan) { @@ -215,7 +209,6 @@ void PvaClientGet::issueConnect() Status PvaClientGet::waitConnect() { - if(isDestroyed) throw std::runtime_error("pvaClientGet was destroyed"); { Lock xx(mutex); if(connectState==connected) { @@ -238,7 +231,6 @@ Status PvaClientGet::waitConnect() void PvaClientGet::get() { - if(isDestroyed) throw std::runtime_error("pvaClientGet was destroyed"); issueGet(); Status status = waitGet(); if(status.isOK()) return; @@ -252,7 +244,6 @@ void PvaClientGet::get() void PvaClientGet::issueGet() { - if(isDestroyed) throw std::runtime_error("pvaClientGet was destroyed"); if(connectState==connectIdle) connect(); if(getState!=getIdle) { Channel::shared_pointer chan(channel.lock()); @@ -268,7 +259,6 @@ void PvaClientGet::issueGet() Status PvaClientGet::waitGet() { - if(isDestroyed) throw std::runtime_error("pvaClientGet was destroyed"); { Lock xx(mutex); if(getState==getComplete) { diff --git a/src/pvaClientMonitor.cpp b/src/pvaClientMonitor.cpp index 29d0ed1..34e716d 100644 --- a/src/pvaClientMonitor.cpp +++ b/src/pvaClientMonitor.cpp @@ -25,6 +25,70 @@ using namespace std; namespace epics { namespace pvaClient { +class MonitorRequesterImpl : public MonitorRequester +{ + PvaClientMonitor::weak_pointer pvaClientMonitor; + PvaClient::weak_pointer pvaClient; +public: + MonitorRequesterImpl( + PvaClientMonitorPtr const & pvaClientMonitor, + PvaClientPtr const &pvaClient) + : pvaClientMonitor(pvaClientMonitor), + pvaClient(pvaClient) + {} + virtual ~MonitorRequesterImpl() { + if(PvaClient::getDebug()) std::cout << "~MonitorRequesterImpl" << std::endl; + } + + virtual std::string getRequesterName() { + PvaClientMonitorPtr clientMonitor(pvaClientMonitor.lock()); + if(!clientMonitor) return string("pvaClientMonitor is null"); + return clientMonitor->getRequesterName(); + } + + virtual void message(std::string const & message, epics::pvData::MessageType messageType) { + PvaClientMonitorPtr clientMonitor(pvaClientMonitor.lock()); + if(!clientMonitor) return; + clientMonitor->message(message,messageType); + } + + virtual void monitorConnect( + const Status& status, + Monitor::shared_pointer const & monitor, + Structure::const_shared_pointer const & structure) + { + PvaClientMonitorPtr clientMonitor(pvaClientMonitor.lock()); + if(!clientMonitor) return; + clientMonitor->monitorConnect(status,monitor,structure); + } + + virtual void unlisten(epics::pvData::MonitorPtr const & monitor) + { + PvaClientMonitorPtr clientMonitor(pvaClientMonitor.lock()); + if(!clientMonitor) return; + clientMonitor->unlisten(monitor); + } + + virtual void monitorEvent(epics::pvData::MonitorPtr const & monitor) + { + PvaClientMonitorPtr clientMonitor(pvaClientMonitor.lock()); + if(!clientMonitor) return; + clientMonitor->monitorEvent(monitor); + } +}; + + +PvaClientMonitorPtr PvaClientMonitor::create( + PvaClientPtr const &pvaClient, + Channel::shared_pointer const & channel, + PVStructurePtr const &pvRequest) +{ + PvaClientMonitorPtr epv(new PvaClientMonitor(pvaClient,channel,pvRequest)); + epv->monitorRequester = MonitorRequesterImplPtr( + new MonitorRequesterImpl(epv,pvaClient)); + return epv; +} + PvaClientMonitor::PvaClientMonitor( PvaClientPtr const &pvaClient, Channel::shared_pointer const & channel, @@ -45,27 +109,22 @@ PvaClientMonitor::~PvaClientMonitor() if(PvaClient::getDebug()) cout<< "PvaClientMonitor::~PvaClientMonitor()\n"; { Lock xx(mutex); - if(isDestroyed) { - cerr<< "Why was PvaClientMonitor::~PvaClientMonitor() called more then once????\n"; - return; - } + if(isDestroyed) throw std::runtime_error("pvaClientMonitor was destroyed"); isDestroyed = true; } if(monitor) monitor->destroy(); - monitor.reset(); - monitorElement.reset(); } void PvaClientMonitor::checkMonitorState() { - if(isDestroyed) throw std::runtime_error("pvaClientMonitor was destroyed"); + if(PvaClient::getDebug()) cout<< "PvaClientMonitor::checkMonitorState()\n"; if(connectState==connectIdle) connect(); if(connectState==connected) start(); } -// from MonitorRequester string PvaClientMonitor::getRequesterName() { + if(PvaClient::getDebug()) cout<< "PvaClientMonitor::getRequesterName()\n"; PvaClientPtr yyy = pvaClient.lock(); if(!yyy) throw std::runtime_error("pvaClient was destroyed"); return yyy->getRequesterName(); @@ -73,7 +132,7 @@ string PvaClientMonitor::getRequesterName() void PvaClientMonitor::message(string const & message,MessageType messageType) { - if(isDestroyed) throw std::runtime_error("pvaClientMonitor was destroyed"); + if(PvaClient::getDebug()) cout<< "PvaClientMonitor::message()\n"; PvaClientPtr yyy = pvaClient.lock(); if(!yyy) throw std::runtime_error("pvaClient was destroyed"); yyy->message(message, messageType); @@ -84,7 +143,7 @@ void PvaClientMonitor::monitorConnect( Monitor::shared_pointer const & monitor, StructureConstPtr const & structure) { - if(isDestroyed) throw std::runtime_error("pvaClientMonitor was destroyed"); + if(PvaClient::getDebug()) cout<< "PvaClientMonitor::monitorConnect()\n"; connectStatus = status; connectState = connected; this->monitor = monitor; @@ -98,29 +157,21 @@ void PvaClientMonitor::monitorConnect( void PvaClientMonitor::monitorEvent(MonitorPtr const & monitor) { - if(isDestroyed) throw std::runtime_error("pvaClientMonitor was destroyed"); + if(PvaClient::getDebug()) cout<< "PvaClientMonitor::monitorEvent()\n"; PvaClientMonitorRequesterPtr req = pvaClientMonitorRequester.lock(); - if(req) req->event(getPtrSelf()); + if(req) req->event(shared_from_this()); if(userWait) waitForEvent.signal(); } void PvaClientMonitor::unlisten(MonitorPtr const & monitor) { if(PvaClient::getDebug()) cout << "PvaClientMonitor::unlisten\n"; - { - Lock xx(mutex); - if(isDestroyed) { - cerr<< "Why was PvaClientMonitor::unlisten called when PvaClientMonitor was destroyed?\n"; - return; - } - } - this->monitor.reset(); - this->monitorElement.reset(); + throw std::runtime_error("pvaClientMonitor::unlisten called but do not know what to do"); } void PvaClientMonitor::connect() { - if(isDestroyed) throw std::runtime_error("pvaClientMonitor was destroyed"); + if(PvaClient::getDebug()) cout << "PvaClientMonitor::connect\n"; issueConnect(); Status status = waitConnect(); if(status.isOK()) return; @@ -131,22 +182,19 @@ void PvaClientMonitor::connect() void PvaClientMonitor::issueConnect() { - if(isDestroyed) throw std::runtime_error("pvaClientMonitor was destroyed"); + if(PvaClient::getDebug()) cout << "PvaClientMonitor::issueConnect\n"; if(connectState!=connectIdle) { string message = string("channel ") + channel->getChannelName() + " pvaClientMonitor already connected "; throw std::runtime_error(message); } - MonitorRequester::shared_pointer monitorRequester = - dynamic_pointer_cast(getPtrSelf()); - //monitorRequester = ChannelMonitorRequester::shared_pointer(new ChannelMonitorRequester(this)); connectState = connectActive; monitor = channel->createMonitor(monitorRequester,pvRequest); } Status PvaClientMonitor::waitConnect() { - if(isDestroyed) throw std::runtime_error("pvaClientMonitor was destroyed"); + if(PvaClient::getDebug()) cout << "PvaClientMonitor::waitConnect\n"; if(connectState==connected) { if(connectStatus.isOK()) connectState = connectIdle; return connectStatus; @@ -163,12 +211,13 @@ Status PvaClientMonitor::waitConnect() void PvaClientMonitor::setRequester(PvaClientMonitorRequesterPtr const & pvaClientMonitorrRequester) { + if(PvaClient::getDebug()) cout << "PvaClientMonitor::setRequester\n"; this->pvaClientMonitorRequester = pvaClientMonitorrRequester; } void PvaClientMonitor::start() { - if(isDestroyed) throw std::runtime_error("pvaClientMonitor was destroyed"); + if(PvaClient::getDebug()) cout << "PvaClientMonitor::start\n"; if(connectState==monitorStarted) return; if(connectState==connectIdle) connect(); if(connectState!=connected) throw std::runtime_error("PvaClientMonitor::start illegal state"); @@ -179,7 +228,7 @@ void PvaClientMonitor::start() void PvaClientMonitor::stop() { - if(isDestroyed) throw std::runtime_error("pvaClientMonitor was destroyed"); + if(PvaClient::getDebug()) cout << "PvaClientMonitor::stop\n"; if(connectState!=monitorStarted) return; connectState = connected; monitor->stop(); @@ -187,6 +236,7 @@ void PvaClientMonitor::stop() bool PvaClientMonitor::poll() { + if(PvaClient::getDebug()) cout << "PvaClientMonitor::poll\n"; checkMonitorState(); if(connectState!=monitorStarted) throw std::runtime_error("PvaClientMonitor::poll illegal state"); if(userPoll) throw std::runtime_error("PvaClientMonitor::poll did not release last"); @@ -199,7 +249,7 @@ bool PvaClientMonitor::poll() bool PvaClientMonitor::waitEvent(double secondsToWait) { - if(isDestroyed) throw std::runtime_error("pvaClientMonitor was destroyed"); + if(PvaClient::getDebug()) cout << "PvaClientMonitor::waitEvent\n"; if(connectState!=monitorStarted) throw std::runtime_error("PvaClientMonitor::waitEvent illegal state"); if(poll()) return true; userWait = true; @@ -214,7 +264,7 @@ bool PvaClientMonitor::waitEvent(double secondsToWait) void PvaClientMonitor::releaseEvent() { - if(isDestroyed) throw std::runtime_error("pvaClientMonitor was destroyed"); + if(PvaClient::getDebug()) cout << "PvaClientMonitor::releaseEvent\n"; if(connectState!=monitorStarted) throw std::runtime_error( "PvaClientMonitor::poll illegal state"); if(!userPoll) throw std::runtime_error("PvaClientMonitor::releaseEvent did not call poll"); @@ -224,17 +274,10 @@ void PvaClientMonitor::releaseEvent() PvaClientMonitorDataPtr PvaClientMonitor::getData() { + if(PvaClient::getDebug()) cout << "PvaClientMonitor::getData\n"; checkMonitorState(); return pvaClientData; } -PvaClientMonitorPtr PvaClientMonitor::create( - PvaClientPtr const &pvaClient, - Channel::shared_pointer const & channel, - PVStructurePtr const &pvRequest) -{ - PvaClientMonitorPtr epv(new PvaClientMonitor(pvaClient,channel,pvRequest)); - return epv; -} }} diff --git a/src/pvaClientMultiChannel.cpp b/src/pvaClientMultiChannel.cpp index a9589a9..fda7035 100644 --- a/src/pvaClientMultiChannel.cpp +++ b/src/pvaClientMultiChannel.cpp @@ -64,10 +64,7 @@ PvaClientMultiChannel::~PvaClientMultiChannel() if(PvaClient::getDebug()) cout<< "PvaClientMultiChannel::~PvaClientMultiChannel()\n"; { Lock xx(mutex); - if(isDestroyed) { - cerr<< "Why was PvaClientMultiChannel::~PvaClientMultiChannel() called more then once????\n"; - return; - } + if(isDestroyed) throw std::runtime_error("pvaClientMultiChannel was destroyed"); isDestroyed = true; } pvaClientChannelArray.clear(); @@ -80,13 +77,11 @@ void PvaClientMultiChannel::checkConnected() epics::pvData::shared_vector PvaClientMultiChannel::getChannelNames() { - if(isDestroyed) throw std::runtime_error("pvaClientMultiChannel was destroyed"); return channelName; } Status PvaClientMultiChannel::connect(double timeout) { - if(isDestroyed) throw std::runtime_error("pvaClientMultiChannel was destroyed"); for(size_t i=0; i< numChannel; ++i) { pvaClientChannelArray[i] = pvaClient->createChannel(channelName[i],providerName); pvaClientChannelArray[i]->issueConnect(); @@ -115,13 +110,11 @@ Status PvaClientMultiChannel::connect(double timeout) bool PvaClientMultiChannel::allConnected() { - if(isDestroyed) throw std::runtime_error("pvaClientMultiChannel was destroyed"); return (numConnected==numChannel) ? true : false; } bool PvaClientMultiChannel::connectionChange() { - if(isDestroyed) throw std::runtime_error("pvaClientMultiChannel was destroyed"); for(size_t i=0; igetChannel(); @@ -134,7 +127,6 @@ bool PvaClientMultiChannel::connectionChange() epics::pvData::shared_vector PvaClientMultiChannel::getIsConnected() { - if(isDestroyed) throw std::runtime_error("pvaClientMultiChannel was destroyed"); for(size_t i=0; i PvaClientMultiChannel::get PvaClientChannelArray PvaClientMultiChannel::getPvaClientChannelArray() { - if(isDestroyed) throw std::runtime_error("pvaClientMultiChannel was destroyed"); return pvaClientChannelArray; } PvaClientPtr PvaClientMultiChannel::getPvaClient() { - if(isDestroyed) throw std::runtime_error("pvaClientMultiChannel was destroyed"); return pvaClient; } diff --git a/src/pvaClientMultiGetDouble.cpp b/src/pvaClientMultiGetDouble.cpp index 05b3aef..61dfb8d 100644 --- a/src/pvaClientMultiGetDouble.cpp +++ b/src/pvaClientMultiGetDouble.cpp @@ -59,10 +59,7 @@ PvaClientMultiGetDouble::~PvaClientMultiGetDouble() if(PvaClient::getDebug()) cout<< "PvaClientMultiGetDouble::~PvaClientMultiGetDouble()\n"; { Lock xx(mutex); - if(isDestroyed) { - cerr<< "Why was PvaClientMultiGetDouble::~PvaClientMultiGetDouble() called more then once????\n"; - return; - } + if(isDestroyed) throw std::runtime_error("pvaClientMultiGetDouble was destroyed"); isDestroyed = true; } pvaClientChannelArray.clear(); diff --git a/src/pvaClientMultiMonitorDouble.cpp b/src/pvaClientMultiMonitorDouble.cpp index 813a2b9..79be101 100644 --- a/src/pvaClientMultiMonitorDouble.cpp +++ b/src/pvaClientMultiMonitorDouble.cpp @@ -60,10 +60,7 @@ PvaClientMultiMonitorDouble::~PvaClientMultiMonitorDouble() if(PvaClient::getDebug()) cout<< "PvaClientMultiMonitorDouble::~PvaClientMultiMonitorDouble()\n"; { Lock xx(mutex); - if(isDestroyed) { - cerr<< "Why was PvaClientMultiMonitorDouble::~PvaClientMultiMonitorDouble() called more then once????\n"; - return; - } + if(isDestroyed) throw std::runtime_error("pvaClientMultiMonitorDouble was destroyed"); isDestroyed = true; } pvaClientChannelArray.clear(); diff --git a/src/pvaClientMultiPutDouble.cpp b/src/pvaClientMultiPutDouble.cpp index 1c52c7a..03ca318 100644 --- a/src/pvaClientMultiPutDouble.cpp +++ b/src/pvaClientMultiPutDouble.cpp @@ -61,10 +61,7 @@ PvaClientMultiPutDouble::~PvaClientMultiPutDouble() if(PvaClient::getDebug()) cout<< "PvaClientMultiPutDouble::~PvaClientMultiPutDouble()\n"; { Lock xx(mutex); - if(isDestroyed) { - cerr<< "Why was PvaClientMultiPutDouble::~PvaClientMultiPutDouble() called more then once????\n"; - return; - } + if(isDestroyed) throw std::runtime_error("pvaClientMultiPutDouble was destroyed"); isDestroyed = true; } pvaClientChannelArray.clear(); diff --git a/src/pvaClientNTMultiData.cpp b/src/pvaClientNTMultiData.cpp index c67d382..9b3bb53 100644 --- a/src/pvaClientNTMultiData.cpp +++ b/src/pvaClientNTMultiData.cpp @@ -92,10 +92,7 @@ PvaClientNTMultiData::~PvaClientNTMultiData() if(PvaClient::getDebug()) cout<< "PvaClientNTMultiData::~PvaClientNTMultiData()\n"; { Lock xx(mutex); - if(isDestroyed) { - cerr<< "Why was PvaClientNTMultiData::~PvaClientNTMultiData() called more then once????\n"; - return; - } + if(isDestroyed) throw std::runtime_error("pvaClientNTMultiData was destroyed"); isDestroyed = true; } pvaClientChannelArray.clear(); diff --git a/src/pvaClientNTMultiGet.cpp b/src/pvaClientNTMultiGet.cpp index 8da1248..b976310 100644 --- a/src/pvaClientNTMultiGet.cpp +++ b/src/pvaClientNTMultiGet.cpp @@ -68,10 +68,7 @@ PvaClientNTMultiGet::~PvaClientNTMultiGet() if(PvaClient::getDebug()) cout<< "PvaClientNTMultiGet::~PvaClientNTMultiGet()\n"; { Lock xx(mutex); - if(isDestroyed) { - cerr<< "Why was PvaClientNTMultiGet::~PvaClientNTMultiGet() called more then once????\n"; - return; - } + if(isDestroyed) throw std::runtime_error("pvaClientNTMultiGet was destroyed"); isDestroyed = true; } pvaClientChannelArray.clear(); diff --git a/src/pvaClientNTMultiMonitor.cpp b/src/pvaClientNTMultiMonitor.cpp index efcbec0..c42e9ca 100644 --- a/src/pvaClientNTMultiMonitor.cpp +++ b/src/pvaClientNTMultiMonitor.cpp @@ -66,10 +66,7 @@ PvaClientNTMultiMonitor::~PvaClientNTMultiMonitor() if(PvaClient::getDebug()) cout<< "PvaClientNTMultiMonitor::~PvaClientNTMultiMonitor()\n"; { Lock xx(mutex); - if(isDestroyed) { - cerr<< "Why was PvaClientNTMultiMonitor::~PvaClientNTMultiMonitor() called more then once????\n"; - return; - } + if(isDestroyed) throw std::runtime_error("pvaClientNTMultiMonitor was destroyed"); isDestroyed = true; } pvaClientChannelArray.clear(); diff --git a/src/pvaClientNTMultiPut.cpp b/src/pvaClientNTMultiPut.cpp index 7317e45..f5b7cc0 100644 --- a/src/pvaClientNTMultiPut.cpp +++ b/src/pvaClientNTMultiPut.cpp @@ -57,10 +57,7 @@ PvaClientNTMultiPut::~PvaClientNTMultiPut() if(PvaClient::getDebug()) cout<< "PvaClientNTMultiPut::~PvaClientNTMultiPut()\n"; { Lock xx(mutex); - if(isDestroyed) { - cerr<< "Why was PvaClientNTMultiPut::~PvaClientNTMultiPut() called more then once????\n"; - return; - } + if(isDestroyed) throw std::runtime_error("pvaClientNTMultiPut was destroyed"); isDestroyed = true; } pvaClientChannelArray.clear(); diff --git a/src/pvaClientProcess.cpp b/src/pvaClientProcess.cpp index bbe7195..0ef0702 100644 --- a/src/pvaClientProcess.cpp +++ b/src/pvaClientProcess.cpp @@ -22,6 +22,64 @@ using namespace std; namespace epics { namespace pvaClient { +class ChannelProcessRequesterImpl : public ChannelProcessRequester +{ + PvaClientProcess::weak_pointer pvaClientProcess; + PvaClient::weak_pointer pvaClient; +public: + ChannelProcessRequesterImpl( + PvaClientProcessPtr const & pvaClientProcess, + PvaClientPtr const &pvaClient) + : pvaClientProcess(pvaClientProcess), + pvaClient(pvaClient) + {} + virtual ~ChannelProcessRequesterImpl() { + if(PvaClient::getDebug()) std::cout << "~ChannelProcessRequesterImpl" << std::endl; + } + + virtual std::string getRequesterName() { + PvaClientProcessPtr clientProcess(pvaClientProcess.lock()); + if(!clientProcess) return string("clientProcess is null"); + return clientProcess->getRequesterName(); + } + + virtual void message(std::string const & message, epics::pvData::MessageType messageType) { + PvaClientProcessPtr clientProcess(pvaClientProcess.lock()); + if(!clientProcess) return; + clientProcess->message(message,messageType); + } + + virtual void channelProcessConnect( + const Status& status, + ChannelProcess::shared_pointer const & channelProcess) + { + PvaClientProcessPtr clientProcess(pvaClientProcess.lock()); + if(!clientProcess) return; + clientProcess->channelProcessConnect(status,channelProcess); + } + + virtual void processDone( + const Status& status, + ChannelProcess::shared_pointer const & ChannelProcess) + { + PvaClientProcessPtr clientProcess(pvaClientProcess.lock()); + if(!clientProcess) return; + clientProcess->processDone(status,ChannelProcess); + } +}; + +PvaClientProcessPtr PvaClientProcess::create( + PvaClientPtr const &pvaClient, + Channel::shared_pointer const & channel, + PVStructurePtr const &pvRequest) +{ + PvaClientProcessPtr epv(new PvaClientProcess(pvaClient,channel,pvRequest)); + epv->channelProcessRequester = ChannelProcessRequesterImplPtr( + new ChannelProcessRequesterImpl(epv,pvaClient)); + return epv; +} + + PvaClientProcess::PvaClientProcess( PvaClientPtr const &pvaClient, Channel::shared_pointer const & channel, @@ -41,10 +99,7 @@ PvaClientProcess::~PvaClientProcess() if(PvaClient::getDebug()) cout<< "PvaClientProcess::~PvaClientProcess()\n"; { Lock xx(mutex); - if(isDestroyed) { - cerr<< "Why was PvaClientProcess::~PvaClientProcess() called more then once????\n"; - return; - } + if(isDestroyed) throw std::runtime_error("pvaClientProcess was destroyed"); isDestroyed = true; } channelProcess->destroy(); @@ -60,7 +115,6 @@ string PvaClientProcess::getRequesterName() void PvaClientProcess::message(string const & message,MessageType messageType) { - if(isDestroyed) throw std::runtime_error("pvaClientProcess was destroyed"); PvaClientPtr yyy = pvaClient.lock(); if(!yyy) throw std::runtime_error("pvaClient was destroyed"); yyy->message(message, messageType); @@ -70,7 +124,6 @@ void PvaClientProcess::channelProcessConnect( const Status& status, ChannelProcess::shared_pointer const & channelProcess) { - if(isDestroyed) return; channelProcessConnectStatus = status; this->channelProcess = channelProcess; waitForConnect.signal(); @@ -81,14 +134,12 @@ void PvaClientProcess::processDone( const Status& status, ChannelProcess::shared_pointer const & channelProcess) { - if(isDestroyed) return; channelProcessStatus = status; waitForProcess.signal(); } void PvaClientProcess::connect() { - if(isDestroyed) throw std::runtime_error("pvaClientProcess was destroyed"); issueConnect(); Status status = waitConnect(); if(status.isOK()) return; @@ -99,20 +150,17 @@ void PvaClientProcess::connect() void PvaClientProcess::issueConnect() { - if(isDestroyed) throw std::runtime_error("pvaClientProcess was destroyed"); if(connectState!=connectIdle) { string message = string("channel ") + channel->getChannelName() + " pvaClientProcess already connected "; throw std::runtime_error(message); } - ChannelProcessRequester::shared_pointer processRequester(shared_from_this()); connectState = connectActive; - channelProcess = channel->createChannelProcess(processRequester,pvRequest); + channelProcess = channel->createChannelProcess(channelProcessRequester,pvRequest); } Status PvaClientProcess::waitConnect() { - if(isDestroyed) throw std::runtime_error("pvaClientProcess was destroyed"); if(connectState!=connectActive) { string message = string("channel ") + channel->getChannelName() + " pvaClientProcess illegal connect state "; @@ -125,7 +173,6 @@ Status PvaClientProcess::waitConnect() void PvaClientProcess::process() { - if(isDestroyed) throw std::runtime_error("pvaClientProcess was destroyed"); issueProcess(); Status status = waitProcess(); if(status.isOK()) return; @@ -136,7 +183,6 @@ void PvaClientProcess::process() void PvaClientProcess::issueProcess() { - if(isDestroyed) throw std::runtime_error("pvaClientProcess was destroyed"); if(connectState==connectIdle) connect(); if(processState!=processIdle) { string message = string("channel ") + channel->getChannelName() @@ -149,7 +195,6 @@ void PvaClientProcess::issueProcess() Status PvaClientProcess::waitProcess() { - if(isDestroyed) throw std::runtime_error("pvaClientProcess was destroyed"); if(processState!=processActive){ string message = string("channel ") + channel->getChannelName() + " PvaClientProcess::waitProcess llegal process state"; @@ -160,13 +205,4 @@ Status PvaClientProcess::waitProcess() return channelProcessStatus; } -PvaClientProcessPtr PvaClientProcess::create( - PvaClientPtr const &pvaClient, - Channel::shared_pointer const & channel, - PVStructurePtr const &pvRequest) -{ - PvaClientProcessPtr epv(new PvaClientProcess(pvaClient,channel,pvRequest)); - return epv; -} - }} diff --git a/src/pvaClientPut.cpp b/src/pvaClientPut.cpp index 7cec325..5ec9d2e 100644 --- a/src/pvaClientPut.cpp +++ b/src/pvaClientPut.cpp @@ -22,6 +22,77 @@ using namespace std; namespace epics { namespace pvaClient { +class ChannelPutRequesterImpl : public ChannelPutRequester +{ + PvaClientPut::weak_pointer pvaClientPut; + PvaClient::weak_pointer pvaClient; +public: + ChannelPutRequesterImpl( + PvaClientPutPtr const & pvaClientPut, + PvaClientPtr const &pvaClient) + : pvaClientPut(pvaClientPut), + pvaClient(pvaClient) + {} + virtual ~ChannelPutRequesterImpl() { + if(PvaClient::getDebug()) std::cout << "~ChannelPutRequesterImpl" << std::endl; + } + + virtual std::string getRequesterName() { + PvaClientPutPtr clientPut(pvaClientPut.lock()); + if(!clientPut) return string("clientPut is null"); + return clientPut->getRequesterName(); + } + + virtual void message(std::string const & message, epics::pvData::MessageType messageType) { + PvaClientPutPtr clientPut(pvaClientPut.lock()); + if(!clientPut) return; + clientPut->message(message,messageType); + } + + virtual void channelPutConnect( + const Status& status, + ChannelPut::shared_pointer const & channelPut, + Structure::const_shared_pointer const & structure) + { + PvaClientPutPtr clientPut(pvaClientPut.lock()); + if(!clientPut) return; + clientPut->channelPutConnect(status,channelPut,structure); + } + + virtual void getDone( + const Status& status, + ChannelPut::shared_pointer const & channelPut, + PVStructurePtr const & pvStructure, + BitSet::shared_pointer const & bitSet) + { + PvaClientPutPtr clientPut(pvaClientPut.lock()); + if(!clientPut) return; + clientPut->getDone(status,channelPut,pvStructure,bitSet); + } + + virtual void putDone( + const Status& status, + ChannelPut::shared_pointer const & channelPut) + { + PvaClientPutPtr clientPut(pvaClientPut.lock()); + if(!clientPut) return; + clientPut->putDone(status,channelPut); + } +}; + +PvaClientPutPtr PvaClientPut::create( + PvaClientPtr const &pvaClient, + Channel::shared_pointer const & channel, + PVStructurePtr const &pvRequest) +{ + PvaClientPutPtr epv(new PvaClientPut(pvaClient,channel,pvRequest)); + epv->channelPutRequester = ChannelPutRequesterImplPtr( + new ChannelPutRequesterImpl(epv,pvaClient)); + return epv; +} + + + PvaClientPut::PvaClientPut( PvaClientPtr const &pvaClient, Channel::shared_pointer const & channel, @@ -41,10 +112,7 @@ PvaClientPut::~PvaClientPut() if(PvaClient::getDebug()) cout<< "PvaClientPut::~PvaClientPut()\n"; { Lock xx(mutex); - if(isDestroyed) { - cerr<< "Why was PvaClientPut::~PvaClientPut() called more then once????\n"; - return; - } + if(isDestroyed) throw std::runtime_error("pvaClientPut was destroyed"); isDestroyed = true; } if(channelPut) channelPut->destroy(); @@ -52,14 +120,12 @@ PvaClientPut::~PvaClientPut() void PvaClientPut::checkPutState() { - if(isDestroyed) throw std::runtime_error("pvaClientPut was destroyed"); if(connectState==connectIdle){ connect(); get(); } } -// from ChannelPutRequester string PvaClientPut::getRequesterName() { PvaClientPtr yyy = pvaClient.lock(); @@ -69,7 +135,6 @@ string PvaClientPut::getRequesterName() void PvaClientPut::message(string const & message,MessageType messageType) { - if(isDestroyed) throw std::runtime_error("pvaClientPut was destroyed"); PvaClientPtr yyy = pvaClient.lock(); if(!yyy) throw std::runtime_error("pvaClient was destroyed"); yyy->message(message, messageType); @@ -80,7 +145,6 @@ void PvaClientPut::channelPutConnect( ChannelPut::shared_pointer const & channelPut, StructureConstPtr const & structure) { - if(isDestroyed) throw std::runtime_error("pvaClientPut was destroyed"); channelPutConnectStatus = status; this->channelPut = channelPut; if(status.isOK()) { @@ -97,7 +161,6 @@ void PvaClientPut::getDone( PVStructurePtr const & pvStructure, BitSetPtr const & bitSet) { - if(isDestroyed) throw std::runtime_error("pvaClientPut was destroyed"); channelGetPutStatus = status; connectState = connected; if(status.isOK()) { @@ -114,14 +177,12 @@ void PvaClientPut::putDone( const Status& status, ChannelPut::shared_pointer const & channelPut) { - if(isDestroyed) throw std::runtime_error("pvaClientPut was destroyed"); channelGetPutStatus = status; waitForGetPut.signal(); } void PvaClientPut::connect() { - if(isDestroyed) throw std::runtime_error("pvaClientPut was destroyed"); issueConnect(); Status status = waitConnect(); if(status.isOK()) return; @@ -134,20 +195,17 @@ void PvaClientPut::connect() void PvaClientPut::issueConnect() { - if(isDestroyed) throw std::runtime_error("pvaClientPut was destroyed"); if(connectState!=connectIdle) { string message = string("channel ") + channel->getChannelName() + " pvaClientPut already connected "; throw std::runtime_error(message); } - ChannelPutRequester::shared_pointer putRequester(shared_from_this()); connectState = connectActive; - channelPut = channel->createChannelPut(putRequester,pvRequest); + channelPut = channel->createChannelPut(channelPutRequester,pvRequest); } Status PvaClientPut::waitConnect() { - if(isDestroyed) throw std::runtime_error("pvaClientPut was destroyed"); if(connectState==connected) { if(!channelPutConnectStatus.isOK()) connectState = connectIdle; return channelPutConnectStatus; @@ -164,7 +222,6 @@ Status PvaClientPut::waitConnect() void PvaClientPut::get() { - if(isDestroyed) throw std::runtime_error("pvaClientPut was destroyed"); issueGet(); Status status = waitGet(); if(status.isOK()) return; @@ -177,7 +234,6 @@ void PvaClientPut::get() void PvaClientPut::issueGet() { - if(isDestroyed) throw std::runtime_error("pvaClientPut was destroyed"); if(connectState==connectIdle) connect(); if(putState!=putIdle) { string message = string("channel ") @@ -191,7 +247,6 @@ void PvaClientPut::issueGet() Status PvaClientPut::waitGet() { - if(isDestroyed) throw std::runtime_error("pvaClientPut was destroyed"); if(putState!=getActive){ string message = string("channel ") + channel->getChannelName() + " PvaClientPut::waitGet illegal put state"; @@ -204,7 +259,6 @@ Status PvaClientPut::waitGet() void PvaClientPut::put() { - if(isDestroyed) throw std::runtime_error("pvaClientPut was destroyed"); issuePut(); Status status = waitPut(); if(status.isOK()) return; @@ -217,7 +271,6 @@ void PvaClientPut::put() void PvaClientPut::issuePut() { - if(isDestroyed) throw std::runtime_error("pvaClientPut was destroyed"); if(connectState==connectIdle) connect(); if(putState!=putIdle) { string message = string("channel ") + channel->getChannelName() @@ -230,7 +283,6 @@ void PvaClientPut::issuePut() Status PvaClientPut::waitPut() { - if(isDestroyed) throw std::runtime_error("pvaClientPut was destroyed"); if(putState!=putActive){ string message = string("channel ") + channel->getChannelName() + " PvaClientPut::waitPut illegal put state"; @@ -248,14 +300,5 @@ PvaClientPutDataPtr PvaClientPut::getData() return pvaClientData; } -PvaClientPutPtr PvaClientPut::create( - PvaClientPtr const &pvaClient, - Channel::shared_pointer const & channel, - PVStructurePtr const &pvRequest) -{ - PvaClientPutPtr epv(new PvaClientPut(pvaClient,channel,pvRequest)); - return epv; -} - }} diff --git a/src/pvaClientPutGet.cpp b/src/pvaClientPutGet.cpp index 974bfc9..2b3ecc0 100644 --- a/src/pvaClientPutGet.cpp +++ b/src/pvaClientPutGet.cpp @@ -21,6 +21,90 @@ using namespace std; namespace epics { namespace pvaClient { +class ChannelPutGetRequesterImpl : public ChannelPutGetRequester +{ + PvaClientPutGet::weak_pointer pvaClientPutGet; + PvaClient::weak_pointer pvaClient; +public: + ChannelPutGetRequesterImpl( + PvaClientPutGetPtr const & pvaClientPutGet, + PvaClientPtr const &pvaClient) + : pvaClientPutGet(pvaClientPutGet), + pvaClient(pvaClient) + {} + virtual ~ChannelPutGetRequesterImpl() { + if(PvaClient::getDebug()) std::cout << "~ChannelPutGetRequesterImpl" << std::endl; + } + + virtual std::string getRequesterName() { + PvaClientPutGetPtr clientPutGet(pvaClientPutGet.lock()); + if(!clientPutGet) return string("clientPutGet is null"); + return clientPutGet->getRequesterName(); + } + + virtual void message(std::string const & message, epics::pvData::MessageType messageType) { + PvaClientPutGetPtr clientPutGet(pvaClientPutGet.lock()); + if(!clientPutGet) return; + clientPutGet->message(message,messageType); + } + + virtual void channelPutGetConnect( + const Status& status, + ChannelPutGet::shared_pointer const & channelPutGet, + Structure::const_shared_pointer const & putStructure, + Structure::const_shared_pointer const & getStructure) + { + PvaClientPutGetPtr clientPutGet(pvaClientPutGet.lock()); + if(!clientPutGet) return; + clientPutGet->channelPutGetConnect(status,channelPutGet,putStructure,getStructure); + } + + virtual void putGetDone( + const Status& status, + ChannelPutGet::shared_pointer const & channelPutGet, + PVStructurePtr const & getPVStructure, + BitSet::shared_pointer const & getBitSet) + { + PvaClientPutGetPtr clientPutGet(pvaClientPutGet.lock()); + if(!clientPutGet) return; + clientPutGet->putGetDone(status,channelPutGet,getPVStructure,getBitSet); + } + + virtual void getPutDone( + const Status& status, + ChannelPutGet::shared_pointer const & channelPutGet, + PVStructurePtr const & putPVStructure, + BitSet::shared_pointer const & putBitSet) + { + PvaClientPutGetPtr clientPutGet(pvaClientPutGet.lock()); + if(!clientPutGet) return; + clientPutGet->getPutDone(status,channelPutGet,putPVStructure,putBitSet); + } + + + virtual void getGetDone( + const Status& status, + ChannelPutGet::shared_pointer const & channelPutGet, + PVStructurePtr const & getPVStructure, + BitSet::shared_pointer const & getBitSet) + { + PvaClientPutGetPtr clientPutGet(pvaClientPutGet.lock()); + if(!clientPutGet) return; + clientPutGet->getGetDone(status,channelPutGet,getPVStructure,getBitSet); + } +}; + +PvaClientPutGetPtr PvaClientPutGet::create( + PvaClientPtr const &pvaClient, + Channel::shared_pointer const & channel, + PVStructurePtr const &pvRequest) +{ + PvaClientPutGetPtr epv(new PvaClientPutGet(pvaClient,channel,pvRequest)); + epv->channelPutGetRequester = ChannelPutGetRequesterImplPtr( + new ChannelPutGetRequesterImpl(epv,pvaClient)); + return epv; +} + PvaClientPutGet::PvaClientPutGet( PvaClientPtr const &pvaClient, Channel::shared_pointer const & channel, @@ -40,10 +124,7 @@ PvaClientPutGet::~PvaClientPutGet() if(PvaClient::getDebug()) cout<< "PvaClientPutGet::~PvaClientPutGet()\n"; { Lock xx(mutex); - if(isDestroyed) { - cerr<< "Why was PvaClientPutGet::~PvaClientPutGet() called more then once????\n"; - return; - } + if(isDestroyed) throw std::runtime_error("pvaClientPutGet was destroyed"); isDestroyed = true; } channelPutGet->destroy(); @@ -51,14 +132,12 @@ PvaClientPutGet::~PvaClientPutGet() void PvaClientPutGet::checkPutGetState() { - if(isDestroyed) throw std::runtime_error("pvaClientPutGet was destroyed"); if(connectState==connectIdle){ connect(); getPut(); } } -// from ChannelPutGetRequester string PvaClientPutGet::getRequesterName() { PvaClientPtr yyy = pvaClient.lock(); @@ -68,7 +147,6 @@ string PvaClientPutGet::getRequesterName() void PvaClientPutGet::message(string const & message,MessageType messageType) { - if(isDestroyed) throw std::runtime_error("pvaClientPutGet was destroyed"); PvaClientPtr yyy = pvaClient.lock(); if(!yyy) throw std::runtime_error("pvaClient was destroyed"); yyy->message(message, messageType); @@ -80,7 +158,6 @@ void PvaClientPutGet::channelPutGetConnect( StructureConstPtr const & putStructure, StructureConstPtr const & getStructure) { - if(isDestroyed) throw std::runtime_error("pvaClientPutGet was destroyed"); channelPutGetConnectStatus = status; this->channelPutGet = channelPutGet; if(status.isOK()) { @@ -99,7 +176,6 @@ void PvaClientPutGet::putGetDone( PVStructurePtr const & getPVStructure, BitSetPtr const & getChangedBitSet) { - if(isDestroyed) throw std::runtime_error("pvaClientPutGet was destroyed"); channelPutGetStatus = status; if(status.isOK()) { pvaClientGetData->setData(getPVStructure,getChangedBitSet); @@ -113,7 +189,6 @@ void PvaClientPutGet::getPutDone( PVStructurePtr const & putPVStructure, BitSetPtr const & putBitSet) { - if(isDestroyed) throw std::runtime_error("pvaClientPutGet was destroyed"); channelPutGetStatus = status; if(status.isOK()) { PVStructurePtr pvs = pvaClientPutData->getPVStructure(); @@ -131,7 +206,6 @@ void PvaClientPutGet::getGetDone( PVStructurePtr const & getPVStructure, BitSetPtr const & getChangedBitSet) { - if(isDestroyed) throw std::runtime_error("pvaClientPutGet was destroyed"); channelPutGetStatus = status; if(status.isOK()) { pvaClientGetData->setData(getPVStructure,getChangedBitSet); @@ -141,7 +215,6 @@ void PvaClientPutGet::getGetDone( void PvaClientPutGet::connect() { - if(isDestroyed) throw std::runtime_error("pvaClientPutGet was destroyed"); issueConnect(); Status status = waitConnect(); if(status.isOK()) return; @@ -152,20 +225,17 @@ void PvaClientPutGet::connect() void PvaClientPutGet::issueConnect() { - if(isDestroyed) throw std::runtime_error("pvaClientPutGet was destroyed"); if(connectState!=connectIdle) { string message = string("channel ") + channel->getChannelName() + " pvaClientPutGet already connected "; throw std::runtime_error(message); } - ChannelPutGetRequester::shared_pointer putGetRequester(shared_from_this()); connectState = connectActive; - channelPutGet = channel->createChannelPutGet(putGetRequester,pvRequest); + channelPutGet = channel->createChannelPutGet(channelPutGetRequester,pvRequest); } Status PvaClientPutGet::waitConnect() { - if(isDestroyed) throw std::runtime_error("pvaClientPutGet was destroyed"); if(connectState!=connectActive) { string message = string("channel ") + channel->getChannelName() + " pvaClientPutGet illegal connect state "; @@ -179,7 +249,6 @@ Status PvaClientPutGet::waitConnect() void PvaClientPutGet::putGet() { - if(isDestroyed) throw std::runtime_error("pvaClientPutGet was destroyed"); issuePutGet(); Status status = waitPutGet(); if(status.isOK()) return; @@ -190,7 +259,6 @@ void PvaClientPutGet::putGet() void PvaClientPutGet::issuePutGet() { - if(isDestroyed) throw std::runtime_error("pvaClientPutGet was destroyed"); if(connectState==connectIdle) connect(); if(putGetState!=putGetIdle) { string message = string("channel ") + channel->getChannelName() @@ -204,7 +272,6 @@ void PvaClientPutGet::issuePutGet() Status PvaClientPutGet::waitPutGet() { - if(isDestroyed) throw std::runtime_error("pvaClientPutGet was destroyed"); if(putGetState!=putGetActive){ string message = string("channel ") + channel->getChannelName() + " PvaClientPutGet::waitPutGet llegal put state"; @@ -217,7 +284,6 @@ Status PvaClientPutGet::waitPutGet() void PvaClientPutGet::getGet() { - if(isDestroyed) throw std::runtime_error("pvaClientPutGet was destroyed"); issueGetGet(); Status status = waitGetGet(); if(status.isOK()) return; @@ -228,7 +294,6 @@ void PvaClientPutGet::getGet() void PvaClientPutGet::issueGetGet() { - if(isDestroyed) throw std::runtime_error("pvaClientPutGet was destroyed"); if(connectState==connectIdle) connect(); if(putGetState!=putGetIdle) { string message = string("channel ") + channel->getChannelName() @@ -241,7 +306,6 @@ void PvaClientPutGet::issueGetGet() Status PvaClientPutGet::waitGetGet() { - if(isDestroyed) throw std::runtime_error("pvaClientPutGet was destroyed"); if(putGetState!=putGetActive){ string message = string("channel ") + channel->getChannelName() + " PvaClientPutGet::waitGetGet illegal state"; @@ -254,7 +318,6 @@ Status PvaClientPutGet::waitGetGet() void PvaClientPutGet::getPut() { - if(isDestroyed) throw std::runtime_error("pvaClientPutGet was destroyed"); issueGetPut(); Status status = waitGetPut(); if(status.isOK()) return; @@ -265,7 +328,6 @@ void PvaClientPutGet::getPut() void PvaClientPutGet::issueGetPut() { - if(isDestroyed) throw std::runtime_error("pvaClientPutGet was destroyed"); if(connectState==connectIdle) connect(); if(putGetState!=putGetIdle) { string message = string("channel ") + channel->getChannelName() @@ -278,7 +340,6 @@ void PvaClientPutGet::issueGetPut() Status PvaClientPutGet::waitGetPut() { - if(isDestroyed) throw std::runtime_error("pvaClientPutGet was destroyed"); if(putGetState!=putGetActive){ string message = string("channel ") + channel->getChannelName() + " PvaClientPutGet::waitGetPut illegal state"; @@ -301,14 +362,4 @@ PvaClientPutDataPtr PvaClientPutGet::getPutData() return pvaClientPutData; } -PvaClientPutGetPtr PvaClientPutGet::create( - PvaClientPtr const &pvaClient, - Channel::shared_pointer const & channel, - PVStructurePtr const &pvRequest) -{ - PvaClientPutGetPtr epv(new PvaClientPutGet(pvaClient,channel,pvRequest)); - return epv; -} - - }} From 6ff53f4dcb930c7d6a6a14ccded27826c9660058 Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Fri, 27 May 2016 14:20:41 -0400 Subject: [PATCH 09/12] still working on RAII; work on doxygen --- Doxyfile | 383 ++++++++++++++++++++------------- src/pv/pvaClient.h | 334 +++++++++++++--------------- src/pv/pvaClientMultiChannel.h | 43 +--- src/pvaClient.cpp | 6 +- src/pvaClientChannel.cpp | 49 +---- src/pvaClientGet.cpp | 32 ++- src/pvaClientMonitor.cpp | 204 ++++++++++++++---- src/pvaClientMultiChannel.cpp | 23 +- src/pvaClientPut.cpp | 107 +++++++-- src/pvaClientPutGet.cpp | 165 +++++++++++--- 10 files changed, 820 insertions(+), 526 deletions(-) diff --git a/Doxyfile b/Doxyfile index 216cc44..2858b5b 100644 --- a/Doxyfile +++ b/Doxyfile @@ -1,4 +1,4 @@ -# Doxyfile 1.8.6 +# Doxyfile 1.8.10 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. @@ -46,10 +46,10 @@ PROJECT_NUMBER = PROJECT_BRIEF = -# With the PROJECT_LOGO tag one can specify an logo or icon that is included in -# the documentation. The maximum height of the logo should not exceed 55 pixels -# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo -# to the output directory. +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. PROJECT_LOGO = @@ -60,7 +60,7 @@ PROJECT_LOGO = OUTPUT_DIRECTORY = -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub- +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- # directories (in 2 levels) under the output directory of each output format and # will distribute the generated files over these directories. Enabling this # option can be useful when feeding doxygen a huge amount of source files, where @@ -70,6 +70,14 @@ OUTPUT_DIRECTORY = CREATE_SUBDIRS = NO +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. @@ -85,14 +93,14 @@ CREATE_SUBDIRS = NO OUTPUT_LANGUAGE = English -# If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member +# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member # descriptions after the members that are listed in the file and class # documentation (similar to Javadoc). Set to NO to disable this. # The default value is: YES. BRIEF_MEMBER_DESC = YES -# If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief +# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief # description of a member or function before the detailed description # # Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the @@ -127,7 +135,7 @@ ALWAYS_DETAILED_SEC = NO INLINE_INHERITED_MEMB = YES -# If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path +# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path # before files name in the file list and in the header files. If set to NO the # shortest path that makes the file name unique will be used # The default value is: YES. @@ -197,9 +205,9 @@ MULTILINE_CPP_IS_BRIEF = NO INHERIT_DOCS = YES -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a -# new page for each member. If set to NO, the documentation of a member will be -# part of the file/class/namespace that contains it. +# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. # The default value is: NO. SEPARATE_MEMBER_PAGES = NO @@ -261,11 +269,14 @@ OPTIMIZE_OUTPUT_VHDL = NO # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, and # language is one of the parsers supported by doxygen: IDL, Java, Javascript, -# C#, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL. For instance to make -# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C -# (default is Fortran), use: inc=Fortran f=C. +# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: +# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: +# Fortran. In the later case the parser tries to guess whether the code is fixed +# or free formatted code, this is the default for Fortran type files), VHDL. For +# instance to make doxygen treat .inc files as Fortran files (default is PHP), +# and .f files as C (default is Fortran), use: inc=Fortran f=C. # -# Note For files without extension you can use no_extension as a placeholder. +# Note: For files without extension you can use no_extension as a placeholder. # # Note that for custom extensions you also need to set FILE_PATTERNS otherwise # the files are not read by doxygen. @@ -284,8 +295,8 @@ MARKDOWN_SUPPORT = YES # When enabled doxygen tries to link words that correspond to documented # classes, or namespaces to their corresponding documentation. Such a link can -# be prevented in individual cases by by putting a % sign in front of the word -# or globally by setting AUTOLINK_SUPPORT to NO. +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. # The default value is: YES. AUTOLINK_SUPPORT = YES @@ -325,13 +336,20 @@ SIP_SUPPORT = NO IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first +# tag is set to YES then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. # The default value is: NO. DISTRIBUTE_GROUP_DOC = NO +# If one adds a struct or class to a group and this option is enabled, then also +# any nested class or struct is added to the same group. By default this option +# is disabled and one has to add nested compounds explicitly via \ingroup. +# The default value is: NO. + +GROUP_NESTED_COMPOUNDS = NO + # Set the SUBGROUPING tag to YES to allow class member groups of the same type # (for instance a group of public functions) to be put as a subgroup of that # type (e.g. under the Public Functions section). Set it to NO to prevent @@ -390,7 +408,7 @@ LOOKUP_CACHE_SIZE = 0 # Build related configuration options #--------------------------------------------------------------------------- -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in # documentation are documented, even if no documentation was available. Private # class members and static file members will be hidden unless the # EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. @@ -400,35 +418,35 @@ LOOKUP_CACHE_SIZE = 0 EXTRACT_ALL = YES -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will # be included in the documentation. # The default value is: NO. EXTRACT_PRIVATE = NO -# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal # scope will be included in the documentation. # The default value is: NO. EXTRACT_PACKAGE = NO -# If the EXTRACT_STATIC tag is set to YES all static members of a file will be +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be # included in the documentation. # The default value is: NO. EXTRACT_STATIC = NO -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined -# locally in source files will be included in the documentation. If set to NO +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, # only classes defined in header files are included. Does not have any effect # for Java sources. # The default value is: YES. EXTRACT_LOCAL_CLASSES = NO -# This flag is only useful for Objective-C code. When set to YES local methods, +# This flag is only useful for Objective-C code. If set to YES, local methods, # which are defined in the implementation section but not in the interface are -# included in the documentation. If set to NO only methods in the interface are +# included in the documentation. If set to NO, only methods in the interface are # included. # The default value is: NO. @@ -453,21 +471,21 @@ HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. If set -# to NO these classes will be included in the various overviews. This option has -# no effect if EXTRACT_ALL is enabled. +# to NO, these classes will be included in the various overviews. This option +# has no effect if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend -# (class|struct|union) declarations. If set to NO these declarations will be +# (class|struct|union) declarations. If set to NO, these declarations will be # included in the documentation. # The default value is: NO. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any -# documentation blocks found inside the body of a function. If set to NO these +# documentation blocks found inside the body of a function. If set to NO, these # blocks will be appended to the function's detailed documentation block. # The default value is: NO. @@ -481,7 +499,7 @@ HIDE_IN_BODY_DOCS = NO INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file -# names in lower-case letters. If set to YES upper-case letters are also +# names in lower-case letters. If set to YES, upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. @@ -490,12 +508,19 @@ INTERNAL_DOCS = NO CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with -# their full class and namespace scopes in the documentation. If set to YES the +# their full class and namespace scopes in the documentation. If set to YES, the # scope will be hidden. # The default value is: NO. HIDE_SCOPE_NAMES = NO +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + # If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of # the files that are included by a file in the documentation of that file. # The default value is: YES. @@ -523,14 +548,14 @@ INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the # (detailed) documentation of file and class members alphabetically by member -# name. If set to NO the members will appear in declaration order. +# name. If set to NO, the members will appear in declaration order. # The default value is: YES. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief # descriptions of file, namespace and class members alphabetically by member -# name. If set to NO the members will appear in declaration order. Note that +# name. If set to NO, the members will appear in declaration order. Note that # this will also influence the order of the classes in the class list. # The default value is: NO. @@ -575,27 +600,25 @@ SORT_BY_SCOPE_NAME = NO STRICT_PROTO_MATCHING = NO -# The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the -# todo list. This list is created by putting \todo commands in the -# documentation. +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. # The default value is: YES. GENERATE_TODOLIST = YES -# The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the -# test list. This list is created by putting \test commands in the -# documentation. +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. # The default value is: YES. GENERATE_TESTLIST = YES -# The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug # list. This list is created by putting \bug commands in the documentation. # The default value is: YES. GENERATE_BUGLIST = YES -# The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO) +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) # the deprecated list. This list is created by putting \deprecated commands in # the documentation. # The default value is: YES. @@ -620,8 +643,8 @@ ENABLED_SECTIONS = MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated at -# the bottom of the documentation of classes and structs. If set to YES the list -# will mention the files that were used to generate the documentation. +# the bottom of the documentation of classes and structs. If set to YES, the +# list will mention the files that were used to generate the documentation. # The default value is: YES. SHOW_USED_FILES = YES @@ -669,8 +692,7 @@ LAYOUT_FILE = # to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. # For LaTeX the style of the bibliography can be controlled using # LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the -# search path. Do not use file names with spaces, bibtex cannot handle them. See -# also \cite for info how to create references. +# search path. See also \cite for info how to create references. CITE_BIB_FILES = @@ -686,7 +708,7 @@ CITE_BIB_FILES = QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are -# generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES # this implies that the warnings are on. # # Tip: Turn warnings on while writing the documentation. @@ -694,7 +716,7 @@ QUIET = NO WARNINGS = YES -# If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate # warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag # will automatically be disabled. # The default value is: YES. @@ -711,8 +733,8 @@ WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that # are documented, but have no documentation for their parameters or return -# value. If set to NO doxygen will only warn about wrong or incomplete parameter -# documentation, but not about the absence of documentation. +# value. If set to NO, doxygen will only warn about wrong or incomplete +# parameter documentation, but not about the absence of documentation. # The default value is: NO. WARN_NO_PARAMDOC = NO @@ -740,7 +762,7 @@ WARN_LOGFILE = # The INPUT tag is used to specify the files and/or directories that contain # documented source files. You may enter file names like myfile.cpp or # directories like /usr/src/myproject. Separate the files or directories with -# spaces. +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. INPUT = include @@ -756,12 +778,17 @@ INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and -# *.h) to filter out the source-files in the directories. If left blank the -# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii, -# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, -# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, -# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, -# *.qsf, *.as and *.js. +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by doxygen. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, +# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, +# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, +# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, +# *.vhdl, *.ucf, *.qsf, *.as and *.js. FILE_PATTERNS = @@ -860,7 +887,7 @@ INPUT_FILTER = FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER ) will also be used to filter the input files that are used for +# INPUT_FILTER) will also be used to filter the input files that are used for # producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). # The default value is: NO. @@ -920,7 +947,7 @@ REFERENCED_BY_RELATION = YES REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set -# to YES, then the hyperlinks from functions in REFERENCES_RELATION and +# to YES then the hyperlinks from functions in REFERENCES_RELATION and # REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will # link to the documentation. # The default value is: YES. @@ -997,7 +1024,7 @@ IGNORE_PREFIX = # Configuration options related to the HTML output #--------------------------------------------------------------------------- -# If the GENERATE_HTML tag is set to YES doxygen will generate HTML output +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output # The default value is: YES. GENERATE_HTML = YES @@ -1059,13 +1086,15 @@ HTML_FOOTER = HTML_STYLESHEET = -# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user- -# defined cascading style sheet that is included after the standard style sheets +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets # created by doxygen. Using this option one can overrule certain style aspects. # This is preferred over using HTML_STYLESHEET since it does not replace the -# standard style sheet and is therefor more robust against future updates. -# Doxygen will copy the style sheet file to the output directory. For an example -# see the documentation. +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). For an example see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_STYLESHEET = @@ -1078,10 +1107,10 @@ HTML_EXTRA_STYLESHEET = # files will be copied as-is; there are no commands or markers available. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_EXTRA_FILES = +HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen -# will adjust the colors in the stylesheet and background images according to +# will adjust the colors in the style sheet and background images according to # this color. Hue is specified as an angle on a colorwheel, see # http://en.wikipedia.org/wiki/Hue for more information. For instance the value # 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 @@ -1112,8 +1141,9 @@ HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting this -# to NO can help when comparing the output of multiple runs. -# The default value is: YES. +# to YES can help to show when doxygen was last run and thus if the +# documentation is up to date. +# The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_TIMESTAMP = YES @@ -1209,28 +1239,29 @@ GENERATE_HTMLHELP = NO CHM_FILE = # The HHC_LOCATION tag can be used to specify the location (absolute path -# including file name) of the HTML help compiler ( hhc.exe). If non-empty +# including file name) of the HTML help compiler (hhc.exe). If non-empty, # doxygen will try to run the HTML help compiler on the generated index.hhp. # The file has to be specified with full path. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. HHC_LOCATION = -# The GENERATE_CHI flag controls if a separate .chi index file is generated ( -# YES) or that it should be included in the master .chm file ( NO). +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the master .chm file (NO). # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. GENERATE_CHI = NO -# The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc) +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) # and project file content. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_INDEX_ENCODING = -# The BINARY_TOC flag controls whether a binary table of contents is generated ( -# YES) or a normal table of contents ( NO) in the .chm file. +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. @@ -1343,7 +1374,7 @@ DISABLE_INDEX = NO # index structure (just like the one that is generated for HTML Help). For this # to work a browser that supports JavaScript, DHTML, CSS and frames is required # (i.e. any modern browser). Windows users are probably better off using the -# HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can # further fine-tune the look of the index. As an example, the default style # sheet generated by doxygen has an example that shows how to put an image at # the root of the tree instead of the PROJECT_NAME. Since the tree basically has @@ -1371,7 +1402,7 @@ ENUM_VALUES_PER_LINE = 4 TREEVIEW_WIDTH = 250 -# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to # external symbols imported via tag files in a separate window. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. @@ -1400,7 +1431,7 @@ FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see # http://www.mathjax.org) which uses client side Javascript for the rendering -# instead of using prerendered bitmaps. Use this if you do not have LaTeX +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX # installed or if you want to formulas look prettier in the HTML output. When # enabled you may also need to install MathJax separately and configure the path # to it using the MATHJAX_RELPATH option. @@ -1470,11 +1501,11 @@ SEARCHENGINE = NO # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a web server instead of a web client using Javascript. There -# are two flavours of web server based searching depending on the -# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for -# searching and an index file used by the script. When EXTERNAL_SEARCH is -# enabled the indexing and searching needs to be provided by external tools. See -# the section "External Indexing and Searching" for details. +# are two flavors of web server based searching depending on the EXTERNAL_SEARCH +# setting. When disabled, doxygen will generate a PHP script for searching and +# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing +# and searching needs to be provided by external tools. See the section +# "External Indexing and Searching" for details. # The default value is: NO. # This tag requires that the tag SEARCHENGINE is set to YES. @@ -1486,7 +1517,7 @@ SERVER_BASED_SEARCH = NO # external search engine pointed to by the SEARCHENGINE_URL option to obtain the # search results. # -# Doxygen ships with an example indexer ( doxyindexer) and search engine +# Doxygen ships with an example indexer (doxyindexer) and search engine # (doxysearch.cgi) which are based on the open source search engine library # Xapian (see: http://xapian.org/). # @@ -1499,7 +1530,7 @@ EXTERNAL_SEARCH = NO # The SEARCHENGINE_URL should point to a search engine hosted by a web server # which will return the search results when EXTERNAL_SEARCH is enabled. # -# Doxygen ships with an example indexer ( doxyindexer) and search engine +# Doxygen ships with an example indexer (doxyindexer) and search engine # (doxysearch.cgi) which are based on the open source search engine library # Xapian (see: http://xapian.org/). See the section "External Indexing and # Searching" for details. @@ -1537,7 +1568,7 @@ EXTRA_SEARCH_MAPPINGS = # Configuration options related to the LaTeX output #--------------------------------------------------------------------------- -# If the GENERATE_LATEX tag is set to YES doxygen will generate LaTeX output. +# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output. # The default value is: YES. GENERATE_LATEX = NO @@ -1568,7 +1599,7 @@ LATEX_CMD_NAME = latex MAKEINDEX_CMD_NAME = makeindex -# If the COMPACT_LATEX tag is set to YES doxygen generates more compact LaTeX +# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX # documents. This may be useful for small projects and may help to save some # trees in general. # The default value is: NO. @@ -1586,9 +1617,12 @@ COMPACT_LATEX = NO PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names -# that should be included in the LaTeX output. To get the times font for -# instance you can specify -# EXTRA_PACKAGES=times +# that should be included in the LaTeX output. The package can be specified just +# by its name or with the correct syntax as to be used with the LaTeX +# \usepackage command. To get the times font for instance you can specify : +# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times} +# To use the option intlimits with the amsmath package you can specify: +# EXTRA_PACKAGES=[intlimits]{amsmath} # If left blank no extra packages will be included. # This tag requires that the tag GENERATE_LATEX is set to YES. @@ -1602,23 +1636,36 @@ EXTRA_PACKAGES = # # Note: Only use a user-defined header if you know what you are doing! The # following commands have a special meaning inside the header: $title, -# $datetime, $date, $doxygenversion, $projectname, $projectnumber. Doxygen will -# replace them by respectively the title of the page, the current date and time, -# only the current date, the version number of doxygen, the project name (see -# PROJECT_NAME), or the project number (see PROJECT_NUMBER). +# $datetime, $date, $doxygenversion, $projectname, $projectnumber, +# $projectbrief, $projectlogo. Doxygen will replace $title with the empty +# string, for the replacement values of the other commands the user is referred +# to HTML_HEADER. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_HEADER = # The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the # generated LaTeX document. The footer should contain everything after the last -# chapter. If it is left blank doxygen will generate a standard footer. +# chapter. If it is left blank doxygen will generate a standard footer. See +# LATEX_HEADER for more information on how to generate a default footer and what +# special commands can be used inside the footer. # # Note: Only use a user-defined footer if you know what you are doing! # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_FOOTER = +# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# LaTeX style sheets that are included after the standard style sheets created +# by doxygen. Using this option one can overrule certain style aspects. Doxygen +# will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_EXTRA_STYLESHEET = + # The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the LATEX_OUTPUT output # directory. Note that the files will be copied as-is; there are no commands or @@ -1636,8 +1683,8 @@ LATEX_EXTRA_FILES = PDF_HYPERLINKS = NO -# If the LATEX_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate -# the PDF file directly from the LaTeX files. Set this option to YES to get a +# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate +# the PDF file directly from the LaTeX files. Set this option to YES, to get a # higher quality PDF documentation. # The default value is: YES. # This tag requires that the tag GENERATE_LATEX is set to YES. @@ -1678,11 +1725,19 @@ LATEX_SOURCE_CODE = NO LATEX_BIB_STYLE = plain +# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated +# page will contain the date and time when the page was generated. Setting this +# to NO can help when comparing the output of multiple runs. +# The default value is: NO. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_TIMESTAMP = NO + #--------------------------------------------------------------------------- # Configuration options related to the RTF output #--------------------------------------------------------------------------- -# If the GENERATE_RTF tag is set to YES doxygen will generate RTF output. The +# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The # RTF output is optimized for Word 97 and may not look too pretty with other RTF # readers/editors. # The default value is: NO. @@ -1697,7 +1752,7 @@ GENERATE_RTF = NO RTF_OUTPUT = rtf -# If the COMPACT_RTF tag is set to YES doxygen generates more compact RTF +# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF # documents. This may be useful for small projects and may help to save some # trees in general. # The default value is: NO. @@ -1734,11 +1789,21 @@ RTF_STYLESHEET_FILE = RTF_EXTENSIONS_FILE = +# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code +# with syntax highlighting in the RTF output. +# +# Note that which sources are shown also depends on other settings such as +# SOURCE_BROWSER. +# The default value is: NO. +# This tag requires that the tag GENERATE_RTF is set to YES. + +RTF_SOURCE_CODE = NO + #--------------------------------------------------------------------------- # Configuration options related to the man page output #--------------------------------------------------------------------------- -# If the GENERATE_MAN tag is set to YES doxygen will generate man pages for +# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for # classes and files. # The default value is: NO. @@ -1762,6 +1827,13 @@ MAN_OUTPUT = man MAN_EXTENSION = .3 +# The MAN_SUBDIR tag determines the name of the directory created within +# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by +# MAN_EXTENSION with the initial . removed. +# This tag requires that the tag GENERATE_MAN is set to YES. + +MAN_SUBDIR = + # If the MAN_LINKS tag is set to YES and doxygen generates man output, then it # will generate one additional man file for each entity documented in the real # man page(s). These additional files only source the real man page, but without @@ -1775,7 +1847,7 @@ MAN_LINKS = NO # Configuration options related to the XML output #--------------------------------------------------------------------------- -# If the GENERATE_XML tag is set to YES doxygen will generate an XML file that +# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that # captures the structure of the code including all documentation. # The default value is: NO. @@ -1789,19 +1861,7 @@ GENERATE_XML = NO XML_OUTPUT = xml -# The XML_SCHEMA tag can be used to specify a XML schema, which can be used by a -# validating XML parser to check the syntax of the XML files. -# This tag requires that the tag GENERATE_XML is set to YES. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify a XML DTD, which can be used by a -# validating XML parser to check the syntax of the XML files. -# This tag requires that the tag GENERATE_XML is set to YES. - -XML_DTD = - -# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program +# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program # listings (including syntax highlighting and cross-referencing information) to # the XML output. Note that enabling this will significantly increase the size # of the XML output. @@ -1814,7 +1874,7 @@ XML_PROGRAMLISTING = YES # Configuration options related to the DOCBOOK output #--------------------------------------------------------------------------- -# If the GENERATE_DOCBOOK tag is set to YES doxygen will generate Docbook files +# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files # that can be used to generate PDF. # The default value is: NO. @@ -1828,14 +1888,23 @@ GENERATE_DOCBOOK = NO DOCBOOK_OUTPUT = docbook +# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the +# program listings (including syntax highlighting and cross-referencing +# information) to the DOCBOOK output. Note that enabling this will significantly +# increase the size of the DOCBOOK output. +# The default value is: NO. +# This tag requires that the tag GENERATE_DOCBOOK is set to YES. + +DOCBOOK_PROGRAMLISTING = NO + #--------------------------------------------------------------------------- # Configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- -# If the GENERATE_AUTOGEN_DEF tag is set to YES doxygen will generate an AutoGen -# Definitions (see http://autogen.sf.net) file that captures the structure of -# the code including all documentation. Note that this feature is still -# experimental and incomplete at the moment. +# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an +# AutoGen Definitions (see http://autogen.sf.net) file that captures the +# structure of the code including all documentation. Note that this feature is +# still experimental and incomplete at the moment. # The default value is: NO. GENERATE_AUTOGEN_DEF = NO @@ -1844,7 +1913,7 @@ GENERATE_AUTOGEN_DEF = NO # Configuration options related to the Perl module output #--------------------------------------------------------------------------- -# If the GENERATE_PERLMOD tag is set to YES doxygen will generate a Perl module +# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module # file that captures the structure of the code including all documentation. # # Note that this feature is still experimental and incomplete at the moment. @@ -1852,7 +1921,7 @@ GENERATE_AUTOGEN_DEF = NO GENERATE_PERLMOD = NO -# If the PERLMOD_LATEX tag is set to YES doxygen will generate the necessary +# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary # Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI # output from the Perl module output. # The default value is: NO. @@ -1860,9 +1929,9 @@ GENERATE_PERLMOD = NO PERLMOD_LATEX = NO -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be nicely +# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely # formatted so it can be parsed by a human reader. This is useful if you want to -# understand what is going on. On the other hand, if this tag is set to NO the +# understand what is going on. On the other hand, if this tag is set to NO, the # size of the Perl module output will be much smaller and Perl will parse it # just the same. # The default value is: YES. @@ -1882,14 +1951,14 @@ PERLMOD_MAKEVAR_PREFIX = # Configuration options related to the preprocessor #--------------------------------------------------------------------------- -# If the ENABLE_PREPROCESSING tag is set to YES doxygen will evaluate all +# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all # C-preprocessor directives found in the sources and include files. # The default value is: YES. ENABLE_PREPROCESSING = YES -# If the MACRO_EXPANSION tag is set to YES doxygen will expand all macro names -# in the source code. If set to NO only conditional compilation will be +# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names +# in the source code. If set to NO, only conditional compilation will be # performed. Macro expansion can be done in a controlled way by setting # EXPAND_ONLY_PREDEF to YES. # The default value is: NO. @@ -1905,7 +1974,7 @@ MACRO_EXPANSION = NO EXPAND_ONLY_PREDEF = NO -# If the SEARCH_INCLUDES tag is set to YES the includes files in the +# If the SEARCH_INCLUDES tag is set to YES, the include files in the # INCLUDE_PATH will be searched if a #include is found. # The default value is: YES. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. @@ -1947,9 +2016,9 @@ PREDEFINED = EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will -# remove all refrences to function-like macros that are alone on a line, have an -# all uppercase name, and do not end with a semicolon. Such function macros are -# typically used for boiler-plate code, and will confuse the parser if not +# remove all references to function-like macros that are alone on a line, have +# an all uppercase name, and do not end with a semicolon. Such function macros +# are typically used for boiler-plate code, and will confuse the parser if not # removed. # The default value is: YES. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. @@ -1969,7 +2038,7 @@ SKIP_FUNCTION_MACROS = YES # where loc1 and loc2 can be relative or absolute paths or URLs. See the # section "Linking to external documentation" for more information about the use # of tag files. -# Note: Each tag file must have an unique name (where the name does NOT include +# Note: Each tag file must have a unique name (where the name does NOT include # the path). If a tag file is not located in the directory in which doxygen is # run, you must also specify the path to the tagfile here. @@ -1981,20 +2050,21 @@ TAGFILES = GENERATE_TAGFILE = -# If the ALLEXTERNALS tag is set to YES all external class will be listed in the -# class index. If set to NO only the inherited external classes will be listed. +# If the ALLEXTERNALS tag is set to YES, all external class will be listed in +# the class index. If set to NO, only the inherited external classes will be +# listed. # The default value is: NO. ALLEXTERNALS = NO -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed in -# the modules index. If set to NO, only the current project's groups will be +# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will be # listed. # The default value is: YES. EXTERNAL_GROUPS = YES -# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed in +# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in # the related pages index. If set to NO, only the current project's pages will # be listed. # The default value is: YES. @@ -2011,7 +2081,7 @@ PERL_PATH = /usr/bin/perl # Configuration options related to the dot tool #--------------------------------------------------------------------------- -# If the CLASS_DIAGRAMS tag is set to YES doxygen will generate a class diagram +# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram # (in HTML and LaTeX) for classes with base or super classes. Setting the tag to # NO turns the diagrams off. Note that this option also works with HAVE_DOT # disabled, but it is recommended to install and use dot, since it yields more @@ -2036,7 +2106,7 @@ MSCGEN_PATH = DIA_PATH = -# If set to YES, the inheritance and collaboration graphs will hide inheritance +# If set to YES the inheritance and collaboration graphs will hide inheritance # and usage relations if the target is undocumented or is not a class. # The default value is: YES. @@ -2061,7 +2131,7 @@ HAVE_DOT = NO DOT_NUM_THREADS = 0 -# When you want a differently looking font n the dot files that doxygen +# When you want a differently looking font in the dot files that doxygen # generates you can specify the font name using DOT_FONTNAME. You need to make # sure dot is able to find the font, which can be done by putting it in a # standard location or by setting the DOTFONTPATH environment variable or by @@ -2109,7 +2179,7 @@ COLLABORATION_GRAPH = YES GROUP_GRAPHS = YES -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. # The default value is: NO. @@ -2161,7 +2231,8 @@ INCLUDED_BY_GRAPH = YES # # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable call graphs for selected -# functions only using the \callgraph command. +# functions only using the \callgraph command. Disabling a call graph can be +# accomplished by means of the command \hidecallgraph. # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2172,7 +2243,8 @@ CALL_GRAPH = NO # # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable caller graphs for selected -# functions only using the \callergraph command. +# functions only using the \callergraph command. Disabling a caller graph can be +# accomplished by means of the command \hidecallergraph. # The default value is: NO. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2195,11 +2267,15 @@ GRAPHICAL_HIERARCHY = YES DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. +# generated by dot. For an explanation of the image formats see the section +# output formats in the documentation of the dot tool (Graphviz (see: +# http://www.graphviz.org/)). # Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order # to make the SVG files visible in IE 9+ (other browsers do not have this # requirement). -# Possible values are: png, jpg, gif and svg. +# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo, +# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and +# png:gdiplus:gdiplus. # The default value is: png. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2242,6 +2318,19 @@ MSCFILE_DIRS = DIAFILE_DIRS = +# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the +# path where java can find the plantuml.jar file. If left blank, it is assumed +# PlantUML is not used or called during a preprocessing step. Doxygen will +# generate a warning when it encounters a \startuml command in this case and +# will not generate output for the diagram. + +PLANTUML_JAR_PATH = + +# When using plantuml, the specified paths are searched for files specified by +# the !include statement in a plantuml block. + +PLANTUML_INCLUDE_PATH = + # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes # that will be shown in the graph. If the number of nodes in a graph becomes # larger than this value, doxygen will truncate the graph, which is visualized @@ -2278,7 +2367,7 @@ MAX_DOT_GRAPH_DEPTH = 0 DOT_TRANSPARENT = NO -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) support # this, this feature is disabled by default. @@ -2295,7 +2384,7 @@ DOT_MULTI_TARGETS = NO GENERATE_LEGEND = YES -# If the DOT_CLEANUP tag is set to YES doxygen will remove the intermediate dot +# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot # files that are used to generate the various graphs. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. diff --git a/src/pv/pvaClient.h b/src/pv/pvaClient.h index 9bf05a6..214ef1f 100644 --- a/src/pv/pvaClient.h +++ b/src/pv/pvaClient.h @@ -89,7 +89,6 @@ class epicsShareClass PvaClient : { public: POINTER_DEFINITIONS(PvaClient); - /** * Destructor */ @@ -98,19 +97,14 @@ public: * @param providerNames Space separated list of provider names. * @return shared pointer to the single instance. */ - 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");} + static PvaClientPtr get(std::string const & providerNames = "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() EPICS_DEPRECATED { - return get("pva ca"); + return get(); } /** Get the requester name. * @return The name. @@ -136,13 +130,6 @@ public: std::string const & channelName, std::string const &providerName = "pva", double timeOut = 5.0); - /** Create an PvaClientChannel. The provider is pva. - * @param channelName The channelName. - * @return The interface. - * @throw runtime_error if connection fails. - */ - PvaClientChannelPtr createChannel(std::string const & channelName) - { return createChannel(channelName,"pva");} /** Create an PvaClientChannel with the specified provider. * @param channelName The channelName. * @param providerName The provider. @@ -151,7 +138,7 @@ public: */ PvaClientChannelPtr createChannel( std::string const & channelName, - std::string const & providerName); + std::string const & providerName = "pva"); /** Set a requester. * The default is for PvaClient to handle messages by printing to System.out. @@ -175,12 +162,7 @@ public: * @return true or false */ static bool getDebug() {return debug;} - /** Get shared pointer to this - */ - PvaClientPtr getPtrSelf() - { - return shared_from_this(); - } + /** Deprecated method * \deprecated This method will go away in future versions. */ @@ -203,7 +185,7 @@ typedef std::tr1::shared_ptr PvaClientGetCachePtr; class PvaClientPutCache; typedef std::tr1::shared_ptr PvaClientPutCachePtr; -// NOTE: must use seprate class that implements ChannelRequester, +// NOTE: must use separate class that implements ChannelRequester, // because pvAccess holds a shared_ptr to ChannelRequester instead of weak_pointer class ChannelRequesterImpl; typedef std::tr1::shared_ptr ChannelRequesterImplPtr; @@ -218,32 +200,10 @@ class epicsShareClass PvaClientChannel { public: POINTER_DEFINITIONS(PvaClientChannel); + /** + * Destructor + */ ~PvaClientChannel(); - /** ChannelRequester method - * @param status The status - * @param channel The channel - */ - void channelCreated( - const epics::pvData::Status& status, - epics::pvAccess::Channel::shared_pointer const & channel); - /** ChannelRequester method - * @param channel The channel - * @param connectionState The connection state. - */ - void channelStateChange( - epics::pvAccess::Channel::shared_pointer const & channel, - epics::pvAccess::Channel::ConnectionState connectionState); - /** ChannelRequester method - * @return The name - */ - std::string getRequesterName(); - /** ChannelRequester method - * @param message The message. - * @param messageType The message type. - */ - void message( - std::string const & message, - epics::pvData::MessageType messageType); /** Get the name of the channel to which PvaClientChannel is connected. * @return The channel name. */ @@ -264,146 +224,108 @@ public: /** Wait until the connection completes or for timeout. * @param timeout The time in seconds to wait. A value of 0 means forever. * @return status. + * @throw runtime_error if failure. */ - epics::pvData::Status waitConnect(double timeout); - /** Calls the next method with subField = ""; + epics::pvData::Status waitConnect(double timeout = 5.0); + /** Create a PvaClientField for the specified subField. + * @param subField The desired subField, i. e. "field.field...." + * An empty string, i. e. "", asks for the entire top level struture as defined by the server. * @return The interface. */ - PvaClientFieldPtr createField(); - /** Calls the next method with request = ""; - * @param subField The syntax for subField is defined in package org.epics.pvdata.copy - * @return The interface. - */ - PvaClientFieldPtr createField(std::string const & subField); - /** Create an PvaClientField for the specified subField. + PvaClientFieldPtr createField(std::string const & subField = ""); + /** First call createRequest as implemented by pvDataCPP and then call the next method. + * @param request The syntax of request is defined by the copy facility of pvData. * @return The interface. * @throw runtime_error if failure. */ - PvaClientProcessPtr createProcess(); - /** First call createRequest as implemented by pvDataJava and then calls the next method. - * @param request The request as described in package org.epics.pvdata.copy - * @return The interface. - * @throw runtime_error if failure. - */ - PvaClientProcessPtr createProcess(std::string const & request); + PvaClientProcessPtr createProcess(std::string const & request = ""); /** Creates an PvaClientProcess. - * @param pvRequest The syntax of pvRequest is described in package org.epics.pvdata.copy. + * @param pvRequest The syntax of pvRequest is defined by the copy facility of pvData. * @return The interface. * @throw runtime_error if failure. */ PvaClientProcessPtr createProcess(epics::pvData::PVStructurePtr const & pvRequest); - /** Call the next method with request = "field(value,alarm,timeStamp)" - * @return The interface. - * @throw runtime_error if failure. - */ - PvaClientGetPtr get(); /** Get a cached PvaClientGet or create and connect to a new PvaClientGet. - * Then call it's get method. * If connection can not be made an exception is thrown. - * @param request The request as described in package org.epics.pvdata.copy + * @param request The syntax of request is defined by the copy facility of pvData. * @return The interface. * @throw runtime_error if failure. */ - PvaClientGetPtr get(std::string const & request); - /** Call the next method with request = "field(value,alarm,timeStamp)" - * @return The interface. - * @throw runtime_error if failure. - */ - PvaClientGetPtr createGet(); + PvaClientGetPtr get(std::string const & request = "field(value,alarm,timeStamp)"); /** First call createRequest as implemented by pvDataJava and then call the next method. - * @param request The request as described in package org.epics.pvdata.copy + * Then get a cached PvaClientGet or create and connect to a new PvaClientGet. + * @param request The syntax of request is defined by the copy facility of pvData. * @return The interface. * @throw runtime_error if failure. */ - PvaClientGetPtr createGet(std::string const & request); + PvaClientGetPtr createGet(std::string const & request = "field(value,alarm,timeStamp)"); /** Creates an PvaClientGet. - * @param pvRequest The syntax of pvRequest is described in package org.epics.pvdata.copy. + * @param pvRequest The syntax of pvRequest is defined by the copy facility of pvData. * @return The interface. * @throw runtime_error if failure. */ PvaClientGetPtr createGet(epics::pvData::PVStructurePtr const & pvRequest); - /** Call the next method with request = "field(value)" - * @return The interface. - * @throw runtime_error if failure. - */ - PvaClientPutPtr put(); - /** get a cached PvaClientPut or create and connect to a new PvaClientPut. - * Then call it's get method. - * @param request The request as described in package org.epics.pvdata.copy + /** First call createRequest as implemented by pvDataJava. + * Then get a cached PvaClientPut or create and connect to a new PvaClientPut. + * Then call it's get method. + * @param request The syntax of request is defined by the copy facility of pvData. * @return The interface. * @throw runtime_error if connection fails */ - PvaClientPutPtr put(std::string const & request); - /** Call the next method with request = "field(value)" + PvaClientPutPtr put(std::string const & request = "field(value)"); + /** First call createRequest as implemented by pvDataJava and then call the next method. + * @param request The syntax of request is defined by the copy facility of pvData. * @return The interface. * @throw runtime_error if failure. */ - PvaClientPutPtr createPut(); - /** First call createRequest as implemented by pvDataJava and then calls the next method. - * @param request The request as described in package org.epics.pvdata.copy - * @return The interface. - * @throw runtime_error if failure. - */ - PvaClientPutPtr createPut(std::string const & request); + PvaClientPutPtr createPut(std::string const & request = "field(value)"); /** Create an PvaClientPut. - * @param pvRequest The syntax of pvRequest is described in package org.epics.pvdata.copy. + * @param pvRequest The syntax of pvRequest is defined by the copy facility of pvData. * @return The interface. */ PvaClientPutPtr createPut(epics::pvData::PVStructurePtr const & pvRequest); - /** Call the next method with request = "record[process=true]putField(argument)getField(result)". - * @return The interface. - * @throw runtime_error if failure. - */ - PvaClientPutGetPtr createPutGet(); /** First call createRequest as implemented by pvDataJava and then calls the next method. - * @param request The request as described in package org.epics.pvdata.copy + * @param request The syntax of request is defined by the copy facility of pvData. * @return The interface. * @throw runtime_error if failure. */ - PvaClientPutGetPtr createPutGet(std::string const & request); + PvaClientPutGetPtr createPutGet( + std::string const & request = "putField(argument)getField(result)"); /** Create an PvaClientPutGet. - * @param pvRequest The syntax of pvRequest is described in package org.epics.pvdata.copy. + * @param pvRequest The syntax of pvRequest is defined by the copy facility of pvData. * @return The interface. */ PvaClientPutGetPtr createPutGet(epics::pvData::PVStructurePtr const & pvRequest); - /** Call the next method with request = "field(value)"; - * @return The interface. - */ - PvaClientArrayPtr createArray(); /** First call createRequest as implemented by pvDataJava and then call the next method. - * @param request The request as described in package org.epics.pvdata.copy + * @param request The syntax of request is defined by the copy facility of pvData. * @return The interface. * @throw runtime_error if failure. */ - PvaClientArrayPtr createArray(std::string const & request); + PvaClientArrayPtr createArray(std::string const & request = "field(value)"); /** Create an PvaClientArray. - * @param pvRequest The syntax of pvRequest is described in package org.epics.pvdata.copy. + * @param pvRequest The syntax of pvRequest is defined by the copy facility of pvData. * @return The interface. + * @throw runtime_error if failure. */ PvaClientArrayPtr createArray(epics::pvData::PVStructurePtr const & pvRequest); - /** Call the next method with request = "field(value,alarm,timeStamp)" - * @return The interface. - * @throw runtime_error if failure. - */ - PvaClientMonitorPtr monitor(); /** Create and connect to a new PvaClientMonitor. * Then call it's start method. * If connection can not be made an exception is thrown. - * @param request The request as described in package org.epics.pvdata.copy + * @param request The syntax of request is defined by the copy facility of pvData. * @return The interface. + * @throw runtime_error if failure. */ - PvaClientMonitorPtr monitor(std::string const & request); + PvaClientMonitorPtr monitor(std::string const & request = "field(value,alarm,timeStamp)"); /** Call the next method with request = "field(value,alarm,timeStamp)" * @param pvaClientMonitorRequester The client callback. * @return The interface. * @throw runtime_error if failure. */ PvaClientMonitorPtr monitor(PvaClientMonitorRequesterPtr const & pvaClientMonitorRequester); - /** Create and connect to a new PvaClientMonitor. * Then call it's start method. * If connection can not be made an exception is thrown. - * @param request The request as described in package org.epics.pvdata.copy + * @param request The syntax of request is defined by the copy facility of pvData. * @param pvaClientMonitorRequester The client callback. * @return The interface. * @throw runtime_error if failure. @@ -411,19 +333,16 @@ public: PvaClientMonitorPtr monitor( std::string const & request, PvaClientMonitorRequesterPtr const & pvaClientMonitorRequester); - /** Call the next method with request = "field(value.alarm,timeStamp)" - * @return The interface. - */ - PvaClientMonitorPtr createMonitor(); /** * @brief First call createRequest as implemented by pvDataJava and then calls the next method. - * @param request The request as described in package org.epics.pvdata.copy + * @param request The syntax of request is defined by the copy facility of pvData. * @return The interface. * @throw runtime_error if failure. */ - PvaClientMonitorPtr createMonitor(std::string const & request); + PvaClientMonitorPtr createMonitor( + std::string const & request = "field(value,alarm,timeStamp)"); /** Create an PvaClientMonitor. - * @param pvRequest The syntax of pvRequest is described in package org.epics.pvdata.copy. + * @param pvRequest The syntax of pvRequest is defined by the copy facility of pvData. * @return The interface. * @throw runtime_error if failure. */ @@ -439,7 +358,18 @@ public: */ void destroy() EPICS_DEPRECATED {} private: - + //ChannelRequester methods + void channelCreated( + const epics::pvData::Status& status, + epics::pvAccess::Channel::shared_pointer const & channel); + void channelStateChange( + epics::pvAccess::Channel::shared_pointer const & channel, + epics::pvAccess::Channel::ConnectionState connectionState); + std::string getRequesterName(); + void message( + std::string const & message, + epics::pvData::MessageType messageType); + static PvaClientChannelPtr create( PvaClientPtr const &pvaClient, std::string const & channelName, @@ -466,6 +396,7 @@ private: epics::pvAccess::Channel::shared_pointer channel; ChannelRequesterImplPtr channelRequester; friend class PvaClient; + friend class ChannelRequesterImpl; }; /** @@ -476,29 +407,38 @@ class epicsShareClass PvaClientGetData { public: POINTER_DEFINITIONS(PvaClientGetData); + /** + * Destructor + */ ~PvaClientGetData() {} /** Set a prefix for throw messages. + * This is called by other pvaClient classes. * @param value The prefix. */ void setMessagePrefix(std::string const & value); /** Get the structure. + * @return The Structure + * @throw runtime_error if failure. */ epics::pvData::StructureConstPtr getStructure(); /** Get the pvStructure. * @return the pvStructure. + * @throw runtime_error if failure. */ epics::pvData::PVStructurePtr getPVStructure(); - /** Get the BitSet for the pvStructure - * This shows which fields have changed value. + /** Get the changed BitSet for the pvStructure + * This shows which fields have changed value since the last get. * @return The bitSet + * @throw runtime_error if failure */ epics::pvData::BitSetPtr getChangedBitSet(); - /** Show the fields that have changed. + /** Show the fields that have changed value since the last get. * @param out The stream that shows the changed fields. - * @return The stream that was input + * @return The stream that was passed as out. */ std::ostream & showChanged(std::ostream & out); /** New data is present. + * This is called by other pvaClient classes, i. e. not by client. * @param pvStructureFrom The new data. * @param bitSetFrom the bitSet showing which values have changed. */ @@ -518,7 +458,8 @@ public: */ bool isValueScalarArray(); /** Get the interface to the value field. - * @return The interface. an excetion is thrown if a value field does not exist. + * @return The interface. + * @throw runtime_error if failure. */ epics::pvData::PVFieldPtr getValue(); /** @@ -527,7 +468,7 @@ public: * @throw runtime_error if failure. */ epics::pvData::PVScalarPtr getScalarValue(); - /** Getthe interface to an array value field. + /** Get the interface to an array value field. * @return The interface. * @throw runtime_error if failure. */ @@ -538,8 +479,8 @@ public: */ std::tr1::shared_ptr getScalarArrayValue(); /** Get the value as a double. - * @throw runtime_error if failure. * @return The value. + * @throw runtime_error if failure. */ double getDouble(); /** Get the value as a string. @@ -558,20 +499,22 @@ public: */ epics::pvData::shared_vector getStringArray(); /** Get the alarm. - * If the pvStructure as an alarm field it's values are returned. - * If no then alarm shows that no alarm defined. + * If the pvStructure has an alarm field it's values are returned. + * Otherwise an exception is thrown. * @return The alarm. + * @throw runtime_error if failure. */ epics::pvData::Alarm getAlarm(); /** Get the timeStamp. - * If the pvStructure as a timeStamp field, it's values are returned. - * If no then all fields are 0. + * If the pvStructure has a timeStamp field, it's values are returned. + * Otherwise an exception is thrown. * @return The timeStamp. */ epics::pvData::TimeStamp getTimeStamp(); /** Factory method for creating an instance of PvaClientGetData. * NOTE: Not normally called by clients * @param structure Introspection interface + * @throw runtime_error if failure. */ static PvaClientGetDataPtr create(epics::pvData::StructureConstPtr const & structure); private: @@ -598,28 +541,33 @@ class epicsShareClass PvaClientPutData { public: POINTER_DEFINITIONS(PvaClientPutData); - + /** + * Destructor + */ ~PvaClientPutData() {} /** Set a prefix for throw messages. * @param value The prefix. */ void setMessagePrefix(std::string const & value); - /** Get the structure. - * @return the structure. + /** Get the structure. + * @return The Structure + * @throw runtime_error if failure. */ epics::pvData::StructureConstPtr getStructure(); - /** Get the pvStructure. - * @return the pvStructure. - */ - epics::pvData::PVStructurePtr getPVStructure(); - /** Get the BitSet for the pvStructure - * This shows which fields have changed value. + /** Get the pvStructure. + * @return the pvStructure. + * @throw runtime_error if failure. + */ + epics::pvData::PVStructurePtr getPVStructure(); + /** Get the changed BitSet for the pvStructure + * This shows which fields have changed values. * @return The bitSet + * @throw runtime_error if failure. */ epics::pvData::BitSetPtr getChangedBitSet(); - /** Show the fields that have changed. + /** Show the fields that have changed values. * @param out The stream that shows the changed fields. - * @return The stream that was input + * @return The stream that was passed as out. */ std::ostream & showChanged(std::ostream & out); /** @@ -729,38 +677,44 @@ class epicsShareClass PvaClientMonitorData { public: POINTER_DEFINITIONS(PvaClientMonitorData); - + /** + * Destructor + */ ~PvaClientMonitorData() {} /** Set a prefix for throw messages. * @param value The prefix. */ void setMessagePrefix(std::string const & value); - /** Get the structure. - * @return the structure. - */ - epics::pvData::StructureConstPtr getStructure(); - /** Get the pvStructure. + /** Get the structure. + * @return The Structure + * @throw runtime_error if failure. + */ + epics::pvData::StructureConstPtr getStructure(); + /** Get the pvStructure. * @return the pvStructure. + * @throw runtime_error if failure. */ epics::pvData::PVStructurePtr getPVStructure(); - /** Get the BitSet for the pvStructure + /** Get the changed BitSet for the pvStructure * This shows which fields have changed value. * @return The bitSet + * @throw runtime_error if failure. */ epics::pvData::BitSetPtr getChangedBitSet(); /** Get the overrun BitSet for the pvStructure * This shows which fields have had more than one change. * @return The bitSet + * @throw runtime_error if failure. */ epics::pvData::BitSetPtr getOverrunBitSet(); /** Show the fields that have changed. * @param out The stream that shows the changed fields. - * @return The stream that was input + * @return The stream that was passed as out. */ std::ostream & showChanged(std::ostream & out); /** Show the fields that have overrun. * @param out The stream that shows the overrun fields. - * @return The stream that was input + * @return The stream that was passed as out */ std::ostream & showOverrun(std::ostream & out); /** Is there a top level field named value. @@ -859,15 +813,17 @@ private: friend class PvaClientMonitor; }; + +// NOTE: must use separate class that implements ChannelProcessRequester, +// because pvAccess holds a shared_ptr to ChannelProcessRequester instead of weak_pointer +class ChannelProcessRequesterImpl; +typedef std::tr1::shared_ptr ChannelProcessRequesterImplPtr; + /** * @brief An easy to use alternative to ChannelProcess. * * @author mrk */ -// NOTE: must use seprate class that implements ChannelProcessRequester, -// because pvAccess holds a shared_ptr to ChannelProcessRequester instead of weak_pointer -class ChannelProcessRequesterImpl; -typedef std::tr1::shared_ptr ChannelProcessRequesterImplPtr; class epicsShareClass PvaClientProcess { public: @@ -886,7 +842,6 @@ public: /** Destructor */ ~PvaClientProcess(); - /** Call issueConnect and then waitConnect. * An exception is thrown if connect fails. * @throw runtime_error if failure. @@ -952,15 +907,15 @@ private: friend class ChannelProcessRequesterImpl; }; +// NOTE: must use separate class that implements ChannelGetRequester, +// because pvAccess holds a shared_ptr to ChannelGetRequester instead of weak_pointer +class ChannelGetRequesterImpl; +typedef std::tr1::shared_ptr ChannelGetRequesterImplPtr; /** * @brief An easy to use alternative to ChannelGet. * * @author mrk */ -// NOTE: must use seprate class that implements ChannelGetRequester, -// because pvAccess holds a shared_ptr to ChannelGetRequester instead of weak_pointer -class ChannelGetRequesterImpl; -typedef std::tr1::shared_ptr ChannelGetRequesterImplPtr; class epicsShareClass PvaClientGet { public: @@ -1056,15 +1011,17 @@ private: friend class ChannelGetRequesterImpl; }; + +// NOTE: must use separate class that implements ChannelPutRequester, +// because pvAccess holds a shared_ptr to ChannelPutRequester instead of weak_pointer +class ChannelPutRequesterImpl; +typedef std::tr1::shared_ptr ChannelPutRequesterImplPtr; + /** * @brief An easy to use alternative to ChannelPut. * * @author mrk */ -// NOTE: must use seprate class that implements ChannelPutRequester, -// because pvAccess holds a shared_ptr to ChannelPutRequester instead of weak_pointer -class ChannelPutRequesterImpl; -typedef std::tr1::shared_ptr ChannelPutRequesterImplPtr; class epicsShareClass PvaClientPut { public: @@ -1153,7 +1110,7 @@ private : enum PutConnectState {connectIdle,connectActive,connected}; PvaClient::weak_pointer pvaClient; - epics::pvAccess::Channel::shared_pointer channel; + epics::pvAccess::Channel::weak_pointer channel; epics::pvData::PVStructurePtr pvRequest; epics::pvData::Mutex mutex; epics::pvData::Event waitForConnect; @@ -1172,15 +1129,16 @@ private : friend class ChannelPutRequesterImpl; }; +// NOTE: must use separate class that implements ChannelPutGetRequester, +// because pvAccess holds a shared_ptr to ChannelPutGetRequester instead of weak_pointer +class ChannelPutGetRequesterImpl; +typedef std::tr1::shared_ptr ChannelPutGetRequesterImplPtr; + /** * @brief An easy to use alternative to ChannelPutGet. * * @author mrk */ -// NOTE: must use seprate class that implements ChannelPutGetRequester, -// because pvAccess holds a shared_ptr to ChannelPutGetRequester instead of weak_pointer -class ChannelPutGetRequesterImpl; -typedef std::tr1::shared_ptr ChannelPutGetRequesterImplPtr; class epicsShareClass PvaClientPutGet { public: @@ -1293,7 +1251,7 @@ private : enum PutGetConnectState {connectIdle,connectActive,connected}; PvaClient::weak_pointer pvaClient; - epics::pvAccess::Channel::shared_pointer channel; + epics::pvAccess::Channel::weak_pointer channel; epics::pvData::PVStructurePtr pvRequest; epics::pvData::Mutex mutex; epics::pvData::Event waitForConnect; @@ -1329,14 +1287,16 @@ public: virtual void event(PvaClientMonitorPtr const & monitor) = 0; }; + +// NOTE: must use separate class that implements MonitorRequester, +// because pvAccess holds a shared_ptr to MonitorRequester instead of weak_pointer +class MonitorRequesterImpl; +typedef std::tr1::shared_ptr MonitorRequesterImplPtr; + /** * @brief An easy to use alternative to Monitor. * */ -// NOTE: must use seprate class that implements MonitorRequester, -// because pvAccess holds a shared_ptr to MonitorRequester instead of weak_pointer -class MonitorRequesterImpl; -typedef std::tr1::shared_ptr MonitorRequesterImplPtr; class epicsShareClass PvaClientMonitor : public std::tr1::enable_shared_from_this { @@ -1356,8 +1316,6 @@ public: /** Destructor */ ~PvaClientMonitor(); - - /** Call issueConnect and then waitConnect. * An exception is thrown if connect fails. */ @@ -1423,7 +1381,7 @@ private: enum MonitorConnectState {connectIdle,connectActive,connected,monitorStarted}; PvaClient::weak_pointer pvaClient; - epics::pvAccess::Channel::shared_pointer channel; + epics::pvAccess::Channel::weak_pointer channel; epics::pvData::PVStructurePtr pvRequest; epics::pvData::Mutex mutex; epics::pvData::Event waitForConnect; diff --git a/src/pv/pvaClientMultiChannel.h b/src/pv/pvaClientMultiChannel.h index 8e30285..20e8537 100644 --- a/src/pv/pvaClientMultiChannel.h +++ b/src/pv/pvaClientMultiChannel.h @@ -79,7 +79,6 @@ public: * Destructor */ ~PvaClientMultiChannel(); - /** Get the channelNames. * @return The names. */ @@ -131,37 +130,20 @@ public: * @return The interface. */ PvaClientNTMultiPutPtr createNTPut(); - /** - * Create a pvaClientNTMultiGet. - * This calls the next method with request = "value,alarm,timeStamp" - * @return The interface. - */ - PvaClientNTMultiGetPtr createNTGet(); /** * Create a pvaClientNTMultiGet; * @param request The request for each channel. * @return The interface. */ - PvaClientNTMultiGetPtr createNTGet(std::string const &request); - /** - * Create a pvaClientNTMultiMonitor. - * This calls the next method with request = "value,alarm,timeStamp" - * @return The interface. - */ - PvaClientNTMultiMonitorPtr createNTMonitor(); + PvaClientNTMultiGetPtr createNTGet( + std::string const &request = "field(value,alarm,timeStamp)"); /** * Create a pvaClientNTMultiPut. * @param request The request for each channel. * @return The interface. */ - PvaClientNTMultiMonitorPtr createNTMonitor(std::string const &request); - /** Get the shared pointer to self. - * @return The shared pointer. - */ - PvaClientMultiChannelPtr getPtrSelf() - { - return shared_from_this(); - } + PvaClientNTMultiMonitorPtr createNTMonitor( + std::string const &request= "field(value,alarm,timeStamp)"); /** Deprecated method * \deprecated This method will go away in future versions. */ @@ -258,14 +240,13 @@ class epicsShareClass PvaClientMultiPutDouble : public: POINTER_DEFINITIONS(PvaClientMultiPutDouble); - /** - * Factory method that creates a PvaClientMultiPutDouble. + /** Factory method that creates a PvaClientMultiPutDouble. * @param pvaClientMultiChannel The interface to PvaClientMultiChannel. * @param pvaClientChannelArray The PvaClientChannel array. * @return The interface. */ static PvaClientMultiPutDoublePtr create( - PvaClientMultiChannelPtr const &pvaMultiChannel, + PvaClientMultiChannelPtr const &pvaClientMultiChannel, PvaClientChannelArray const &pvaClientChannelArray); ~PvaClientMultiPutDouble(); /** @@ -312,14 +293,13 @@ class epicsShareClass PvaClientMultiMonitorDouble : public: POINTER_DEFINITIONS(PvaClientMultiMonitorDouble); - /** - * Factory method that creates a PvaClientMultiMonitorDouble. + /** Factory method that creates a PvaClientMultiMonitorDouble. * @param pvaClientMultiChannel The interface to PvaClientMultiChannel. * @param pvaClientChannelArray The PvaClientChannel array. * @return The interface. */ static PvaClientMultiMonitorDoublePtr create( - PvaClientMultiChannelPtr const &pvaMultiChannel, + PvaClientMultiChannelPtr const &pvaClientMultiChannel, PvaClientChannelArray const &pvaClientChannelArray); ~PvaClientMultiMonitorDouble(); /** @@ -507,15 +487,14 @@ class epicsShareClass PvaClientNTMultiMonitor : public: POINTER_DEFINITIONS(PvaClientNTMultiMonitor); - /** - * Factory method that creates a PvaClientNTMultiMonitor. + /** Factory method that creates a PvaClientNTMultiMonitor. * @param pvaClientMultiChannel The interface to PvaClientMultiChannel. * @param pvaClientChannelArray The PvaClientChannel array. * @param pvRequest The pvRequest for each channel. * @return The interface. */ static PvaClientNTMultiMonitorPtr create( - PvaClientMultiChannelPtr const &pvaNTMultiChannel, + PvaClientMultiChannelPtr const &pvaClientMultiChannel, PvaClientChannelArray const &pvaClientChannelArray, epics::pvData::PVStructurePtr const & pvRequest); ~PvaClientNTMultiMonitor(); @@ -589,7 +568,7 @@ public: */ static PvaClientNTMultiDataPtr create( epics::pvData::UnionConstPtr const & u, - PvaClientMultiChannelPtr const &pvaNTMultiChannel, + PvaClientMultiChannelPtr const &pvaClientMultiChannel, PvaClientChannelArray const &pvaClientChannelArray, epics::pvData::PVStructurePtr const & pvRequest); ~PvaClientNTMultiData(); diff --git a/src/pvaClient.cpp b/src/pvaClient.cpp index 4567070..8416970 100644 --- a/src/pvaClient.cpp +++ b/src/pvaClient.cpp @@ -128,14 +128,14 @@ PvaClient::PvaClient(std::string const & providerNames) } PvaClient::~PvaClient() { - if(PvaClient::debug) cout<< "PvaClient::~PvaClient()\n"; { Lock xx(mutex); if(isDestroyed) throw std::runtime_error("pvaClient was destroyed"); isDestroyed = true; } if(PvaClient::debug) { - cout << "pvaChannel cache:\n"; + cout<< "PvaClient::~PvaClient()\n" + << "pvaChannel cache:\n"; showCache(); } if(pvaStarted){ @@ -188,7 +188,7 @@ PvaClientChannelPtr PvaClient::channel( PvaClientChannelPtr PvaClient::createChannel(string const & channelName, string const & providerName) { - return PvaClientChannel::create(getPtrSelf(),channelName,providerName); + return PvaClientChannel::create(shared_from_this(),channelName,providerName); } void PvaClient::setRequester(RequesterPtr const & requester) diff --git a/src/pvaClientChannel.cpp b/src/pvaClientChannel.cpp index 542e29e..45229c7 100644 --- a/src/pvaClientChannel.cpp +++ b/src/pvaClientChannel.cpp @@ -200,17 +200,16 @@ PvaClientChannel::PvaClientChannel( PvaClientChannel::~PvaClientChannel() { - if(PvaClient::getDebug()) { - cout << "PvaClientChannel::~PvaClientChannel() " - << " channelName " << channelName - << " this " << this << " channel " << channel - << endl; - } { Lock xx(mutex); if(isDestroyed) throw std::runtime_error("pvaClientChannel was destroyed"); isDestroyed = true; } + if(PvaClient::getDebug()) { + cout << "PvaClientChannel::~PvaClientChannel() " + << " channelName " << channelName + << endl; + } if(PvaClient::getDebug()) showCache(); pvaClientGetCache.reset(); pvaClientPutCache.reset(); @@ -354,10 +353,6 @@ Status PvaClientChannel::waitConnect(double timeout) return Status(Status::STATUSTYPE_ERROR,channelName + " not connected"); } -PvaClientFieldPtr PvaClientChannel::createField() -{ - return createField(""); -} PvaClientFieldPtr PvaClientChannel::createField(string const & subField) { @@ -365,11 +360,6 @@ PvaClientFieldPtr PvaClientChannel::createField(string const & subField) throw std::runtime_error("PvaClientChannel::createField not implemented"); } -PvaClientProcessPtr PvaClientChannel::createProcess() -{ - return createProcess(""); -} - PvaClientProcessPtr PvaClientChannel::createProcess(string const & request) { PVStructurePtr pvRequest = createRequest->createRequest(request); @@ -390,7 +380,6 @@ PvaClientProcessPtr PvaClientChannel::createProcess(PVStructurePtr const & pvRe return PvaClientProcess::create(yyy,channel,pvRequest); } -PvaClientGetPtr PvaClientChannel::get() {return get("value,alarm,timeStamp");} PvaClientGetPtr PvaClientChannel::get(string const & request) { @@ -402,10 +391,6 @@ PvaClientGetPtr PvaClientChannel::get(string const & request) return pvaClientGet; } -PvaClientGetPtr PvaClientChannel::createGet() -{ - return PvaClientChannel::createGet("value,alarm,timeStamp"); -} PvaClientGetPtr PvaClientChannel::createGet(string const & request) { @@ -427,7 +412,6 @@ PvaClientGetPtr PvaClientChannel::createGet(PVStructurePtr const & pvRequest) return PvaClientGet::create(yyy,channel,pvRequest); } -PvaClientPutPtr PvaClientChannel::put() {return put("value");} PvaClientPutPtr PvaClientChannel::put(string const & request) { @@ -440,10 +424,6 @@ PvaClientPutPtr PvaClientChannel::put(string const & request) return pvaClientPut; } -PvaClientPutPtr PvaClientChannel::createPut() -{ - return createPut("value"); -} PvaClientPutPtr PvaClientChannel::createPut(string const & request) { @@ -465,11 +445,6 @@ PvaClientPutPtr PvaClientChannel::createPut(PVStructurePtr const & pvRequest) return PvaClientPut::create(yyy,channel,pvRequest); } -PvaClientPutGetPtr PvaClientChannel::createPutGet() -{ - return createPutGet("putField(argument)getField(result)"); -} - PvaClientPutGetPtr PvaClientChannel::createPutGet(string const & request) { PVStructurePtr pvRequest = createRequest->createRequest(request); @@ -491,10 +466,6 @@ PvaClientPutGetPtr PvaClientChannel::createPutGet(PVStructurePtr const & pvReque } -PvaClientArrayPtr PvaClientChannel::createArray() -{ - return createArray("value"); -} PvaClientArrayPtr PvaClientChannel::createArray(string const & request) { @@ -515,11 +486,6 @@ PvaClientArrayPtr PvaClientChannel::createArray(PVStructurePtr const & pvReques } -PvaClientMonitorPtr PvaClientChannel::monitor() -{ - return monitor("value,alarm,timeStamp"); -} - PvaClientMonitorPtr PvaClientChannel::monitor(string const & request) { PvaClientMonitorPtr pvaClientMonitor = createMonitor(request); @@ -543,11 +509,6 @@ PvaClientMonitorPtr PvaClientChannel::monitor(string const & request, return pvaClientMonitor; } -PvaClientMonitorPtr PvaClientChannel::createMonitor() -{ - return createMonitor("value,alarm,timeStamp"); -} - PvaClientMonitorPtr PvaClientChannel::createMonitor(string const & request) { PVStructurePtr pvRequest = createRequest->createRequest(request); diff --git a/src/pvaClientGet.cpp b/src/pvaClientGet.cpp index 5ed4438..3401282 100644 --- a/src/pvaClientGet.cpp +++ b/src/pvaClientGet.cpp @@ -94,17 +94,29 @@ PvaClientGet::PvaClientGet( connectState(connectIdle), getState(getIdle) { - if(PvaClient::getDebug()) cout<< "PvaClientGet::PvaClientGet\n"; + if(PvaClient::getDebug()) { + cout << "PvaClientGet::PvaClientGet::PvaClientGet" + << " channelName " << channel->getChannelName() + << endl; + } } PvaClientGet::~PvaClientGet() { - if(PvaClient::getDebug()) cout<< "PvaClientGet::~PvaClientGet()\n"; { Lock xx(mutex); if(isDestroyed) throw std::runtime_error("pvaClientGet was destroyed"); isDestroyed = true; } + if(PvaClient::getDebug()) { + string channelName("disconnected"); + Channel::shared_pointer chan(channel.lock()); + if(chan) channelName = chan->getChannelName(); + cout<< "PvaClientGet::~PvaClientGet" + << " channelName " << channelName + << endl; + } + if(channelGet) channelGet->destroy(); } void PvaClientGet::checkGetState() @@ -117,7 +129,7 @@ void PvaClientGet::checkGetState() string PvaClientGet::getRequesterName() { PvaClientPtr yyy = pvaClient.lock(); - if(!yyy) return string("PvaClientGet::getRequesterName() PvaClient isDestroyed"); + if(!yyy) return string("PvaClientGet::getRequesterName PvaClient isDestroyed"); return yyy->getRequesterName(); } @@ -134,7 +146,11 @@ void PvaClientGet::channelGetConnect( StructureConstPtr const & structure) { if(PvaClient::getDebug()) { + string channelName("disconnected"); + Channel::shared_pointer chan(channel.lock()); + if(chan) channelName = chan->getChannelName(); cout << "PvaClientGet::channelGetConnect" + << " channelName " << channelGet->getChannel()->getChannelName() << " status.isOK " << (status.isOK() ? "true" : "false") << endl; } @@ -145,8 +161,7 @@ void PvaClientGet::channelGetConnect( this->channelGet = channelGet; if(status.isOK()) { pvaClientData = PvaClientGetData::create(structure); - Channel::shared_pointer chan(channel.lock()); - if(chan) pvaClientData->setMessagePrefix(chan->getChannelName()); + pvaClientData->setMessagePrefix(channelGet->getChannel()->getChannelName()); } } waitForConnect.signal(); @@ -160,14 +175,17 @@ void PvaClientGet::getDone( BitSetPtr const & bitSet) { if(PvaClient::getDebug()) { + string channelName("disconnected"); + Channel::shared_pointer chan(channel.lock()); + if(chan) channelName = chan->getChannelName(); cout << "PvaClientGet::getDone" + << " channelName " << channelName << " status.isOK " << (status.isOK() ? "true" : "false") << endl; } { Lock xx(mutex); channelGetStatus = status; - getState = getComplete; if(status.isOK()) { pvaClientData->setData(pvStructure,bitSet); } @@ -220,7 +238,7 @@ Status PvaClientGet::waitConnect() string channelName("disconnected"); if(chan) channelName = chan->getChannelName(); string message = string("channel ") + channelName - + " pvaClientGet illegal connect state "; + + " PvaClientGet::waitConnect illegal connect state "; throw std::runtime_error(message); } } diff --git a/src/pvaClientMonitor.cpp b/src/pvaClientMonitor.cpp index 34e716d..b367185 100644 --- a/src/pvaClientMonitor.cpp +++ b/src/pvaClientMonitor.cpp @@ -101,40 +101,52 @@ PvaClientMonitor::PvaClientMonitor( userPoll(false), userWait(false) { - if(PvaClient::getDebug()) cout<< "PvaClientMonitor::PvaClientMonitor()\n"; + if(PvaClient::getDebug()) { + cout<< "PvaClientMonitor::PvaClientMonitor()" + << " channelName " << channel->getChannelName() + << endl; + } } PvaClientMonitor::~PvaClientMonitor() { - if(PvaClient::getDebug()) cout<< "PvaClientMonitor::~PvaClientMonitor()\n"; + if(PvaClient::getDebug()) cout<< "PvaClientMonitor::~PvaClientMonitor\n"; { Lock xx(mutex); if(isDestroyed) throw std::runtime_error("pvaClientMonitor was destroyed"); isDestroyed = true; } - if(monitor) monitor->destroy(); + if(PvaClient::getDebug()) { + string channelName("disconnected"); + Channel::shared_pointer chan(channel.lock()); + if(chan) channelName = chan->getChannelName(); + cout<< "PvaClientMonitor::~PvaClientMonitor" + << " channelName " << channelName + << endl; + } + if(monitor) { + if(connectState==monitorStarted) monitor->stop(); + monitor->destroy(); + } } void PvaClientMonitor::checkMonitorState() { - if(PvaClient::getDebug()) cout<< "PvaClientMonitor::checkMonitorState()\n"; if(connectState==connectIdle) connect(); if(connectState==connected) start(); } string PvaClientMonitor::getRequesterName() { - if(PvaClient::getDebug()) cout<< "PvaClientMonitor::getRequesterName()\n"; PvaClientPtr yyy = pvaClient.lock(); - if(!yyy) throw std::runtime_error("pvaClient was destroyed"); + if(!yyy) return string("PvaClientMonitor::getRequesterName() PvaClient isDestroyed"); return yyy->getRequesterName(); } void PvaClientMonitor::message(string const & message,MessageType messageType) { - if(PvaClient::getDebug()) cout<< "PvaClientMonitor::message()\n"; PvaClientPtr yyy = pvaClient.lock(); - if(!yyy) throw std::runtime_error("pvaClient was destroyed"); + if(!yyy) return; yyy->message(message, messageType); } @@ -143,13 +155,22 @@ void PvaClientMonitor::monitorConnect( Monitor::shared_pointer const & monitor, StructureConstPtr const & structure) { - if(PvaClient::getDebug()) cout<< "PvaClientMonitor::monitorConnect()\n"; + Channel::shared_pointer chan(channel.lock()); + if(PvaClient::getDebug()) { + string channelName("disconnected"); + Channel::shared_pointer chan(channel.lock()); + if(chan) channelName = chan->getChannelName(); + cout << "PvaClientMonitor::monitorConnect" + << " channelName " << channelName + << " status.isOK " << (status.isOK() ? "true" : "false") + << endl; + } connectStatus = status; connectState = connected; this->monitor = monitor; - if(status.isOK()) { + if(status.isOK() && chan) { pvaClientData = PvaClientMonitorData::create(structure); - pvaClientData->setMessagePrefix(channel->getChannelName()); + pvaClientData->setMessagePrefix(chan->getChannelName()); } waitForConnect.signal(); @@ -157,7 +178,14 @@ void PvaClientMonitor::monitorConnect( void PvaClientMonitor::monitorEvent(MonitorPtr const & monitor) { - if(PvaClient::getDebug()) cout<< "PvaClientMonitor::monitorEvent()\n"; + if(PvaClient::getDebug()) { + string channelName("disconnected"); + Channel::shared_pointer chan(channel.lock()); + if(chan) channelName = chan->getChannelName(); + cout << "PvaClientMonitor::monitorEvent" + << " channelName " << channelName + << endl; + } PvaClientMonitorRequesterPtr req = pvaClientMonitorRequester.lock(); if(req) req->event(shared_from_this()); if(userWait) waitForEvent.signal(); @@ -171,37 +199,51 @@ void PvaClientMonitor::unlisten(MonitorPtr const & monitor) void PvaClientMonitor::connect() { - if(PvaClient::getDebug()) cout << "PvaClientMonitor::connect\n"; issueConnect(); Status status = waitConnect(); if(status.isOK()) return; - string message = string("channel ") + channel->getChannelName() - + " PvaClientMonitor::connect " + status.getMessage(); + Channel::shared_pointer chan(channel.lock()); + string channelName("disconnected"); + if(chan) channelName = chan->getChannelName(); + string message = string("channel ") + + channelName + + " PvaClientMonitor::connect " + + status.getMessage(); throw std::runtime_error(message); } void PvaClientMonitor::issueConnect() { - if(PvaClient::getDebug()) cout << "PvaClientMonitor::issueConnect\n"; + Channel::shared_pointer chan(channel.lock()); if(connectState!=connectIdle) { - string message = string("channel ") + channel->getChannelName() + string channelName("disconnected"); + if(chan) channelName = chan->getChannelName(); + string message = string("channel ") + + channelName + " pvaClientMonitor already connected "; throw std::runtime_error(message); } - connectState = connectActive; - monitor = channel->createMonitor(monitorRequester,pvRequest); + if(chan) { + connectState = connectActive; + monitor = chan->createMonitor(monitorRequester,pvRequest); + return; + } + throw std::runtime_error("PvaClientMonitor::issueConnect() but channel disconnected"); } Status PvaClientMonitor::waitConnect() { - if(PvaClient::getDebug()) cout << "PvaClientMonitor::waitConnect\n"; if(connectState==connected) { if(connectStatus.isOK()) connectState = connectIdle; return connectStatus; } if(connectState!=connectActive) { - string message = string("channel ") + channel->getChannelName() - + " pvaClientMonitor illegal connect state "; + Channel::shared_pointer chan(channel.lock()); + string channelName("disconnected"); + if(chan) channelName = chan->getChannelName(); + string message = string("channel ") + + channelName + + " PvaClientMonitor::waitConnect illegal connect state "; throw std::runtime_error(message); } waitForConnect.wait(); @@ -211,16 +253,37 @@ Status PvaClientMonitor::waitConnect() void PvaClientMonitor::setRequester(PvaClientMonitorRequesterPtr const & pvaClientMonitorrRequester) { - if(PvaClient::getDebug()) cout << "PvaClientMonitor::setRequester\n"; + if(PvaClient::getDebug()) { + string channelName("disconnected"); + Channel::shared_pointer chan(channel.lock()); + if(chan) channelName = chan->getChannelName(); + cout << "PvaClientMonitor::setRequester" + << " channelName " << channelName + << endl; + } this->pvaClientMonitorRequester = pvaClientMonitorrRequester; } void PvaClientMonitor::start() { - if(PvaClient::getDebug()) cout << "PvaClientMonitor::start\n"; + if(PvaClient::getDebug()) { + string channelName("disconnected"); + Channel::shared_pointer chan(channel.lock()); + if(chan) channelName = chan->getChannelName(); + cout << "PvaClientMonitor::start" + << " channelName " << channelName + << endl; + } if(connectState==monitorStarted) return; if(connectState==connectIdle) connect(); - if(connectState!=connected) throw std::runtime_error("PvaClientMonitor::start illegal state"); + if(connectState!=connected) { + Channel::shared_pointer chan(channel.lock()); + string channelName("disconnected"); + if(chan) channelName = chan->getChannelName(); + string message = string("channel ") + channelName + + " PvaClientMonitor::start illegal state "; + throw std::runtime_error(message); + } connectState = monitorStarted; monitor->start(); } @@ -228,7 +291,14 @@ void PvaClientMonitor::start() void PvaClientMonitor::stop() { - if(PvaClient::getDebug()) cout << "PvaClientMonitor::stop\n"; + if(PvaClient::getDebug()) { + string channelName("disconnected"); + Channel::shared_pointer chan(channel.lock()); + if(chan) channelName = chan->getChannelName(); + cout << "PvaClientMonitor::stop" + << " channelName " << channelName + << endl; + } if(connectState!=monitorStarted) return; connectState = connected; monitor->stop(); @@ -236,10 +306,31 @@ void PvaClientMonitor::stop() bool PvaClientMonitor::poll() { - if(PvaClient::getDebug()) cout << "PvaClientMonitor::poll\n"; + if(PvaClient::getDebug()) { + string channelName("disconnected"); + Channel::shared_pointer chan(channel.lock()); + if(chan) channelName = chan->getChannelName(); + cout << "PvaClientMonitor::poll" + << " channelName " << channelName + << endl; + } checkMonitorState(); - if(connectState!=monitorStarted) throw std::runtime_error("PvaClientMonitor::poll illegal state"); - if(userPoll) throw std::runtime_error("PvaClientMonitor::poll did not release last"); + if(connectState!=monitorStarted) { + string channelName("disconnected"); + Channel::shared_pointer chan(channel.lock()); + if(chan) channelName = chan->getChannelName(); + string message = string("channel ") + channelName + + " PvaClientMonitor::poll illegal state "; + throw std::runtime_error(message); + } + if(userPoll) { + string channelName("disconnected"); + Channel::shared_pointer chan(channel.lock()); + if(chan) channelName = chan->getChannelName(); + string message = string("channel ") + channelName + + " PvaClientMonitor::poll did not release last"; + throw std::runtime_error(message); + } monitorElement = monitor->poll(); if(!monitorElement) return false; userPoll = true; @@ -249,8 +340,22 @@ bool PvaClientMonitor::poll() bool PvaClientMonitor::waitEvent(double secondsToWait) { - if(PvaClient::getDebug()) cout << "PvaClientMonitor::waitEvent\n"; - if(connectState!=monitorStarted) throw std::runtime_error("PvaClientMonitor::waitEvent illegal state"); + if(PvaClient::getDebug()) { + string channelName("disconnected"); + Channel::shared_pointer chan(channel.lock()); + if(chan) channelName = chan->getChannelName(); + cout << "PvaClientMonitor::waitEvent" + << " channelName " << channelName + << endl; + } + if(connectState!=monitorStarted) { + Channel::shared_pointer chan(channel.lock()); + string channelName("disconnected"); + if(chan) channelName = chan->getChannelName(); + string message = string("channel ") + channelName + + " PvaClientMonitor::waitEvent illegal state "; + throw std::runtime_error(message); + } if(poll()) return true; userWait = true; if(secondsToWait==0.0) { @@ -264,17 +369,44 @@ bool PvaClientMonitor::waitEvent(double secondsToWait) void PvaClientMonitor::releaseEvent() { - if(PvaClient::getDebug()) cout << "PvaClientMonitor::releaseEvent\n"; - if(connectState!=monitorStarted) throw std::runtime_error( - "PvaClientMonitor::poll illegal state"); - if(!userPoll) throw std::runtime_error("PvaClientMonitor::releaseEvent did not call poll"); + if(PvaClient::getDebug()) { + string channelName("disconnected"); + Channel::shared_pointer chan(channel.lock()); + if(chan) channelName = chan->getChannelName(); + cout << "PvaClientMonitor::releaseEvent" + << " channelName " << channelName + << endl; + } + if(connectState!=monitorStarted) { + Channel::shared_pointer chan(channel.lock()); + string channelName("disconnected"); + if(chan) channelName = chan->getChannelName(); + string message = string("channel ") + channelName + + " PvaClientMonitor::releaseEvent monitor not started "; + throw std::runtime_error(message); + } + if(!userPoll) { + Channel::shared_pointer chan(channel.lock()); + string channelName("disconnected"); + if(chan) channelName = chan->getChannelName(); + string message = string("channel ") + channelName + + " PvaClientMonitor::releaseEvent did not call poll"; + throw std::runtime_error(message); + } userPoll = false; monitor->release(monitorElement); } PvaClientMonitorDataPtr PvaClientMonitor::getData() { - if(PvaClient::getDebug()) cout << "PvaClientMonitor::getData\n"; + if(PvaClient::getDebug()) { + string channelName("disconnected"); + Channel::shared_pointer chan(channel.lock()); + if(chan) channelName = chan->getChannelName(); + cout << "PvaClientMonitor::getData" + << " channelName " << channelName + << endl; + } checkMonitorState(); return pvaClientData; } diff --git a/src/pvaClientMultiChannel.cpp b/src/pvaClientMultiChannel.cpp index fda7035..12e638c 100644 --- a/src/pvaClientMultiChannel.cpp +++ b/src/pvaClientMultiChannel.cpp @@ -155,35 +155,30 @@ PvaClientPtr PvaClientMultiChannel::getPvaClient() PvaClientMultiGetDoublePtr PvaClientMultiChannel::createGet() { checkConnected(); - return PvaClientMultiGetDouble::create(getPtrSelf(),pvaClientChannelArray); + return PvaClientMultiGetDouble::create(shared_from_this(),pvaClientChannelArray); } PvaClientMultiPutDoublePtr PvaClientMultiChannel::createPut() { checkConnected(); - return PvaClientMultiPutDouble::create(getPtrSelf(),pvaClientChannelArray); + return PvaClientMultiPutDouble::create(shared_from_this(),pvaClientChannelArray); } PvaClientMultiMonitorDoublePtr PvaClientMultiChannel::createMonitor() { checkConnected(); - return PvaClientMultiMonitorDouble::create(getPtrSelf(), pvaClientChannelArray); + return PvaClientMultiMonitorDouble::create(shared_from_this(), pvaClientChannelArray); } PvaClientNTMultiPutPtr PvaClientMultiChannel::createNTPut() { checkConnected(); - return PvaClientNTMultiPut::create(getPtrSelf(), pvaClientChannelArray); + return PvaClientNTMultiPut::create(shared_from_this(), pvaClientChannelArray); } -PvaClientNTMultiGetPtr PvaClientMultiChannel::createNTGet() -{ - return createNTGet("value,alarm,timeStamp"); -} - PvaClientNTMultiGetPtr PvaClientMultiChannel::createNTGet(std::string const &request) { checkConnected(); @@ -193,13 +188,7 @@ PvaClientNTMultiGetPtr PvaClientMultiChannel::createNTGet(std::string const &req + createRequest->getMessage(); throw std::runtime_error(message); } - return PvaClientNTMultiGet::create(getPtrSelf(), pvaClientChannelArray,pvRequest); -} - - -PvaClientNTMultiMonitorPtr PvaClientMultiChannel::createNTMonitor() -{ - return createNTMonitor("value,alarm,timeStamp"); + return PvaClientNTMultiGet::create(shared_from_this(), pvaClientChannelArray,pvRequest); } PvaClientNTMultiMonitorPtr PvaClientMultiChannel::createNTMonitor(std::string const &request) @@ -211,7 +200,7 @@ PvaClientNTMultiMonitorPtr PvaClientMultiChannel::createNTMonitor(std::string co + createRequest->getMessage(); throw std::runtime_error(message); } - return PvaClientNTMultiMonitor::create(getPtrSelf(), pvaClientChannelArray,pvRequest); + return PvaClientNTMultiMonitor::create(shared_from_this(), pvaClientChannelArray,pvRequest); } diff --git a/src/pvaClientPut.cpp b/src/pvaClientPut.cpp index 5ec9d2e..700ba1f 100644 --- a/src/pvaClientPut.cpp +++ b/src/pvaClientPut.cpp @@ -104,17 +104,28 @@ PvaClientPut::PvaClientPut( connectState(connectIdle), putState(putIdle) { - if(PvaClient::getDebug()) cout<< "PvaClientPut::PvaClientPut()\n"; + if(PvaClient::getDebug()) { + cout<< "PvaClientPut::PvaClientPut" + << " channelName " << channel->getChannelName() + << endl; + } } PvaClientPut::~PvaClientPut() { - if(PvaClient::getDebug()) cout<< "PvaClientPut::~PvaClientPut()\n"; { Lock xx(mutex); if(isDestroyed) throw std::runtime_error("pvaClientPut was destroyed"); isDestroyed = true; } + if(PvaClient::getDebug()) { + string channelName("disconnected"); + Channel::shared_pointer chan(channel.lock()); + if(chan) channelName = chan->getChannelName(); + cout<< "PvaClientPut::~PvaClientPut" + << " channelName " << channelName + << endl; + } if(channelPut) channelPut->destroy(); } @@ -129,14 +140,14 @@ void PvaClientPut::checkPutState() string PvaClientPut::getRequesterName() { PvaClientPtr yyy = pvaClient.lock(); - if(!yyy) throw std::runtime_error("pvaClient was destroyed"); + if(!yyy) return string("PvaClientPut::getRequesterName() PvaClient isDestroyed"); return yyy->getRequesterName(); } void PvaClientPut::message(string const & message,MessageType messageType) { PvaClientPtr yyy = pvaClient.lock(); - if(!yyy) throw std::runtime_error("pvaClient was destroyed"); + if(!yyy) return; yyy->message(message, messageType); } @@ -145,11 +156,17 @@ void PvaClientPut::channelPutConnect( ChannelPut::shared_pointer const & channelPut, StructureConstPtr const & structure) { + if(PvaClient::getDebug()) { + cout << "PvaClientPut::channelPutConnect" + << " channelName " << channelPut->getChannel()->getChannelName() + << " status.isOK " << (status.isOK() ? "true" : "false") + << endl; + } channelPutConnectStatus = status; this->channelPut = channelPut; if(status.isOK()) { pvaClientData = PvaClientPutData::create(structure); - pvaClientData->setMessagePrefix(channel->getChannelName()); + pvaClientData->setMessagePrefix(channelPut->getChannel()->getChannelName()); } waitForConnect.signal(); @@ -161,6 +178,15 @@ void PvaClientPut::getDone( PVStructurePtr const & pvStructure, BitSetPtr const & bitSet) { + if(PvaClient::getDebug()) { + string channelName("disconnected"); + Channel::shared_pointer chan(channel.lock()); + if(chan) channelName = chan->getChannelName(); + cout << "PvaClientPut::getDone" + << " channelName " << channelName + << " status.isOK " << (status.isOK() ? "true" : "false") + << endl; + } channelGetPutStatus = status; connectState = connected; if(status.isOK()) { @@ -177,6 +203,15 @@ void PvaClientPut::putDone( const Status& status, ChannelPut::shared_pointer const & channelPut) { + if(PvaClient::getDebug()) { + string channelName("disconnected"); + Channel::shared_pointer chan(channel.lock()); + if(chan) channelName = chan->getChannelName(); + cout << "PvaClientPut::putDone" + << " channelName " << channelName + << " status.isOK " << (status.isOK() ? "true" : "false") + << endl; + } channelGetPutStatus = status; waitForGetPut.signal(); } @@ -186,8 +221,11 @@ void PvaClientPut::connect() issueConnect(); Status status = waitConnect(); if(status.isOK()) return; + Channel::shared_pointer chan(channel.lock()); + string channelName("disconnected"); + if(chan) channelName = chan->getChannelName(); string message = string("channel ") - + channel->getChannelName() + + channelName + " PvaClientPut::connect " + status.getMessage(); throw std::runtime_error(message); @@ -195,13 +233,20 @@ void PvaClientPut::connect() void PvaClientPut::issueConnect() { + Channel::shared_pointer chan(channel.lock()); if(connectState!=connectIdle) { - string message = string("channel ") + channel->getChannelName() + string channelName("disconnected"); + if(chan) channelName = chan->getChannelName(); + string message = string("channel ") + channelName + " pvaClientPut already connected "; throw std::runtime_error(message); } - connectState = connectActive; - channelPut = channel->createChannelPut(channelPutRequester,pvRequest); + if(chan) { + connectState = connectActive; + channelPut = chan->createChannelPut(channelPutRequester,pvRequest); + return; + } + throw std::runtime_error("PvaClientPut::issueConnect() but channel disconnected"); } Status PvaClientPut::waitConnect() @@ -211,8 +256,11 @@ Status PvaClientPut::waitConnect() return channelPutConnectStatus; } if(connectState!=connectActive) { - string message = string("channel ") + channel->getChannelName() - + " pvaClientPut illegal connect state "; + Channel::shared_pointer chan(channel.lock()); + string channelName("disconnected"); + if(chan) channelName = chan->getChannelName(); + string message = string("channel ") + channelName + + " PvaClientPut::waitConnect illegal connect state "; throw std::runtime_error(message); } waitForConnect.wait(); @@ -225,9 +273,12 @@ void PvaClientPut::get() issueGet(); Status status = waitGet(); if(status.isOK()) return; + Channel::shared_pointer chan(channel.lock()); + string channelName("disconnected"); + if(chan) channelName = chan->getChannelName(); string message = string("channel ") - + channel->getChannelName() - + " PvaClientPut::get " + + channelName + + " PvaClientPut::get " + status.getMessage(); throw std::runtime_error(message); } @@ -236,8 +287,11 @@ void PvaClientPut::issueGet() { if(connectState==connectIdle) connect(); if(putState!=putIdle) { + Channel::shared_pointer chan(channel.lock()); + string channelName("disconnected"); + if(chan) channelName = chan->getChannelName(); string message = string("channel ") - + channel->getChannelName() + + channelName + "PvaClientPut::issueGet get or put aleady active "; throw std::runtime_error(message); } @@ -248,7 +302,11 @@ void PvaClientPut::issueGet() Status PvaClientPut::waitGet() { if(putState!=getActive){ - string message = string("channel ") + channel->getChannelName() + Channel::shared_pointer chan(channel.lock()); + string channelName("disconnected"); + if(chan) channelName = chan->getChannelName(); + string message = string("channel ") + + channelName + " PvaClientPut::waitGet illegal put state"; throw std::runtime_error(message); } @@ -262,8 +320,11 @@ void PvaClientPut::put() issuePut(); Status status = waitPut(); if(status.isOK()) return; + Channel::shared_pointer chan(channel.lock()); + string channelName("disconnected"); + if(chan) channelName = chan->getChannelName(); string message = string("channel ") - + channel->getChannelName() + + channelName + " PvaClientPut::put " + status.getMessage(); throw std::runtime_error(message); @@ -273,7 +334,11 @@ void PvaClientPut::issuePut() { if(connectState==connectIdle) connect(); if(putState!=putIdle) { - string message = string("channel ") + channel->getChannelName() + Channel::shared_pointer chan(channel.lock()); + string channelName("disconnected"); + if(chan) channelName = chan->getChannelName(); + string message = string("channel ") + + channelName + "PvaClientPut::issueGet get or put aleady active "; throw std::runtime_error(message); } @@ -284,9 +349,13 @@ void PvaClientPut::issuePut() Status PvaClientPut::waitPut() { if(putState!=putActive){ - string message = string("channel ") + channel->getChannelName() + Channel::shared_pointer chan(channel.lock()); + string channelName("disconnected"); + if(chan) channelName = chan->getChannelName(); + string message = string("channel ") + + channelName + " PvaClientPut::waitPut illegal put state"; - throw std::runtime_error(message); + throw std::runtime_error(message); } waitForGetPut.wait(); putState = putIdle; diff --git a/src/pvaClientPutGet.cpp b/src/pvaClientPutGet.cpp index 2b3ecc0..4da7f41 100644 --- a/src/pvaClientPutGet.cpp +++ b/src/pvaClientPutGet.cpp @@ -116,17 +116,28 @@ PvaClientPutGet::PvaClientPutGet( connectState(connectIdle), putGetState(putGetIdle) { - if(PvaClient::getDebug()) cout<< "PvaClientPutGet::PvaClientPutGet()\n"; + if(PvaClient::getDebug()) { + cout<< "PvaClientPutGet::PvaClientPutGet" + << " channelName " << channel->getChannelName() + << endl; + } } PvaClientPutGet::~PvaClientPutGet() { - if(PvaClient::getDebug()) cout<< "PvaClientPutGet::~PvaClientPutGet()\n"; { Lock xx(mutex); if(isDestroyed) throw std::runtime_error("pvaClientPutGet was destroyed"); isDestroyed = true; } + if(PvaClient::getDebug()) { + string channelName("disconnected"); + Channel::shared_pointer chan(channel.lock()); + if(chan) channelName = chan->getChannelName(); + cout<< "PvaClientPutGet::~PvaClientPutGet" + << " channelName " << channelName + << endl; + } channelPutGet->destroy(); } @@ -141,14 +152,14 @@ void PvaClientPutGet::checkPutGetState() string PvaClientPutGet::getRequesterName() { PvaClientPtr yyy = pvaClient.lock(); - if(!yyy) throw std::runtime_error("pvaClient was destroyed"); + if(!yyy) return string("PvaClientPutGet::getRequesterName() PvaClient isDestroyed"); return yyy->getRequesterName(); } void PvaClientPutGet::message(string const & message,MessageType messageType) { PvaClientPtr yyy = pvaClient.lock(); - if(!yyy) throw std::runtime_error("pvaClient was destroyed"); + if(!yyy) return; yyy->message(message, messageType); } @@ -158,13 +169,19 @@ void PvaClientPutGet::channelPutGetConnect( StructureConstPtr const & putStructure, StructureConstPtr const & getStructure) { + if(PvaClient::getDebug()) { + cout << "PvaClientPutGet::channelPutGetConnect" + << " channelName " << channelPutGet->getChannel()->getChannelName() + << " status.isOK " << (status.isOK() ? "true" : "false") + << endl; + } channelPutGetConnectStatus = status; this->channelPutGet = channelPutGet; if(status.isOK()) { pvaClientPutData = PvaClientPutData::create(putStructure); - pvaClientPutData->setMessagePrefix(channel->getChannelName()); + pvaClientPutData->setMessagePrefix(channelPutGet->getChannel()->getChannelName()); pvaClientGetData = PvaClientGetData::create(getStructure); - pvaClientGetData->setMessagePrefix(channel->getChannelName()); + pvaClientGetData->setMessagePrefix(channelPutGet->getChannel()->getChannelName()); } waitForConnect.signal(); @@ -176,6 +193,15 @@ void PvaClientPutGet::putGetDone( PVStructurePtr const & getPVStructure, BitSetPtr const & getChangedBitSet) { + if(PvaClient::getDebug()) { + string channelName("disconnected"); + Channel::shared_pointer chan(channel.lock()); + if(chan) channelName = chan->getChannelName(); + cout << "PvaClientPutGet::putGetDone" + << " channelName " << channelName + << " status.isOK " << (status.isOK() ? "true" : "false") + << endl; + } channelPutGetStatus = status; if(status.isOK()) { pvaClientGetData->setData(getPVStructure,getChangedBitSet); @@ -189,6 +215,15 @@ void PvaClientPutGet::getPutDone( PVStructurePtr const & putPVStructure, BitSetPtr const & putBitSet) { + if(PvaClient::getDebug()) { + string channelName("disconnected"); + Channel::shared_pointer chan(channel.lock()); + if(chan) channelName = chan->getChannelName(); + cout << "PvaClientPutGet::getPutDone" + << " channelName " << channelName + << " status.isOK " << (status.isOK() ? "true" : "false") + << endl; + } channelPutGetStatus = status; if(status.isOK()) { PVStructurePtr pvs = pvaClientPutData->getPVStructure(); @@ -206,6 +241,15 @@ void PvaClientPutGet::getGetDone( PVStructurePtr const & getPVStructure, BitSetPtr const & getChangedBitSet) { + if(PvaClient::getDebug()) { + string channelName("disconnected"); + Channel::shared_pointer chan(channel.lock()); + if(chan) channelName = chan->getChannelName(); + cout << "PvaClientPutGet::getGetDone" + << " channelName " << channelName + << " status.isOK " << (status.isOK() ? "true" : "false") + << endl; + } channelPutGetStatus = status; if(status.isOK()) { pvaClientGetData->setData(getPVStructure,getChangedBitSet); @@ -218,28 +262,50 @@ void PvaClientPutGet::connect() issueConnect(); Status status = waitConnect(); if(status.isOK()) return; - string message = string("channel ") + channel->getChannelName() - + " PvaClientPutGet::connect " + status.getMessage(); + Channel::shared_pointer chan(channel.lock()); + string channelName("disconnected"); + if(chan) channelName = chan->getChannelName(); + string message = string("channel ") + + channelName + + " PvaClientPutGet::connect " + + status.getMessage(); throw std::runtime_error(message); } void PvaClientPutGet::issueConnect() { + Channel::shared_pointer chan(channel.lock()); if(connectState!=connectIdle) { - string message = string("channel ") + channel->getChannelName() + string channelName("disconnected"); + if(chan) channelName = chan->getChannelName(); + string message = string("channel ") + channelName + " pvaClientPutGet already connected "; throw std::runtime_error(message); } - connectState = connectActive; - channelPutGet = channel->createChannelPutGet(channelPutGetRequester,pvRequest); + if(chan) { + connectState = connectActive; + channelPutGet = chan->createChannelPutGet(channelPutGetRequester,pvRequest); + return; + } + throw std::runtime_error("PvaClientPutGet::issueConnect() but channel disconnected"); } Status PvaClientPutGet::waitConnect() { - if(connectState!=connectActive) { - string message = string("channel ") + channel->getChannelName() - + " pvaClientPutGet illegal connect state "; - throw std::runtime_error(message); + { + Lock xx(mutex); + if(connectState==connected) { + if(!channelPutGetConnectStatus.isOK()) connectState = connectIdle; + return channelPutGetConnectStatus; + } + if(connectState!=connectActive) { + Channel::shared_pointer chan(channel.lock()); + string channelName("disconnected"); + if(chan) channelName = chan->getChannelName(); + string message = string("channel ") + channelName + + " PvaClientPutGet::waitConnect illegal connect state "; + throw std::runtime_error(message); + } } waitForConnect.wait(); connectState = channelPutGetConnectStatus.isOK() ? connected : connectIdle; @@ -252,8 +318,13 @@ void PvaClientPutGet::putGet() issuePutGet(); Status status = waitPutGet(); if(status.isOK()) return; - string message = string("channel ") + channel->getChannelName() - + " PvaClientPutGet::putGet " + status.getMessage(); + Channel::shared_pointer chan(channel.lock()); + string channelName("disconnected"); + if(chan) channelName = chan->getChannelName(); + string message = string("channel ") + + channelName + + " PvaClientPut::putGet " + + status.getMessage(); throw std::runtime_error(message); } @@ -261,8 +332,11 @@ void PvaClientPutGet::issuePutGet() { if(connectState==connectIdle) connect(); if(putGetState!=putGetIdle) { - string message = string("channel ") + channel->getChannelName() - + " PvaClientPutGet::issueGet get or put aleady active "; + Channel::shared_pointer chan(channel.lock()); + string channelName("disconnected"); + if(chan) channelName = chan->getChannelName(); + string message = string("channel ") + channelName + + " PvaClientPutGet::issuePutGet get or put aleady active "; throw std::runtime_error(message); } putGetState = putGetActive; @@ -273,8 +347,11 @@ void PvaClientPutGet::issuePutGet() Status PvaClientPutGet::waitPutGet() { if(putGetState!=putGetActive){ - string message = string("channel ") + channel->getChannelName() - + " PvaClientPutGet::waitPutGet llegal put state"; + Channel::shared_pointer chan(channel.lock()); + string channelName("disconnected"); + if(chan) channelName = chan->getChannelName(); + string message = string("channel ") + channelName + + " PvaClientPutGet::waitPutGet get or put aleady active "; throw std::runtime_error(message); } waitForPutGet.wait(); @@ -287,8 +364,13 @@ void PvaClientPutGet::getGet() issueGetGet(); Status status = waitGetGet(); if(status.isOK()) return; - string message = string("channel ") + channel->getChannelName() - + " PvaClientPutGet::getGet " + status.getMessage(); + Channel::shared_pointer chan(channel.lock()); + string channelName("disconnected"); + if(chan) channelName = chan->getChannelName(); + string message = string("channel ") + + channelName + + " PvaClientPut::getGet " + + status.getMessage(); throw std::runtime_error(message); } @@ -296,8 +378,11 @@ void PvaClientPutGet::issueGetGet() { if(connectState==connectIdle) connect(); if(putGetState!=putGetIdle) { - string message = string("channel ") + channel->getChannelName() - + " PvaClientPutGet::issueGetGet aleady active "; + Channel::shared_pointer chan(channel.lock()); + string channelName("disconnected"); + if(chan) channelName = chan->getChannelName(); + string message = string("channel ") + channelName + + " PvaClientPutGet::issueGetGet get or put aleady active "; throw std::runtime_error(message); } putGetState = putGetActive; @@ -307,8 +392,11 @@ void PvaClientPutGet::issueGetGet() Status PvaClientPutGet::waitGetGet() { if(putGetState!=putGetActive){ - string message = string("channel ") + channel->getChannelName() - + " PvaClientPutGet::waitGetGet illegal state"; + Channel::shared_pointer chan(channel.lock()); + string channelName("disconnected"); + if(chan) channelName = chan->getChannelName(); + string message = string("channel ") + channelName + + " PvaClientPutGet::waitGetGet get or put aleady active "; throw std::runtime_error(message); } waitForPutGet.wait(); @@ -321,8 +409,13 @@ void PvaClientPutGet::getPut() issueGetPut(); Status status = waitGetPut(); if(status.isOK()) return; - string message = string("channel ") + channel->getChannelName() - + " PvaClientPutGet::getPut " + status.getMessage(); + Channel::shared_pointer chan(channel.lock()); + string channelName("disconnected"); + if(chan) channelName = chan->getChannelName(); + string message = string("channel ") + + channelName + + " PvaClientPut::getPut " + + status.getMessage(); throw std::runtime_error(message); } @@ -330,8 +423,11 @@ void PvaClientPutGet::issueGetPut() { if(connectState==connectIdle) connect(); if(putGetState!=putGetIdle) { - string message = string("channel ") + channel->getChannelName() - + " PvaClientPutGet::issueGetPut aleady active "; + Channel::shared_pointer chan(channel.lock()); + string channelName("disconnected"); + if(chan) channelName = chan->getChannelName(); + string message = string("channel ") + channelName + + " PvaClientPutGet::issueGetPut get or put aleady active "; throw std::runtime_error(message); } putGetState = putGetActive; @@ -341,8 +437,11 @@ void PvaClientPutGet::issueGetPut() Status PvaClientPutGet::waitGetPut() { if(putGetState!=putGetActive){ - string message = string("channel ") + channel->getChannelName() - + " PvaClientPutGet::waitGetPut illegal state"; + Channel::shared_pointer chan(channel.lock()); + string channelName("disconnected"); + if(chan) channelName = chan->getChannelName(); + string message = string("channel ") + channelName + + " PvaClientPutGet::waitGetPut get or put aleady active "; throw std::runtime_error(message); } waitForPutGet.wait(); From 04b5434b69be187be3d144cbf114c9bd10e9015d Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Wed, 8 Jun 2016 08:34:25 -0400 Subject: [PATCH 10/12] add some debug messages --- src/pvaClientMonitor.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/pvaClientMonitor.cpp b/src/pvaClientMonitor.cpp index b367185..ebfb361 100644 --- a/src/pvaClientMonitor.cpp +++ b/src/pvaClientMonitor.cpp @@ -172,6 +172,9 @@ void PvaClientMonitor::monitorConnect( pvaClientData = PvaClientMonitorData::create(structure); pvaClientData->setMessagePrefix(chan->getChannelName()); } + if(PvaClient::getDebug()) { + cout << "PvaClientMonitor::monitorConnect calling waitForConnect.signal\n"; + } waitForConnect.signal(); } @@ -199,6 +202,7 @@ void PvaClientMonitor::unlisten(MonitorPtr const & monitor) void PvaClientMonitor::connect() { + if(PvaClient::getDebug()) cout << "PvaClientMonitor::connect\n"; issueConnect(); Status status = waitConnect(); if(status.isOK()) return; @@ -214,6 +218,7 @@ void PvaClientMonitor::connect() void PvaClientMonitor::issueConnect() { + if(PvaClient::getDebug()) cout << "PvaClientMonitor::issueConnect\n"; Channel::shared_pointer chan(channel.lock()); if(connectState!=connectIdle) { string channelName("disconnected"); @@ -233,6 +238,7 @@ void PvaClientMonitor::issueConnect() Status PvaClientMonitor::waitConnect() { + if(PvaClient::getDebug()) cout << "PvaClientMonitor::waitConnect\n"; if(connectState==connected) { if(connectStatus.isOK()) connectState = connectIdle; return connectStatus; @@ -246,8 +252,15 @@ Status PvaClientMonitor::waitConnect() + " PvaClientMonitor::waitConnect illegal connect state "; throw std::runtime_error(message); } + if(PvaClient::getDebug()) { + cout << "PvaClientMonitor::waitConnect calling waitForConnect.wait\n"; + } waitForConnect.wait(); connectState = connectStatus.isOK() ? connected : connectIdle; + if(PvaClient::getDebug()) { + cout << "PvaClientMonitor::waitConnect" + << " connectStatus " << (connectStatus.isOK() ? "connected" : "not connected"); + } return connectStatus; } From 32fb16fcf031625d41f5e5cc7d34496a6c43f2a8 Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Fri, 10 Jun 2016 07:48:36 -0400 Subject: [PATCH 11/12] fix bug in src/pvaClientMonitor.cpp; other minor changes --- src/pvaClientGet.cpp | 7 +++---- src/pvaClientMonitor.cpp | 6 +++--- src/pvaClientPut.cpp | 43 ++++++++++++++++++++++++---------------- 3 files changed, 32 insertions(+), 24 deletions(-) diff --git a/src/pvaClientGet.cpp b/src/pvaClientGet.cpp index 3401282..4a3ba6a 100644 --- a/src/pvaClientGet.cpp +++ b/src/pvaClientGet.cpp @@ -150,7 +150,7 @@ void PvaClientGet::channelGetConnect( Channel::shared_pointer chan(channel.lock()); if(chan) channelName = chan->getChannelName(); cout << "PvaClientGet::channelGetConnect" - << " channelName " << channelGet->getChannel()->getChannelName() + << " channelName " << channelName << " status.isOK " << (status.isOK() ? "true" : "false") << endl; } @@ -208,17 +208,16 @@ void PvaClientGet::connect() void PvaClientGet::issueConnect() { + Channel::shared_pointer chan(channel.lock()); if(connectState!=connectIdle) { - Channel::shared_pointer chan(channel.lock()); string channelName("disconnected"); if(chan) channelName = chan->getChannelName(); string message = string("channel ") + channelName + " pvaClientGet already connected "; throw std::runtime_error(message); } - connectState = connectActive; - Channel::shared_pointer chan(channel.lock()); if(chan) { + connectState = connectActive; channelGet = chan->createChannelGet(channelGetRequester,pvRequest); return; } diff --git a/src/pvaClientMonitor.cpp b/src/pvaClientMonitor.cpp index ebfb361..6bdd970 100644 --- a/src/pvaClientMonitor.cpp +++ b/src/pvaClientMonitor.cpp @@ -240,7 +240,7 @@ Status PvaClientMonitor::waitConnect() { if(PvaClient::getDebug()) cout << "PvaClientMonitor::waitConnect\n"; if(connectState==connected) { - if(connectStatus.isOK()) connectState = connectIdle; + if(!connectStatus.isOK()) connectState = connectIdle; return connectStatus; } if(connectState!=connectActive) { @@ -264,7 +264,7 @@ Status PvaClientMonitor::waitConnect() return connectStatus; } -void PvaClientMonitor::setRequester(PvaClientMonitorRequesterPtr const & pvaClientMonitorrRequester) +void PvaClientMonitor::setRequester(PvaClientMonitorRequesterPtr const & pvaClientMonitorRequester) { if(PvaClient::getDebug()) { string channelName("disconnected"); @@ -274,7 +274,7 @@ void PvaClientMonitor::setRequester(PvaClientMonitorRequesterPtr const & pvaClie << " channelName " << channelName << endl; } - this->pvaClientMonitorRequester = pvaClientMonitorrRequester; + this->pvaClientMonitorRequester = pvaClientMonitorRequester; } void PvaClientMonitor::start() diff --git a/src/pvaClientPut.cpp b/src/pvaClientPut.cpp index 700ba1f..72705f8 100644 --- a/src/pvaClientPut.cpp +++ b/src/pvaClientPut.cpp @@ -157,16 +157,22 @@ void PvaClientPut::channelPutConnect( StructureConstPtr const & structure) { if(PvaClient::getDebug()) { + string channelName("disconnected"); + Channel::shared_pointer chan(channel.lock()); + if(chan) channelName = chan->getChannelName(); cout << "PvaClientPut::channelPutConnect" - << " channelName " << channelPut->getChannel()->getChannelName() + << " channelName " << channelName << " status.isOK " << (status.isOK() ? "true" : "false") << endl; } - channelPutConnectStatus = status; - this->channelPut = channelPut; - if(status.isOK()) { - pvaClientData = PvaClientPutData::create(structure); - pvaClientData->setMessagePrefix(channelPut->getChannel()->getChannelName()); + { + Lock xx(mutex); + channelPutConnectStatus = status; + this->channelPut = channelPut; + if(status.isOK()) { + pvaClientData = PvaClientPutData::create(structure); + pvaClientData->setMessagePrefix(channelPut->getChannel()->getChannelName()); + } } waitForConnect.signal(); @@ -251,17 +257,20 @@ void PvaClientPut::issueConnect() Status PvaClientPut::waitConnect() { - if(connectState==connected) { - if(!channelPutConnectStatus.isOK()) connectState = connectIdle; - return channelPutConnectStatus; - } - if(connectState!=connectActive) { - Channel::shared_pointer chan(channel.lock()); - string channelName("disconnected"); - if(chan) channelName = chan->getChannelName(); - string message = string("channel ") + channelName - + " PvaClientPut::waitConnect illegal connect state "; - throw std::runtime_error(message); + { + Lock xx(mutex); + if(connectState==connected) { + if(!channelPutConnectStatus.isOK()) connectState = connectIdle; + return channelPutConnectStatus; + } + if(connectState!=connectActive) { + Channel::shared_pointer chan(channel.lock()); + string channelName("disconnected"); + if(chan) channelName = chan->getChannelName(); + string message = string("channel ") + channelName + + " PvaClientPut::waitConnect illegal connect state "; + throw std::runtime_error(message); + } } waitForConnect.wait(); if(!channelPutConnectStatus.isOK()) connectState = connectIdle; From 7a4bd88d8dc57371cd858b48415c4f741a3a91b8 Mon Sep 17 00:00:00 2001 From: mrkraimer Date: Sat, 11 Jun 2016 12:01:57 -0400 Subject: [PATCH 12/12] doc and shared version changes --- RELEASE_NOTES.md => documentation/RELEASE_NOTES.md | 5 ++--- src/Makefile | 3 ++- src/pvaClient.cpp | 3 +-- src/pvaClientChannel.cpp | 2 -- 4 files changed, 5 insertions(+), 8 deletions(-) rename RELEASE_NOTES.md => documentation/RELEASE_NOTES.md (77%) diff --git a/RELEASE_NOTES.md b/documentation/RELEASE_NOTES.md similarity index 77% rename from RELEASE_NOTES.md rename to documentation/RELEASE_NOTES.md index d9380b7..d13c27b 100644 --- a/RELEASE_NOTES.md +++ b/documentation/RELEASE_NOTES.md @@ -1,4 +1,4 @@ -pvaClientCPP - Release/4.2 +EPICS V4 release 4.6 ========================== PvaClientMultiChannel @@ -8,10 +8,9 @@ checkConnected() now throws an exception if connect fails. -pvaClientCPP - Release/4.1 +EPICS V4 release 4.5 ========================== -This is for EPICS V4 release 4.5 pvaClient is a synchronous API for pvAccess. diff --git a/src/Makefile b/src/Makefile index 921ee19..7c05e15 100644 --- a/src/Makefile +++ b/src/Makefile @@ -5,7 +5,8 @@ include $(TOP)/configure/CONFIG LIBRARY += pvaClient -SHRLIB_VERSION=4.1.1 +# shared library ABI version. +SHRLIB_VERSION ?= 4.2-DEV INC += pv/pvaClient.h INC += pv/pvaClientMultiChannel.h diff --git a/src/pvaClient.cpp b/src/pvaClient.cpp index 8416970..b385557 100644 --- a/src/pvaClient.cpp +++ b/src/pvaClient.cpp @@ -78,8 +78,7 @@ void PvaClientChannelCache::showCache() string providerName = channel->getProvider()->getProviderName(); cout << "channel " << channelName << " provider " << providerName << endl; pvaChannel->showCache(); - } - + } } size_t PvaClientChannelCache::cacheSize() diff --git a/src/pvaClientChannel.cpp b/src/pvaClientChannel.cpp index 45229c7..dd0680d 100644 --- a/src/pvaClientChannel.cpp +++ b/src/pvaClientChannel.cpp @@ -211,8 +211,6 @@ PvaClientChannel::~PvaClientChannel() << endl; } if(PvaClient::getDebug()) showCache(); - pvaClientGetCache.reset(); - pvaClientPutCache.reset(); }