From c59715f687ddb9e9b962afb3d04ad2b17537ae94 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Wed, 9 Sep 2015 18:22:16 -0400 Subject: [PATCH 01/12] cleanup commented code blocks --- src/remote/codec.cpp | 99 ------------------------ src/remoteClient/clientContextImpl.cpp | 100 ------------------------- 2 files changed, 199 deletions(-) diff --git a/src/remote/codec.cpp b/src/remote/codec.cpp index 592b70d..ebdadae 100644 --- a/src/remote/codec.cpp +++ b/src/remote/codec.cpp @@ -1019,101 +1019,7 @@ namespace epics { std::size_t elementCount, std::size_t elementSize) { return false; - // _socketBuffer == existingBuffer -/* - std::size_t bytesToBeDeserialized = elementCount*elementSize; - - // TODO check if bytesToDeserialized < threshold that direct pays off? - - _directPayloadRead = bytesToBeDeserialized; - _directBuffer = deserializeTo; - - while (true) - { - // retrieve what's already in buffers - size_t availableBytes = min(_directPayloadRead, _socketBuffer->getRemaining()); - existingBuffer->getArray(_directBuffer, availableBytes); - _directPayloadRead -= availableBytes; - - if (_directPayloadRead == 0) - return true; - - _directBuffer += availableBytes; - - // subtract what was already processed - size_t pos = _socketBuffer->getPosition(); - _storedPayloadSize -= pos -_storedPosition; - _storedPosition = pos; - - // no more data and we have some payload left => read buffer - if (likely(_storedPayloadSize > 0)) - { - size_t bytesToRead = std::min(_directPayloadRead, _storedPayloadSize); - processReadIntoDirectBuffer(bytesToRead); -// std::cout << "d: " << bytesToRead << std::endl; - _storedPayloadSize -= bytesToRead; - _directPayloadRead -= bytesToRead; - } - - if (_directPayloadRead == 0) - return true; - - _stage = PROCESS_HEADER; - processReadCached(true, UNDEFINED_STAGE, _directPayloadRead); - - _storedPosition = _socketBuffer->getPosition(); - _storedLimit = _socketBuffer->getLimit(); - _socketBuffer->setLimit( - min(_storedPosition + _storedPayloadSize, _storedLimit) - ); - - } - - return true; -*/ } -/* - void AbstractCodec::processReadIntoDirectBuffer(size_t bytesToRead) - { - while (bytesToRead > 0) - { - ssize_t bytesRead = recv(_channel, _directBuffer, bytesToRead, 0); - - // std::cout << "d: " << bytesRead << std::endl; - - if(unlikely(bytesRead<=0)) - { - - if (bytesRead<0) - { - int socketError = SOCKERRNO; - - // interrupted or timeout - if (socketError == EINTR || - socketError == EAGAIN || - socketError == EWOULDBLOCK) - continue; - } - - // error (disconnect, end-of-stream) detected - close(); - - THROW_BASE_EXCEPTION("bytesRead < 0"); - - return; - } - - bytesToRead -= bytesRead; - _directBuffer += bytesRead; - - } - } -*/ - - - - - // // // BlockingAbstractCodec @@ -1228,11 +1134,6 @@ namespace epics { bac->processWrite(); } catch (connection_closed_exception &cce) { // noop - /* - LOG(logLevelDebug, - "connection closed by remote host while in sendThread at %s:%d: %s", - __FILE__, __LINE__, e.what()); - */ } catch (std::exception &e) { LOG(logLevelWarn, "an exception caught while in sendThread at %s:%d: %s", diff --git a/src/remoteClient/clientContextImpl.cpp b/src/remoteClient/clientContextImpl.cpp index fc6e92c..ffe72bb 100644 --- a/src/remoteClient/clientContextImpl.cpp +++ b/src/remoteClient/clientContextImpl.cpp @@ -2160,106 +2160,6 @@ namespace epics { } } - /* - virtual void response(Transport::shared_pointer const & transport, ByteBuffer* payloadBuffer) { - - bool notify = false; - - { - Lock guard(m_mutex); - - // if in overrun mode, check if some is free - if (m_overrunInProgress) - { - MonitorElementPtr newElement = m_monitorQueue.getFree(); - if (newElement.get() != 0) - { - // take new, put current in use - PVStructurePtr pvStructure = m_monitorElement->pvStructurePtr; - copyUnchecked(pvStructure, newElement->pvStructurePtr); - - BitSetUtil::compress(m_monitorElement->changedBitSet, pvStructure); - BitSetUtil::compress(m_monitorElement->overrunBitSet, pvStructure); - m_monitorQueue.setUsed(m_monitorElement); - - m_monitorElement = newElement; - notify = true; - - m_overrunInProgress = false; - } - } - } - - if (notify) - { - EXCEPTION_GUARD(m_callback->monitorEvent(shared_from_this())); - } - - { - Lock guard(m_mutex); - - // setup current fields - PVStructurePtr pvStructure = m_monitorElement->pvStructurePtr; - BitSet::shared_pointer changedBitSet = m_monitorElement->changedBitSet; - BitSet::shared_pointer overrunBitSet = m_monitorElement->overrunBitSet; - - // special treatment if in overrun state - if (m_overrunInProgress) - { - // lazy init - if (m_bitSet1.get() == 0) m_bitSet1.reset(new BitSet(changedBitSet->size())); - if (m_bitSet2.get() == 0) m_bitSet2.reset(new BitSet(overrunBitSet->size())); - - m_bitSet1->deserialize(payloadBuffer, transport.get()); - pvStructure->deserialize(payloadBuffer, transport.get(), m_bitSet1.get()); - m_bitSet2->deserialize(payloadBuffer, transport.get()); - - // OR local overrun - // TODO this does not work perfectly if bitSet is compressed !!! - // uncompressed bitSets should be used !!! - overrunBitSet->or_and(*(changedBitSet.get()), *(m_bitSet1.get())); - - // OR remove change - *(changedBitSet.get()) |= *(m_bitSet1.get()); - - // OR remote overrun - *(overrunBitSet.get()) |= *(m_bitSet2.get()); - } - else - { - // deserialize changedBitSet and data, and overrun bit set - changedBitSet->deserialize(payloadBuffer, transport.get()); - pvStructure->deserialize(payloadBuffer, transport.get(), changedBitSet.get()); - overrunBitSet->deserialize(payloadBuffer, transport.get()); - } - - // prepare next free (if any) - MonitorElementPtr newElement = m_monitorQueue.getFree(); - if (newElement.get() == 0) { - m_overrunInProgress = true; - return; - } - - // if there was overrun in progress we manipulated bitSets... compress them - if (m_overrunInProgress) { - BitSetUtil::compress(changedBitSet, pvStructure); - BitSetUtil::compress(overrunBitSet, pvStructure); - - m_overrunInProgress = false; - } - - copyUnchecked(pvStructure, newElement->pvStructurePtr); - - m_monitorQueue.setUsed(m_monitorElement); - - m_monitorElement = newElement; - } - - EXCEPTION_GUARD(m_callback->monitorEvent(shared_from_this())); - - } - */ - virtual void response(Transport::shared_pointer const & transport, ByteBuffer* payloadBuffer) { From 839faf66c0cff75985ef16525f2e0dcead880d58 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Thu, 10 Sep 2015 12:26:05 -0400 Subject: [PATCH 02/12] AtomicValue use epicsAtomic if available --- src/remote/codec.h | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/src/remote/codec.h b/src/remote/codec.h index 988c982..edfd6f3 100644 --- a/src/remote/codec.h +++ b/src/remote/codec.h @@ -21,6 +21,11 @@ #include #include #include +#include + +#if defined(EPICS_VERSION_INT) && EPICS_VERSION_INT>=VERSION_INT(3,15,1,0) +#include +#endif #include #include @@ -48,8 +53,39 @@ namespace epics { namespace pvAccess { namespace detail { - // TODO replace mutex with atomic (CAS) operations - template +#if defined(EPICS_VERSION_INT) && EPICS_VERSION_INT>=VERSION_INT(3,15,1,0) + template + class AtomicValue + { + T val; + public: + AtomicValue() :val(0) {} + inline T getAndSet(T newval) + { + int oldval; + // epicsAtomic doesn't have unconditional swap + do { + oldval = epics::atomic::get(val); + }while(epics::atomic::compareAndSwap(val, oldval, newval)!=oldval); + return oldval; + } + inline T get() { return epics::atomic::get(val); } + }; + // treat bool as int + template<> + class AtomicValue + { + AtomicValue realval; + public: + inline bool getAndSet(bool newval) + { + return this->realval.getAndSet(newval?1:0)!=0; + } + inline bool get() { return !!this->realval.get(); } + }; + +#else + template class AtomicValue { public: @@ -69,6 +105,7 @@ namespace epics { T _value; epics::pvData::Mutex mutex; }; +#endif // TODO replace this queue with lock-free implementation From 0fe4e41099710b1dd87949464fec6b55cefb59bf Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Fri, 4 Sep 2015 13:35:50 -0400 Subject: [PATCH 03/12] don't silently swallow exceptions --- src/server/serverContext.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/serverContext.cpp b/src/server/serverContext.cpp index 48c7812..367371e 100644 --- a/src/server/serverContext.cpp +++ b/src/server/serverContext.cpp @@ -552,7 +552,7 @@ void ServerContextImpl::dispose() } catch(...) { - // noop + std::cerr<<"Oh no, something when wrong in ServerContextImpl::dispose!\n"; } } From 1d30949690e4efc531d8ed7d9e31bcf6994c4cd4 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Fri, 4 Sep 2015 13:50:13 -0400 Subject: [PATCH 04/12] no point in using envGetConfigParamPtr except for predefine parameters Unless a default is provided, this is equivlent to getenv() --- src/utils/configuration.cpp | 9 ++------- src/utils/configuration.h | 1 - 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/utils/configuration.cpp b/src/utils/configuration.cpp index d93014a..53281d7 100644 --- a/src/utils/configuration.cpp +++ b/src/utils/configuration.cpp @@ -242,8 +242,6 @@ void Properties::list() SystemConfigurationImpl::SystemConfigurationImpl() : _properties(new Properties()) { - _envParam.name = new char[256]; - _envParam.pdflt = NULL; // no exception, default value is taken //_ibuffer.exceptions ( ifstream::failbit | ifstream::badbit ); //_obuffer.exceptions ( ifstream::failbit | ifstream::badbit ); @@ -251,7 +249,6 @@ SystemConfigurationImpl::SystemConfigurationImpl() : SystemConfigurationImpl::~SystemConfigurationImpl() { - if(_envParam.name) delete[] _envParam.name; } bool SystemConfigurationImpl::getPropertyAsBoolean(const string &name, const bool defaultValue) @@ -332,8 +329,7 @@ float SystemConfigurationImpl::getPropertyAsDouble(const string &name, const dou string SystemConfigurationImpl::getPropertyAsString(const string &name, const string &defaultValue) { - strncpy(_envParam.name,name.c_str(),name.length() + 1); - const char* val = envGetConfigParamPtr(&_envParam); + const char* val = getenv(name.c_str()); if(val != NULL) { return _properties->getProperty(name, string(val)); @@ -343,8 +339,7 @@ string SystemConfigurationImpl::getPropertyAsString(const string &name, const st bool SystemConfigurationImpl::hasProperty(const string &key) { - strncpy(_envParam.name,key.c_str(),key.length() + 1); - const char* val = envGetConfigParamPtr(&_envParam); + const char* val = getenv(key.c_str()); return (val != NULL) || _properties->hasProperty(key); } diff --git a/src/utils/configuration.h b/src/utils/configuration.h index 3a5acf3..321eb2c 100644 --- a/src/utils/configuration.h +++ b/src/utils/configuration.h @@ -152,7 +152,6 @@ public: bool hasProperty(const std::string &name); std::auto_ptr _properties; private: - ENV_PARAM _envParam; std::istringstream _ibuffer; std::ostringstream _obuffer; From 87af5b308f8be5146989a22f661b0e1e0a4cd51f Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Fri, 4 Sep 2015 14:53:43 -0400 Subject: [PATCH 05/12] config get socket address revamp configurationTest --- src/utils/configuration.cpp | 18 ++++ src/utils/configuration.h | 14 +++ testApp/utils/Makefile | 6 +- testApp/utils/configurationTest.cpp | 135 +++++++++++++++++++--------- 4 files changed, 126 insertions(+), 47 deletions(-) diff --git a/src/utils/configuration.cpp b/src/utils/configuration.cpp index 53281d7..10dcd6d 100644 --- a/src/utils/configuration.cpp +++ b/src/utils/configuration.cpp @@ -8,6 +8,8 @@ #include +#include + #define epicsExportSharedSymbols #include @@ -337,6 +339,22 @@ string SystemConfigurationImpl::getPropertyAsString(const string &name, const st return _properties->getProperty(name, defaultValue); } +bool SystemConfigurationImpl::getPropertyAsAddress(const std::string& name, osiSockAddr* addr) +{ + unsigned short dftport=0; + if(addr->sa.sa_family==AF_INET) + dftport = ntohs(addr->ia.sin_port); + + std::string val(getPropertyAsString(name, "")); + + if(val.empty()) return false; + + addr->ia.sin_family = AF_INET; + if(aToIPAddr(val.c_str(), dftport, &addr->ia)) + return false; + return true; +} + bool SystemConfigurationImpl::hasProperty(const string &key) { const char* val = getenv(key.c_str()); diff --git a/src/utils/configuration.h b/src/utils/configuration.h index 321eb2c..e50cd88 100644 --- a/src/utils/configuration.h +++ b/src/utils/configuration.h @@ -31,6 +31,8 @@ #include +union osiSockAddr; // defined in osiSock; + namespace epics { namespace pvAccess { @@ -135,6 +137,17 @@ public: * @return environment variable value as std::string or default value if it does not exist. */ virtual std::string getPropertyAsString(const std::string &name, const std::string &defaultValue) = 0; + /** + * Fetch and parse as a socket address and port number (address family set accordingly). + * At present only numeric addresses are parsed (eg. "127.0.0.1:4242"). + * + * The storage pointed to be addr should be initialized with a default value, or zeroed. + * + * @param name name of the environment variable to return. + * @pram addr pointer to the address struct to be filled in + * @return true if addr now contains an address, false otherwise + */ + virtual bool getPropertyAsAddress(const std::string& name, osiSockAddr* addr) = 0; virtual bool hasProperty(const std::string &name) = 0; }; @@ -149,6 +162,7 @@ public: float getPropertyAsFloat(const std::string &name, const float defaultValue); float getPropertyAsDouble(const std::string &name, const double defaultValue); std::string getPropertyAsString(const std::string &name, const std::string &defaultValue); + bool getPropertyAsAddress(const std::string& name, osiSockAddr* addr); bool hasProperty(const std::string &name); std::auto_ptr _properties; private: diff --git a/testApp/utils/Makefile b/testApp/utils/Makefile index f0936f8..a775946 100644 --- a/testApp/utils/Makefile +++ b/testApp/utils/Makefile @@ -44,7 +44,7 @@ TESTSCRIPTS_HOST += $(TESTS:%=%.t) #testHarness_SRCS += namedLockPatternTest.cpp #TESTS += namedLockPatternTest -#TESTPROD_HOST += configurationTest -#configurationTest_SRCS += configurationTest.cpp +TESTPROD_HOST += configurationTest +configurationTest_SRCS += configurationTest.cpp #testHarness_SRCS += configurationTest.cpp -#TESTS += configurationTest +TESTS += configurationTest diff --git a/testApp/utils/configurationTest.cpp b/testApp/utils/configurationTest.cpp index 5f9b9b8..4ed339f 100644 --- a/testApp/utils/configurationTest.cpp +++ b/testApp/utils/configurationTest.cpp @@ -4,13 +4,20 @@ */ #include -#include + +#include +#include +#include + +#include #include #include -#include -#include -#include +#include +#include + +#include +#include #ifdef _WIN32 void setenv(char * a, char * b, int c) @@ -25,62 +32,102 @@ using namespace epics::pvAccess; using namespace epics::pvData; using namespace std; -int main(int argc, char *argv[]) +static void showEnv(const char *name) { - SystemConfigurationImpl* configuration = new SystemConfigurationImpl(); - bool boolProperty = configuration->getPropertyAsBoolean("boolProperty", true); - assert(boolProperty == true); + testDiag("%s = \"%s\"", name, getenv(name)); +} - int32 intProperty = configuration->getPropertyAsInteger("intProperty", 1); - assert(intProperty == 1); +static void setEnv(const char *name, const char *val) +{ + epicsEnvSet(name, val); + testDiag("%s = \"%s\"", name, getenv(name)); +} - float floatProperty = configuration->getPropertyAsFloat("floatProperty", 3); - assert(floatProperty == 3); +static void showAddr(const osiSockAddr& addr) +{ + char buf[40]; + sockAddrToDottedIP(&addr.sa, buf, sizeof(buf)); + testDiag("%s", buf); +} - double doubleProperty = configuration->getPropertyAsDouble("doubleProperty", -3); - assert(doubleProperty == -3); +#define TESTVAL(TYPE, VAL1, VAL2, VAL1S) do {\ + showEnv(#TYPE "Property"); \ + testOk1(configuration->getPropertyAs##TYPE(#TYPE "Property", VAL1) == VAL1); \ + testOk1(configuration->getPropertyAs##TYPE(#TYPE "Property", VAL2) == VAL2); \ + setEnv(#TYPE "Property", VAL1S); \ + testOk1(configuration->getPropertyAs##TYPE(#TYPE "Property", VAL1) == VAL1); \ + testOk1(configuration->getPropertyAs##TYPE(#TYPE "Property", VAL2) == VAL1); \ + } while(0) - string stringProperty = configuration->getPropertyAsString("stringProperty", "string"); - assert(stringProperty == string("string")); - ConfigurationProviderImpl* configProvider = ConfigurationFactory::getProvider(); - configProvider->registerConfiguration("conf1",static_cast(configuration)); +MAIN(configurationTest) +{ + testPlan(35); + testDiag("Default configuration"); + Configuration::shared_pointer configuration(new SystemConfigurationImpl()); - SystemConfigurationImpl* configurationOut = static_cast(configProvider->getConfiguration("conf1")); - assert(configurationOut == configuration); + TESTVAL(String, "one", "two", "one"); + TESTVAL(Boolean, true, false, "true"); + TESTVAL(Integer, 100, 321, "100"); + TESTVAL(Float, 42.0e3, 44.0e3, "42.0e3"); + TESTVAL(Double, 42.0e3, 44.0e3, "42.0e3"); - intProperty = configuration->getPropertyAsInteger("intProperty", 2); - assert(intProperty == 1); + testDiag("IP Address w/o default or explicit port"); - floatProperty = configuration->getPropertyAsFloat("floatProperty", 4); - assert(floatProperty == 3); + showEnv("AddressProperty"); + osiSockAddr addr; + memset(&addr, 0, sizeof(addr)); + addr.ia.sin_family = AF_INET+1; // something not IPv4 + addr.ia.sin_port = htons(42); - doubleProperty = configuration->getPropertyAsDouble("doubleProperty", -4); - assert(doubleProperty == -3); + testOk1(configuration->getPropertyAsAddress("AddressProperty", &addr)==false); + setEnv("AddressProperty", "127.0.0.1"); // no port + testOk1(configuration->getPropertyAsAddress("AddressProperty", &addr)==true); + showAddr(addr); - stringProperty = configuration->getPropertyAsString("stringProperty", "string1"); - assert(stringProperty == string("string")); + testOk1(addr.ia.sin_family==AF_INET); + testOk1(ntohl(addr.ia.sin_addr.s_addr)==INADDR_LOOPBACK); + testOk1(ntohs(addr.ia.sin_port)==0); - setenv("boolProperty1", "1", 1); - boolProperty = configuration->getPropertyAsInteger("boolProperty1", 0); - assert(boolProperty == true); + testDiag("IP Address w/ default port"); - setenv("intProperty1", "45", 1); - intProperty = configuration->getPropertyAsInteger("intProperty1", 2); - assert(intProperty == 45); + memset(&addr, 0, sizeof(addr)); + addr.ia.sin_family = AF_INET; + addr.ia.sin_port = htons(42); - setenv("floatProperty1", "22", 1); - floatProperty = configuration->getPropertyAsFloat("floatProperty1", 3); - assert(floatProperty == 22); + testOk1(configuration->getPropertyAsAddress("AddressProperty", &addr)==true); + showAddr(addr); - setenv("dobuleProperty1", "42", 1); - doubleProperty = configuration->getPropertyAsDouble("dobuleProperty1", -3); - assert(doubleProperty == 42); + testOk1(addr.ia.sin_family==AF_INET); + testOk1(ntohl(addr.ia.sin_addr.s_addr)==INADDR_LOOPBACK); + testOk1(ntohs(addr.ia.sin_port)==42); - if(configProvider) delete configProvider; - epicsExitCallAtExits(); - CDRMonitor::get().show(stdout, true); - return 0; + testDiag("IP Address w/ default and explicit port"); + + setEnv("AddressProperty", "127.0.0.1:43"); // no port + testOk1(configuration->getPropertyAsAddress("AddressProperty", &addr)==true); + showAddr(addr); + + memset(&addr, 0, sizeof(addr)); + addr.ia.sin_family = AF_INET; + addr.ia.sin_port = htons(42); + + testOk1(configuration->getPropertyAsAddress("AddressProperty", &addr)==true); + showAddr(addr); + + testOk1(addr.ia.sin_family==AF_INET); + testOk1(ntohl(addr.ia.sin_addr.s_addr)==INADDR_LOOPBACK); + testOk1(ntohs(addr.ia.sin_port)==43); + + testDiag("register with global configuration listings"); + + ConfigurationProvider::shared_pointer configProvider(ConfigurationFactory::getProvider()); + configProvider->registerConfiguration("conf1", configuration); + + Configuration::shared_pointer configurationOut(configProvider->getConfiguration("conf1")); + testOk1(configurationOut.get() == configuration.get()); + + return testDone(); } From e08db19ddc7bebac711e0e4a8465486359162822 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Tue, 8 Sep 2015 10:57:34 -0400 Subject: [PATCH 06/12] avoid unnecessary vector copy --- src/server/responseHandlers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/responseHandlers.cpp b/src/server/responseHandlers.cpp index 020ee9c..e6c2982 100644 --- a/src/server/responseHandlers.cpp +++ b/src/server/responseHandlers.cpp @@ -540,7 +540,7 @@ public: PVStringArray::shared_pointer allChannelNames = result->getSubField("value"); ChannelListRequesterImpl::shared_pointer listListener(new ChannelListRequesterImpl()); - std::vector providers = m_serverContext->getChannelProviders(); + std::vector& providers = m_serverContext->getChannelProviders(); size_t providerCount = providers.size(); for (size_t i = 0; i < providerCount; i++) From 2e64b1b78553e2a3751e919475412b1131f98c26 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Tue, 8 Sep 2015 12:44:37 -0400 Subject: [PATCH 07/12] Message for unhandled exceptions in UDP message processing --- src/remote/blockingUDPTransport.cpp | 12 +++++++++++- src/remote/codec.cpp | 4 ++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/remote/blockingUDPTransport.cpp b/src/remote/blockingUDPTransport.cpp index aac605f..c03464f 100644 --- a/src/remote/blockingUDPTransport.cpp +++ b/src/remote/blockingUDPTransport.cpp @@ -243,7 +243,17 @@ inline int sendto(int s, const char *buf, size_t len, int flags, const struct so _receiveBuffer->flip(); - processBuffer(thisTransport, fromAddress, _receiveBuffer.get()); + try{ + processBuffer(thisTransport, fromAddress, _receiveBuffer.get()); + }catch(std::exception& e){ + LOG(logLevelError, + "an exception caught while in UDP receiveThread at %s:%d: %s", + __FILE__, __LINE__, e.what()); + } catch (...) { + LOG(logLevelError, + "unknown exception caught while in UDP receiveThread at %s:%d.", + __FILE__, __LINE__); + } } } else if (unlikely(bytesRead == -1)) { diff --git a/src/remote/codec.cpp b/src/remote/codec.cpp index ebdadae..4bb1cb5 100644 --- a/src/remote/codec.cpp +++ b/src/remote/codec.cpp @@ -1106,11 +1106,11 @@ namespace epics { try { bac->processRead(); } catch (std::exception &e) { - LOG(logLevelWarn, + LOG(logLevelError, "an exception caught while in receiveThread at %s:%d: %s", __FILE__, __LINE__, e.what()); } catch (...) { - LOG(logLevelWarn, + LOG(logLevelError, "unknown exception caught while in receiveThread at %s:%d.", __FILE__, __LINE__); } From 9696b17196f1d24bc8388a78946d65d5ac2f80fa Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Wed, 9 Sep 2015 18:22:08 -0400 Subject: [PATCH 08/12] use shared_ptr immediately --- src/server/responseHandlers.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/server/responseHandlers.cpp b/src/server/responseHandlers.cpp index e6c2982..b6fe912 100644 --- a/src/server/responseHandlers.cpp +++ b/src/server/responseHandlers.cpp @@ -295,10 +295,9 @@ void ServerSearchHandler::handleResponse(osiSockAddr* responseFrom, { // TODO object pool!!! int providerCount = _providers.size(); - ServerChannelFindRequesterImpl* pr = new ServerChannelFindRequesterImpl(_context, providerCount); - pr->set(name, searchSequenceId, cid, responseAddress, responseRequired, false); + std::tr1::shared_ptr tp(new ServerChannelFindRequesterImpl(_context, providerCount)); + tp->set(name, searchSequenceId, cid, responseAddress, responseRequired, false); // TODO use std::make_shared - std::tr1::shared_ptr tp(pr); ChannelFindRequester::shared_pointer spr = tp; for (int i = 0; i < providerCount; i++) @@ -314,11 +313,10 @@ void ServerSearchHandler::handleResponse(osiSockAddr* responseFrom, #define MAX_SERVER_SEARCH_RESPONSE_DELAY_MS 100 double period = (rand() % MAX_SERVER_SEARCH_RESPONSE_DELAY_MS)/(double)1000; - ServerChannelFindRequesterImpl* pr = new ServerChannelFindRequesterImpl(_context, 1); - pr->set("", searchSequenceId, 0, responseAddress, true, true); + std::tr1::shared_ptr tp(new ServerChannelFindRequesterImpl(_context, 1)); + tp->set("", searchSequenceId, 0, responseAddress, true, true); // TODO use std::make_shared - std::tr1::shared_ptr tp(pr); TimerCallback::shared_pointer tc = tp; _context->getTimer()->scheduleAfterDelay(tc, period); } From f561cb97dc49d0aaa6ec37f88b829fe64a446a0f Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Wed, 9 Sep 2015 19:00:22 -0400 Subject: [PATCH 09/12] shorten thread names so more of the interesting part is shown by epicsThreadShowAll() --- src/remote/blockingUDPTransport.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/remote/blockingUDPTransport.cpp b/src/remote/blockingUDPTransport.cpp index c03464f..483da6f 100644 --- a/src/remote/blockingUDPTransport.cpp +++ b/src/remote/blockingUDPTransport.cpp @@ -87,7 +87,7 @@ inline int sendto(int s, const char *buf, size_t len, int flags, const struct so void BlockingUDPTransport::start() { - string threadName = "UDP-receive " + inetAddressToString(_bindAddress); + string threadName = "UDP-rx " + inetAddressToString(_bindAddress); if (IS_LOGGABLE(logLevelTrace)) { @@ -292,7 +292,7 @@ inline int sendto(int s, const char *buf, size_t len, int flags, const struct so if (IS_LOGGABLE(logLevelTrace)) { - string threadName = "UDP-receive "+inetAddressToString(_bindAddress); + string threadName = "UDP-rx "+inetAddressToString(_bindAddress); LOG(logLevelTrace, "Thread '%s' exiting.", threadName.c_str()); } From be01b418f2a30f2e0cba459fa947515aaeed7ca2 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Thu, 10 Sep 2015 15:48:30 -0400 Subject: [PATCH 10/12] use CMD_* instead of magic number --- src/remote/simpleChannelSearchManagerImpl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/remote/simpleChannelSearchManagerImpl.cpp b/src/remote/simpleChannelSearchManagerImpl.cpp index f8a42a6..5363ca1 100644 --- a/src/remote/simpleChannelSearchManagerImpl.cpp +++ b/src/remote/simpleChannelSearchManagerImpl.cpp @@ -181,7 +181,7 @@ void SimpleChannelSearchManagerImpl::initializeSendBuffer() m_sendBuffer.putByte(PVA_MAGIC); m_sendBuffer.putByte(PVA_VERSION); m_sendBuffer.putByte((EPICS_BYTE_ORDER == EPICS_ENDIAN_BIG) ? 0x80 : 0x00); // data + 7-bit endianess - m_sendBuffer.putByte((int8_t)3); // search + m_sendBuffer.putByte(CMD_SEARCH); m_sendBuffer.putInt(4+1+3+16+2+1); // "zero" payload m_sendBuffer.putInt(m_sequenceNumber); From fccf7c1b936be69144d272807b1345467364bf20 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Mon, 23 Nov 2015 16:51:53 -0500 Subject: [PATCH 11/12] quiet (un)signed warning --- src/pipelineService/pipelineServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pipelineService/pipelineServer.cpp b/src/pipelineService/pipelineServer.cpp index 3e25649..9a64c56 100644 --- a/src/pipelineService/pipelineServer.cpp +++ b/src/pipelineService/pipelineServer.cpp @@ -99,7 +99,7 @@ class ChannelPipelineMonitorImpl : { Lock guard(m_freeQueueLock); m_freeQueue.reserve(m_queueSize); - for (int32 i = 0; i < m_queueSize; i++) + for (size_t i = 0; i < m_queueSize; i++) { PVStructure::shared_pointer pvStructure = getPVDataCreate()->createPVStructure(structure); MonitorElement::shared_pointer monitorElement(new MonitorElement(pvStructure)); From 0fd7b111a1d7448533efaf0132ea161a0c02393c Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Tue, 24 Nov 2015 14:39:06 -0500 Subject: [PATCH 12/12] pre-processor fun --- src/remote/codec.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/remote/codec.h b/src/remote/codec.h index edfd6f3..c45174b 100644 --- a/src/remote/codec.h +++ b/src/remote/codec.h @@ -23,8 +23,11 @@ #include #include -#if defined(EPICS_VERSION_INT) && EPICS_VERSION_INT>=VERSION_INT(3,15,1,0) +#ifdef EPICS_VERSION_INT +#if EPICS_VERSION_INT>=VERSION_INT(3,15,1,0) #include +#define PVA_CODEC_USE_ATOMIC +#endif #endif #include @@ -53,7 +56,8 @@ namespace epics { namespace pvAccess { namespace detail { -#if defined(EPICS_VERSION_INT) && EPICS_VERSION_INT>=VERSION_INT(3,15,1,0) +#ifdef PVA_CODEC_USE_ATOMIC +#undef PVA_CODEC_USE_ATOMIC template class AtomicValue {