From 776c4cf44954b0741b66b7bb4ac5ab37fa7e45d2 Mon Sep 17 00:00:00 2001 From: Matej Sekoranja Date: Fri, 13 May 2011 20:38:22 +0200 Subject: [PATCH] returning by ref --- pvAccessApp/client/pvAccess.h | 10 ++-- .../remoteClient/clientContextImpl.cpp | 46 +++++++++++++++---- testApp/remote/testServer.cpp | 17 +++++-- 3 files changed, 54 insertions(+), 19 deletions(-) diff --git a/pvAccessApp/client/pvAccess.h b/pvAccessApp/client/pvAccess.h index 6b6bff7..978aea9 100644 --- a/pvAccessApp/client/pvAccess.h +++ b/pvAccessApp/client/pvAccess.h @@ -457,8 +457,8 @@ namespace epics { namespace pvAccess { * Get the the channel provider of this channel. * @return The channel provider. */ - virtual std::tr1::shared_ptr getProvider() = 0; -// virtual ChannelProvider::shared_pointer getProvider() = 0; + virtual std::tr1::shared_ptr const & getProvider() = 0; +// virtual ChannelProvider::shared_pointer const & getProvider() = 0; /** * Returns the channel's remote address, e.g. "/192.168.1.101:5064" or "#C0 S1". @@ -482,8 +482,8 @@ namespace epics { namespace pvAccess { * Get the channel epics::pvData::Requester. * @return The epics::pvData::Requester. */ -// virtual ChannelRequester::shared_pointer getChannelRequester() = 0; - virtual std::tr1::shared_ptr getChannelRequester() = 0; +// virtual ChannelRequester::shared_pointer const & getChannelRequester() = 0; + virtual std::tr1::shared_ptr const & getChannelRequester() = 0; /** * Is the channel connected? @@ -747,7 +747,7 @@ namespace epics { namespace pvAccess { * Get channel provider implementation. * @return the channel provider. */ - virtual ChannelProvider::shared_pointer getProvider() = 0; + virtual ChannelProvider::shared_pointer const & getProvider() = 0; /** * Prints detailed information about the context to the standard output stream. diff --git a/pvAccessApp/remoteClient/clientContextImpl.cpp b/pvAccessApp/remoteClient/clientContextImpl.cpp index a52221f..50cd084 100644 --- a/pvAccessApp/remoteClient/clientContextImpl.cpp +++ b/pvAccessApp/remoteClient/clientContextImpl.cpp @@ -1704,6 +1704,9 @@ namespace epics { Mutex m_mutex; BitSet::shared_pointer nullBitSet; PVStructure::shared_pointer nullPVStructure; + + MonitorElement::shared_pointer m_nullMonitorElement; + MonitorElement::shared_pointer m_thisPtr; public: @@ -1730,12 +1733,20 @@ namespace epics { virtual MonitorElement::shared_pointer const & poll() { Lock guard(m_mutex); - return m_gotMonitor ? static_pointer_cast(shared_from_this()) : MonitorElement::shared_pointer(); + if (m_gotMonitor) + return m_nullMonitorElement; + else + { + // TODO this is not OK!!! requires destroy() call to clean-up + m_thisPtr = shared_from_this(); + return m_thisPtr; + } } virtual void release(MonitorElement::shared_pointer const & monitorElement) { Lock guard(m_mutex); m_gotMonitor = false; + m_thisPtr.reset(); } Status start() { @@ -1747,7 +1758,7 @@ namespace epics { } void destroy() { - // noop + m_thisPtr.reset(); } // ============ MonitorElement ============ @@ -1784,6 +1795,9 @@ namespace epics { BitSet::shared_pointer m_monitorElementChangeBitSet; BitSet::shared_pointer m_monitorElementOverrunBitSet; + MonitorElement::shared_pointer m_nullMonitorElement; + MonitorElement::shared_pointer m_thisPtr; + public: MonitorStrategyEntire(MonitorRequester::shared_pointer const & callback) : @@ -1817,17 +1831,26 @@ namespace epics { virtual MonitorElement::shared_pointer const & poll() { Lock guard(m_mutex); - return m_gotMonitor ? static_pointer_cast(shared_from_this()) : MonitorElement::shared_pointer(); + if (m_gotMonitor) + return m_nullMonitorElement; + else + { + // TODO this is not OK!!! requires destroy() call to clean-up + m_thisPtr = shared_from_this(); + return m_thisPtr; + } } virtual void release(MonitorElement::shared_pointer const & monitorElement) { Lock guard(m_mutex); m_gotMonitor = false; + m_thisPtr.reset(); } Status start() { Lock guard(m_mutex); m_gotMonitor = false; + m_thisPtr.reset(); return Status::OK; } @@ -1836,7 +1859,7 @@ namespace epics { } void destroy() { - // noop + m_thisPtr.reset(); } // ============ MonitorElement ============ @@ -1879,6 +1902,8 @@ namespace epics { BitSet::shared_pointer m_dataChangeBitSet; BitSet::shared_pointer m_dataOverrunBitSet; bool m_needToCompress; + + MonitorElement::shared_pointer thisMonitorElement; public: @@ -1949,13 +1974,15 @@ namespace epics { m_needToCompress = false; } - MonitorElement::shared_pointer thisMonitorElement = shared_from_this(); + // TODO fix this + thisMonitorElement = shared_from_this(); return thisMonitorElement; } virtual void release(MonitorElement::shared_pointer const & monitorElement) { Lock guard(m_mutex); m_gotMonitor = false; + thisMonitorElement.reset(); } Status start() { @@ -1963,6 +1990,7 @@ namespace epics { if (!m_monitorElementChangeBitSet) return Status(Status::STATUSTYPE_ERROR, "Monitor not connected."); m_gotMonitor = false; + thisMonitorElement.reset(); m_monitorElementChangeBitSet->clear(); m_monitorElementOverrunBitSet->clear(); return Status::OK; @@ -1973,7 +2001,7 @@ namespace epics { } void destroy() { - // noop + thisMonitorElement.reset(); } // ============ MonitorElement ============ @@ -2965,7 +2993,7 @@ namespace epics { std::cout << "[" << getRequesterName() << "] message(" << message << ", " << messageTypeName[messageType] << ")" << std::endl; } - virtual ChannelProvider::shared_pointer getProvider() + virtual ChannelProvider::shared_pointer const & getProvider() { return m_context->getProvider(); } @@ -2989,7 +3017,7 @@ namespace epics { return m_name; } - virtual ChannelRequester::shared_pointer getChannelRequester() + virtual ChannelRequester::shared_pointer const & getChannelRequester() { return m_requester; } @@ -3639,7 +3667,7 @@ TODO return m_version; } - virtual ChannelProvider::shared_pointer getProvider() { + virtual ChannelProvider::shared_pointer const & getProvider() { //Lock lock(m_contextMutex); return m_provider; } diff --git a/testApp/remote/testServer.cpp b/testApp/remote/testServer.cpp index 7e15194..2b3f54e 100644 --- a/testApp/remote/testServer.cpp +++ b/testApp/remote/testServer.cpp @@ -462,6 +462,9 @@ class MockMonitor : public Monitor, public MonitorElement, public std::tr1::enab bool m_first; Mutex m_lock; int m_count; + + MonitorElement::shared_pointer m_thisPtr; + MonitorElement::shared_pointer m_nullMonitor; protected: MockMonitor(MonitorRequester::shared_pointer const & monitorRequester, PVStructure::shared_pointer const & pvStructure, PVStructure::shared_pointer const & pvRequest) : @@ -513,13 +516,13 @@ class MockMonitor : public Monitor, public MonitorElement, public std::tr1::enab Lock xx(m_lock); if (m_count) { - return MonitorElement::shared_pointer(); + return m_nullMonitor; } else { m_count++; - MonitorElement::shared_pointer thisPtr = shared_from_this(); - return thisPtr; + m_thisPtr = shared_from_this(); + return m_thisPtr; } } @@ -527,11 +530,15 @@ class MockMonitor : public Monitor, public MonitorElement, public std::tr1::enab { Lock xx(m_lock); if (m_count) + { + m_thisPtr.reset(); m_count--; + } } virtual void destroy() { + m_thisPtr.reset(); stop(); } @@ -625,7 +632,7 @@ class MockChannel : public Channel { std::cout << "[" << getRequesterName() << "] message(" << message << ", " << messageTypeName[messageType] << ")" << std::endl; } - virtual ChannelProvider::shared_pointer getProvider() + virtual ChannelProvider::shared_pointer const & getProvider() { return m_provider; } @@ -640,7 +647,7 @@ class MockChannel : public Channel { return m_name; } - virtual std::tr1::shared_ptr getChannelRequester() + virtual std::tr1::shared_ptr const & getChannelRequester() { return m_requester; }