diff --git a/src/server/responseHandlers.cpp b/src/server/responseHandlers.cpp index ba06d17..02654dd 100644 --- a/src/server/responseHandlers.cpp +++ b/src/server/responseHandlers.cpp @@ -839,8 +839,11 @@ void ServerChannelRequesterImpl::channelCreated(const Status& status, Channel::s } } -void ServerChannelRequesterImpl::channelStateChange(Channel::shared_pointer const & /*channel*/, const Channel::ConnectionState /*isConnected*/) +void ServerChannelRequesterImpl::channelStateChange(Channel::shared_pointer const & /*channel*/, const Channel::ConnectionState isConnected) { + if(isConnected==Channel::CONNECTED || isConnected==Channel::NEVER_CONNECTED) + return; + if(Transport::shared_pointer transport = _transport.lock()) { ChannelHostingTransport::shared_pointer casTransport = dynamic_pointer_cast(transport); diff --git a/src/utils/configuration.cpp b/src/utils/configuration.cpp index a49e2db..713af0b 100644 --- a/src/utils/configuration.cpp +++ b/src/utils/configuration.cpp @@ -4,19 +4,12 @@ * in file LICENSE that is included with this distribution. */ -#include -#include -#include -#include -#include -#include - #include #include +#include #include -#include #include #define epicsExportSharedSymbols @@ -33,122 +26,6 @@ namespace pvAccess { using namespace epics::pvData; using namespace std; -#ifndef EPICS_VERSION_INT -#define VERSION_INT(V,R,M,P) ( ((V)<<24) | ((R)<<16) | ((M)<<8) | (P)) -#define EPICS_VERSION_INT VERSION_INT(EPICS_VERSION, EPICS_REVISION, EPICS_MODIFICATION, EPICS_PATCH_LEVEL) -#endif - -#if EPICS_VERSION_INT < VERSION_INT(3,15,0,1) -/* integer conversion primitives added to epicsStdlib.c in 3.15.0.1 */ - -#define S_stdlib_noConversion 1 /* No digits to convert */ -#define S_stdlib_extraneous 2 /* Extraneous characters */ -#define S_stdlib_underflow 3 /* Too small to represent */ -#define S_stdlib_overflow 4 /* Too large to represent */ -#define S_stdlib_badBase 5 /* Number base not supported */ - -static int -epicsParseDouble(const char *str, double *to, char **units) -{ - int c; - char *endp; - double value; - - while ((c = *str) && isspace(c)) - ++str; - - errno = 0; - value = epicsStrtod(str, &endp); - - if (endp == str) - return S_stdlib_noConversion; - if (errno == ERANGE) - return (value == 0) ? S_stdlib_underflow : S_stdlib_overflow; - - while ((c = *endp) && isspace(c)) - ++endp; - if (c && !units) - return S_stdlib_extraneous; - - *to = value; - if (units) - *units = endp; - return 0; -} - -static int -epicsParseFloat(const char *str, float *to, char **units) -{ - double value, abs; - int status = epicsParseDouble(str, &value, units); - - if (status) - return status; - - abs = fabs(value); - if (value > 0 && abs <= FLT_MIN) - return S_stdlib_underflow; - // NOTE: 'finite' is deprecated in OS X 10.9, use 'isfinite' instead - if (isfinite(value) && abs >= FLT_MAX) - return S_stdlib_overflow; - - *to = (float)value; - return 0; -} - -static int -epicsParseLong(const char *str, long *to, int base, char **units) -{ - int c; - char *endp; - long value; - - while ((c = *str) && isspace(c)) - ++str; - - errno = 0; - value = strtol(str, &endp, base); - - if (endp == str) - return S_stdlib_noConversion; - if (errno == EINVAL) /* Not universally supported */ - return S_stdlib_badBase; - if (errno == ERANGE) - return S_stdlib_overflow; - - while ((c = *endp) && isspace(c)) - ++endp; - if (c && !units) - return S_stdlib_extraneous; - - *to = value; - if (units) - *units = endp; - return 0; -} - -static int -epicsParseInt32(const char *str, epicsInt32 *to, int base, char **units) -{ - long value; - int status = epicsParseLong(str, &value, base, units); - - if (status) - return status; - -#if (LONG_MAX > 0x7fffffff) - if (value < -0x80000000L || value > 0x7fffffffL) - return S_stdlib_overflow; -#endif - - *to = (epicsInt32)value; - return 0; -} - -#endif - - - Properties::Properties() {} Properties::Properties(const string &fileName) : _fileName(fileName) {} @@ -283,32 +160,29 @@ bool Configuration::getPropertyAsBoolean(const std::string &name, const bool def epics::pvData::int32 Configuration::getPropertyAsInteger(const std::string &name, const epics::pvData::int32 defaultValue) const { - epicsInt32 ret; - std::string val(getPropertyAsString(name, "")); - - if(epicsParseInt32(val.c_str(), &ret, 0, NULL)) + try{ + return castUnsafe(getPropertyAsString(name, "")); + }catch(std::runtime_error&){ return defaultValue; - return ret; + } } float Configuration::getPropertyAsFloat(const std::string &name, const float defaultValue) const { - float ret; - std::string val(getPropertyAsString(name, "")); - - if(epicsParseFloat(val.c_str(), &ret, NULL)) + try{ + return castUnsafe(getPropertyAsString(name, "")); + }catch(std::runtime_error&){ return defaultValue; - return ret; + } } double Configuration::getPropertyAsDouble(const std::string &name, const double defaultValue) const { - double ret; - std::string val(getPropertyAsString(name, "")); - - if(epicsParseDouble(val.c_str(), &ret, NULL)) + try { + return castUnsafe(getPropertyAsString(name, "")); + }catch(std::runtime_error&){ return defaultValue; - return ret; + } } std::string Configuration::getPropertyAsString(const std::string &name, const std::string &defaultValue) const diff --git a/src/utils/fairQueue.h b/src/utils/fairQueue.h index 976c14a..014f455 100644 --- a/src/utils/fairQueue.h +++ b/src/utils/fairQueue.h @@ -49,7 +49,15 @@ public: typedef std::tr1::shared_ptr value_type; class epicsShareClass entry { - ELLNODE node; + /* In c++, use of ellLib (which implies offsetof()) should be restricted + * to POD structs. So enode_t exists as a POD struct for which offsetof() + * is safe and well defined. enode_t::self is used in place of + * casting via CONTAINER(penode, entry, enode) + */ + struct enode_t { + ELLNODE node; + entry *self; + } enode; unsigned Qcnt; value_type holder; #ifndef NDEBUG @@ -61,16 +69,20 @@ public: entry(const entry&); entry& operator=(const entry&); public: - entry() :node(), Qcnt(0), holder() + entry() :Qcnt(0), holder() #ifndef NDEBUG , owner(NULL) #endif { - node.next = node.previous = NULL; + enode.node.next = enode.node.previous = NULL; + enode.self = this; } ~entry() { // nodes should be removed from the list before deletion - assert(!node.next && !node.previous && !owner); + assert(!enode.node.next && !enode.node.previous); +#ifndef NDEBUG + assert(!owner); +#endif } }; @@ -111,7 +123,7 @@ public: assert(P->owner==NULL); P->owner = this; P->holder = ent; // the list will hold a reference - ellAdd(&list, &P->node); // push_back + ellAdd(&list, &P->enode.node); // push_back } else assert(P->owner==this); } @@ -124,16 +136,18 @@ public: ELLNODE *cur = ellGet(&list); // pop_front if(cur) { - entry *P = CONTAINER(cur, entry, node); + typedef typename entry::enode_t enode_t; + enode_t *PN = CONTAINER(cur, enode_t, node); + entry *P = PN->self; assert(P->owner==this); assert(P->Qcnt>0); if(--P->Qcnt==0) { - P->node.previous = P->node.next = NULL; + PN->node.previous = PN->node.next = NULL; P->owner = NULL; ret.swap(P->holder); } else { - ellAdd(&list, &P->node); // push_back + ellAdd(&list, &P->enode.node); // push_back ret = P->holder; }