From 4d54b91a3a9255a79461ab2426d059e5b175e1e6 Mon Sep 17 00:00:00 2001 From: Jeff Hill Date: Thu, 7 Nov 2013 10:26:03 -0700 Subject: [PATCH 1/7] o fixed compile errors in, and proper diagnostic from, casPVI.cc o suprressed some compile time warnings in bucketLib.c o cleaned up cxx templates README o removed use of tsMinMax from libCom in favor of the standard library (calls to tsMinMax still exist in other components in base, but they are being removed) o removed sharable library export of certain private member functions from class fdManager o fixed aToIPAddr to correctly lookup all of the different IP addresses string types on all OS types independent of the OS interfae variations o removed use of inet_aton from vxWorks implementation of hostToIPAddr o this function is for converting a host name to an ip address _only_ o the aToIPAddr wrapper is supposed to do the dotted ip ascii string to ip address structure conversion independent of OS spoecific interface variations, when it works correctly o fixed some spelling issues in comments o added additional optimizations for processors w/o floating point ALU to addNanoSec in epicsTime o removed tabs and junk comments from win32 osdProcess.c o moved PLL update in win32 osdTime.c from timer to a dedicated thread o added missing epicsExportShared symbols define to osiNTPTime.c o fixed server ctor should not modify arguments of its caller in blockingSockTest o removed sunpro specific ifdef nolomger needed from epicsTimeTest.cpp --- src/ca/legacy/pcas/generic/casPVI.cc | 5 +- src/libCom/bucketLib/bucketLib.c | 4 +- src/libCom/cxxTemplates/README | 24 +-- src/libCom/fdmgr/fdManager.cpp | 13 +- src/libCom/fdmgr/fdManager.h | 4 +- src/libCom/misc/aToIPAddr.c | 173 ++++++++++++++---- src/libCom/misc/ipAddrToAsciiAsynchronous.cpp | 4 +- src/libCom/osi/epicsThread.h | 9 +- src/libCom/osi/epicsTime.cpp | 106 +++++------ src/libCom/osi/epicsTime.h | 18 +- src/libCom/osi/os/WIN32/osdProcess.c | 138 +++++++------- src/libCom/osi/os/WIN32/osdTime.cpp | 120 ++++++++---- src/libCom/osi/os/vxWorks/osdSock.c | 13 +- src/libCom/osi/osiNTPTime.c | 1 + src/libCom/test/blockingSockTest.cpp | 109 ++++++----- src/libCom/test/epicsTimeTest.cpp | 7 +- 16 files changed, 432 insertions(+), 316 deletions(-) diff --git a/src/ca/legacy/pcas/generic/casPVI.cc b/src/ca/legacy/pcas/generic/casPVI.cc index 7f862a044..8702614be 100644 --- a/src/ca/legacy/pcas/generic/casPVI.cc +++ b/src/ca/legacy/pcas/generic/casPVI.cc @@ -211,9 +211,10 @@ void casPVI::updateEnumStringTableAsyncCompletion ( const gdd & resp ) } } else { - errMessage ( S_cas_badType, + errPrintf ( S_cas_badType, __FILE__, __LINE__, "application type \"enums\" string conversion" - " table for enumerated PV isnt a string type?" ); + " table for enumerated PV \"%s\" isnt a string type?", + getName() ); } } else if ( resp.dimension() == 1 ) { diff --git a/src/libCom/bucketLib/bucketLib.c b/src/libCom/bucketLib/bucketLib.c index 9fd887b6d..dc98b1aaf 100644 --- a/src/libCom/bucketLib/bucketLib.c +++ b/src/libCom/bucketLib/bucketLib.c @@ -144,7 +144,7 @@ static ITEM **bucketStringCompare (ITEM **ppi, const void *pId) */ static BUCKETID bucketUnsignedHash (BUCKET *pb, const void *pId) { - const unsigned *pUId = pId; + const unsigned *pUId = (const unsigned *) pId; unsigned src; BUCKETID hashid; @@ -194,7 +194,7 @@ static BUCKETID bucketPointerHash (BUCKET *pb, const void *pId) */ static BUCKETID bucketStringHash (BUCKET *pb, const void *pId) { - const char *pStr = pId; + const char *pStr = (const char *) pId; BUCKETID hashid; unsigned i; diff --git a/src/libCom/cxxTemplates/README b/src/libCom/cxxTemplates/README index ba9a29bb8..786c598b3 100644 --- a/src/libCom/cxxTemplates/README +++ b/src/libCom/cxxTemplates/README @@ -30,28 +30,6 @@ class "T" (the type stored in the hash table) must derive from class "ID" (the hash table key type) and also derive from tsSLNode. -So far, the only confusion I have run into with templates has been: - -1) strange compiler messages - unrelated to cause of course - -when I get the class declaration order wrong (so that the -compiler has trouble instantiating the template). - -2) sun pro/dec/att compilers use a template database and -gnu/msvc++ compilers use explicit template instantiation. -Therefore blocks of code of this sort are required: - -#include "resourceLib.h" // template def -#include "resourceLib.cc" // template functions (that are not inline) -#if defined (EXPL_TEMPL) - // - // From Stroustrups's "The C++ Programming Language" - // Appendix A: r.14.9 - // - // This explicitly instantiates the template class's member - // functions into "templInst.o" - // - template class resTable; - template class resTable; -#endif + diff --git a/src/libCom/fdmgr/fdManager.cpp b/src/libCom/fdmgr/fdManager.cpp index 113cc138d..8beafe8db 100644 --- a/src/libCom/fdmgr/fdManager.cpp +++ b/src/libCom/fdmgr/fdManager.cpp @@ -21,20 +21,17 @@ // 1) This library is not thread safe // -// -// ANSI C -// -#include -#include +#include #define instantiateRecourceLib #define epicsExportSharedSymbols #include "epicsAssert.h" #include "epicsThread.h" -#include "tsMinMax.h" #include "fdManager.h" #include "locationException.h" +using std :: max; + epicsShareDef fdManager fileDescriptorManager; const unsigned mSecPerSec = 1000u; @@ -261,9 +258,9 @@ void fdRegId::show ( unsigned level ) const // // fdManager::installReg () // -epicsShareFunc void fdManager::installReg (fdReg ®) +void fdManager::installReg (fdReg ®) { - this->maxFD = tsMax ( this->maxFD, reg.getFD()+1 ); + this->maxFD = max ( this->maxFD, reg.getFD()+1 ); // Most applications will find that its important to push here to // the front of the list so that transient writes get executed // first allowing incoming read protocol to find that outgoing diff --git a/src/libCom/fdmgr/fdManager.h b/src/libCom/fdmgr/fdManager.h index 694749448..621a004bc 100644 --- a/src/libCom/fdmgr/fdManager.h +++ b/src/libCom/fdmgr/fdManager.h @@ -104,8 +104,8 @@ private: fdReg * pCBReg; void reschedule (); double quantum (); - epicsShareFunc void installReg (fdReg ®); - epicsShareFunc void removeReg (fdReg ®); + void installReg (fdReg ®); + void removeReg (fdReg ®); void lazyInitTimerQueue (); fdManager ( const fdManager & ); fdManager & operator = ( const fdManager & ); diff --git a/src/libCom/misc/aToIPAddr.c b/src/libCom/misc/aToIPAddr.c index 104418fc1..7753675ee 100644 --- a/src/libCom/misc/aToIPAddr.c +++ b/src/libCom/misc/aToIPAddr.c @@ -1,8 +1,8 @@ /*************************************************************************\ +* Copyright (c) 2013 LANS LLC, as Operator of +* Los Alamos National Laboratory. * Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne * National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. * EPICS BASE is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. \*************************************************************************/ @@ -13,22 +13,51 @@ */ #include #include +#include #define epicsExportSharedSymbols #include "osiSock.h" -#include "epicsStdlib.h" + +#ifndef NELEMENTS +#define NELEMENTS(A) (sizeof(A)/sizeof(A[0])) +#endif /*NELEMENTS*/ + +/* + * addrArrayToUL () + */ +static int addrArrayToUL ( const unsigned *pAddr, + unsigned nElements, struct in_addr *pIpAddr ) +{ + unsigned i; + uint32_t addr = 0ul; + + for ( i=0u; i < nElements; i++ ) { + if ( pAddr[i] > 0xff ) { + return -1; + } + addr <<= 8; + addr |= ( uint32_t ) pAddr[i]; + } + pIpAddr->s_addr = htonl ( addr ); + + return 0; +} /* * initIPAddr() * !! ipAddr should be passed in in network byte order !! * !! port is passed in in host byte order !! */ -static int initIPAddr (struct in_addr ipAddr, unsigned short port, - struct sockaddr_in *pIP) +static int initIPAddr ( struct in_addr ipAddr, unsigned port, + struct sockaddr_in *pIP ) { - memset(pIP, '\0', sizeof(*pIP)); + if ( port > 0xffff ) { + return -1; + } + uint16_t port_16 = (uint16_t) port; + memset (pIP, '\0', sizeof(*pIP)); pIP->sin_family = AF_INET; - pIP->sin_port = htons(port); + pIP->sin_port = htons(port_16); pIP->sin_addr = ipAddr; return 0; } @@ -42,47 +71,121 @@ static int initIPAddr (struct in_addr ipAddr, unsigned short port, * * Sets the port number to "defaultPort" only if * "pAddrString" does not contain an address of the form - * "n.n.n.n:p" + * "n.n.n.n:p or host:p" */ -epicsShareFunc int epicsShareAPI -aToIPAddr(const char *pAddrString, unsigned short defaultPort, - struct sockaddr_in *pIP) +epicsShareFunc int epicsShareAPI +aToIPAddr( const char *pAddrString, unsigned short defaultPort, + struct sockaddr_in *pIP ) { int status; - char hostName[512]; /* !! change n elements here requires change in format below !! */ - unsigned int port; - unsigned long numaddr; + unsigned addr[4]; + unsigned long rawAddr; + /* + * !! change n elements here requires change in format below !! + */ + char hostName[512]; + char dummy[8]; + unsigned port; struct in_addr ina; /* - * Scan for a port number + * dotted ip addresses */ - status = sscanf( pAddrString, " %511[^:]:%u", hostName, &port ); - if ( status == 0 ) { - return -1; + status = sscanf ( pAddrString, " %u . %u . %u . %u %7s ", + addr, addr+1u, addr+2u, addr+3u, dummy ); + if ( status == 4 ) { + if ( addrArrayToUL ( addr, NELEMENTS ( addr ), & ina ) < 0 ) { + return -1; + } + port = defaultPort; + return initIPAddr ( ina, port, pIP ); } + + /* + * dotted ip addresses and port + */ + status = sscanf ( pAddrString, " %u . %u . %u . %u : %u %7s", + addr, addr+1u, addr+2u, addr+3u, &port, dummy ); + if ( status >= 5 ) { + if ( status > 5 ) { + /* + * valid at the start but detritus on the end + */ + return -1; + } + if ( addrArrayToUL ( addr, NELEMENTS ( addr ), &ina ) < 0 ) { + return -1; + } + return initIPAddr ( ina, port, pIP ); + } + + /* + * IP address as a raw number + */ + status = sscanf ( pAddrString, " %lu %7s ", &rawAddr, dummy ); + if ( status == 1 ) { + if ( rawAddr > 0xffffffff ) { + return -1; + } + port = defaultPort; + { + uint32_t rawAddr_32 = ( uint32_t ) rawAddr; + ina.s_addr = htonl ( rawAddr_32 ); + return initIPAddr ( ina, port, pIP ); + } + } + + /* + * IP address as a raw number, and port + */ + status = sscanf ( pAddrString, " %lu : %u %7s ", &rawAddr, &port, dummy ); + if ( status >= 2 ) { + if ( status > 2 ) { + /* + * valid at the start but detritus on the end + */ + return -1; + } + if ( rawAddr > 0xffffffff ) { + return -1; + } + { + uint32_t rawAddr_32 = ( uint32_t ) rawAddr; + ina.s_addr = htonl ( rawAddr_32 ); + return initIPAddr ( ina, port, pIP ); + } + } + + + /* + * host name string + */ + status = sscanf ( pAddrString, " %511[^:] %s ", hostName, dummy ); if ( status == 1 ) { port = defaultPort; + status = hostToIPAddr ( hostName, &ina ); + if ( status == 0 ) { + return initIPAddr ( ina, port, pIP ); + } } - else if (status == 2 && port > 65535) { - return -1; - } - + /* - * Look for a valid host name or dotted quad + * host name string, and port */ - status = hostToIPAddr( hostName, &ina ); - if ( status == 0 ) { - return initIPAddr( ina, port, pIP ); + status = sscanf ( pAddrString, " %511[^:] : %u %s ", hostName, + &port, dummy ); + if ( status >= 2 ) { + if ( status > 2 ) { + /* + * valid at the start but detritus on the end + */ + return -1; + } + status = hostToIPAddr ( hostName, &ina ); + if ( status == 0 ) { + return initIPAddr ( ina, port, pIP ); + } } - /* - * Try the IP address as a decimal integer - */ - if ( epicsParseULong( hostName, &numaddr, 10, NULL ) ) { - return -1; - } - - ina.s_addr = htonl( numaddr ); - return initIPAddr( ina, port, pIP ); + return -1; } diff --git a/src/libCom/misc/ipAddrToAsciiAsynchronous.cpp b/src/libCom/misc/ipAddrToAsciiAsynchronous.cpp index 91359d1f3..32e37d121 100644 --- a/src/libCom/misc/ipAddrToAsciiAsynchronous.cpp +++ b/src/libCom/misc/ipAddrToAsciiAsynchronous.cpp @@ -25,7 +25,7 @@ #include #include #include -#include +#include #define epicsExportSharedSymbols #include "ipAddrToAsciiAsynchronous.h" @@ -206,7 +206,7 @@ ipAddrToAsciiEnginePrivate::~ipAddrToAsciiEnginePrivate () this->thread.exitWait (); } -// for now its probably sufficent to allocate one +// for now its probably sufficient to allocate one // DNS transaction thread for all codes sharing // the same process that need DNS services but we // leave our options open for the future diff --git a/src/libCom/osi/epicsThread.h b/src/libCom/osi/epicsThread.h index d7be5d197..9102ec734 100644 --- a/src/libCom/osi/epicsThread.h +++ b/src/libCom/osi/epicsThread.h @@ -10,7 +10,12 @@ #ifndef epicsThreadh #define epicsThreadh +#ifdef __cplusplus +#include +using std :: size_t; +#else #include +#endif #include "shareLib.h" @@ -38,7 +43,9 @@ typedef void (*EPICSTHREADFUNC)(void *parm); /* stack sizes for each stackSizeClass are implementation and CPU dependent */ typedef enum { - epicsThreadStackSmall, epicsThreadStackMedium, epicsThreadStackBig + epicsThreadStackSmall, + epicsThreadStackMedium, + epicsThreadStackBig } epicsThreadStackSizeClass; typedef enum { diff --git a/src/libCom/osi/epicsTime.cpp b/src/libCom/osi/epicsTime.cpp index a137ebd03..684d26e23 100644 --- a/src/libCom/osi/epicsTime.cpp +++ b/src/libCom/osi/epicsTime.cpp @@ -1,8 +1,10 @@ /*************************************************************************\ -* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne -* National Laboratory. +* Copyright (c) 2011 LANS LLC, as Operator of +* Los Alamos National Laboratory. * Copyright (c) 2002 The Regents of the University of California, as * Operator of Los Alamos National Laboratory. +* Copyright (c) 2007 UChicago Argonne LLC, as Operator of Argonne +* National Laboratory. * EPICS BASE is distributed subject to a Software License Agreement found * in file LICENSE that is included with this distribution. \*************************************************************************/ @@ -58,8 +60,12 @@ static const unsigned long NTP_TIME_AT_EPICS_EPOCH = // // epicsTime (const unsigned long secIn, const unsigned long nSecIn) // -inline epicsTime::epicsTime (const unsigned long secIn, const unsigned long nSecIn) : - secPastEpoch ( nSecIn / nSecPerSec + secIn ), nSec ( nSecIn % nSecPerSec ) {} +inline epicsTime::epicsTime (const unsigned long secIn, + const unsigned long nSecIn) : + secPastEpoch ( nSecIn / nSecPerSec + secIn ), + nSec ( nSecIn % nSecPerSec ) +{ +} // // epicsTimeLoadTimeInit @@ -109,51 +115,45 @@ epicsTimeLoadTimeInit::epicsTimeLoadTimeInit () // // epicsTime::addNanoSec () // -// many of the UNIX timestamp formats have nano sec stored as a long +// The nano-second field of several of the the UNIX time stamp formats +// field is stored in the C type "long". // -void epicsTime::addNanoSec (long nSecAdj) +void epicsTime :: addNanoSec ( long nSecAdj ) { - // After optimizing this function we now have a larger - // code which uses only unsigned integer arithmetic. - // This is for the benefit of embedded cpu's lacking - // a hardware floating point coprocessor at the - // expense of some additional code to maintain. - // joh 14-11-2012 + // + // After optimizing this function we now have a larger code which + // uses only unsigned integer, and not floating point, arithmetic. + // This change benefits embedded CPU's lacking a floating point + // co-processor at the expense of some additional code to maintain. + // + // We hope that all CPU's we run on provide at least an integer + // divide instruction which should enable this implementation + // to be more efficient than implementations based on branching; + // this is presuming that we will run on pipelined architectures. + // + // Overflow and underflow is expected; in the future we might + // operate close to, the modulo of, the EPICS epic. + // + // We are depending on the normalize operation in the private + // constructor used below. + // + // joh 11-04-2012 + // if ( nSecAdj >= 0 ) { - unsigned long nSecOffsetLong = - static_cast < unsigned long > ( nSecAdj ); - while ( nSecOffsetLong >= nSecPerSec ) { - this->secPastEpoch++; // overflow expected - nSecOffsetLong -= nSecPerSec; - } - const epicsUInt32 nSecOffset = - static_cast < epicsUInt32 > ( nSecOffsetLong ); - epicsUInt32 nSecPerSecRemaining = nSecPerSec - nSecOffset; - if ( this->nSec >= nSecPerSecRemaining ) { - this->secPastEpoch++; // overflow expected - this->nSec -= nSecPerSecRemaining; - } - else { - this->nSec += nSecOffset; - } + const unsigned long nSecPlus = + static_cast ( nSecAdj ); + const unsigned long nSecPlusAdj = nSecPlus % nSecPerSec; + const unsigned long secPlusAdj = nSecPlus / nSecPerSec; + *this = epicsTime ( this->secPastEpoch+secPlusAdj, + this->nSec+nSecPlusAdj ); } else { - unsigned long nSecOffsetLong = - static_cast ( -nSecAdj ); - while ( nSecOffsetLong >= nSecPerSec ) { - this->secPastEpoch--; // underflow expected - nSecOffsetLong -= nSecPerSec; - } - const epicsUInt32 nSecOffset = - static_cast < epicsUInt32 > ( nSecOffsetLong ); - if ( this->nSec >= nSecOffset ) { - this->nSec -= nSecOffset; - } - else { - // borrow - this->secPastEpoch--; // underflow expected - this->nSec += nSecPerSec - nSecOffset; - } + const unsigned long nSecMinus = + static_cast ( -nSecAdj ); + const unsigned long nSecMinusAdj = nSecMinus % nSecPerSec; + const unsigned long secMinusAdj = nSecMinus / nSecPerSec; + *this = epicsTime ( this->secPastEpoch - secMinusAdj - 1u, + this->nSec + nSecPerSec - nSecMinusAdj ); } } @@ -368,8 +368,8 @@ epicsTime::operator struct timeval () const time_t_wrapper ansiTimeTicks; ansiTimeTicks = *this; - // On Posix systems timeval :: tv_sec is a time_t so this can be - // a direct assignement. On other systems I dont know that we can + // On Posix systems timeval :: tv_sec is a time_t so this can be + // a direct assignment. On other systems I dont know that we can // guarantee that time_t and timeval :: tv_sec will have the // same epoch or have the same scaling factor to discrete seconds. // For example, on windows time_t changed recently to a 64 bit @@ -387,8 +387,8 @@ epicsTime::operator struct timeval () const epicsTime::epicsTime (const struct timeval &ts) { time_t_wrapper ansiTimeTicks; - // On Posix systems timeval :: tv_sec is a time_t so this can be - // a direct assignement. On other systems I dont know that we can + // On Posix systems timeval :: tv_sec is a time_t so this can be + // a direct assignment. On other systems I dont know that we can // guarantee that time_t and timeval :: tv_sec will have the // same epoch or have the same scaling factor to discrete seconds. // For example, on windows time_t changed recently to a 64 bit @@ -438,11 +438,11 @@ epicsTime::operator epicsTimeStamp () const } epicsTimeStamp ts; // - // trucation by design + // truncation by design // ------------------- - // epicsTime::secPastEpoch is based on ulong and has much greater range - // on 64 bit hosts than the orginal epicsTimeStamp::secPastEpoch. The - // epicsTimeStamp::secPastEpoch is based on epicsUInt32 so that it will + // epicsTime::secPastEpoch is based on ulong and has much greater range + // on 64 bit hosts than the original epicsTimeStamp::secPastEpoch. The + // epicsTimeStamp::secPastEpoch is based on epicsUInt32 so that it will // match the original network protocol. Of course one can anticipate // that eventually, a epicsUInt64 based network time stamp will be // introduced when 64 bit architectures are more ubiquitous. @@ -653,7 +653,7 @@ void epicsTime::show ( unsigned level ) const } if ( level > 1 ) { - // this also supresses the "defined, but not used" + // this also suppresses the "defined, but not used" // warning message printf ( "epicsTime: revision \"%s\"\n", pEpicsTimeVersion ); diff --git a/src/libCom/osi/epicsTime.h b/src/libCom/osi/epicsTime.h index a36d6afe3..3f83d74d4 100644 --- a/src/libCom/osi/epicsTime.h +++ b/src/libCom/osi/epicsTime.h @@ -12,7 +12,11 @@ #ifndef epicsTimehInclude #define epicsTimehInclude -#include +#ifdef __cplusplus +# include +#else +# include +#endif #include "shareLib.h" #include "epicsTypes.h" @@ -42,7 +46,7 @@ struct l_fp; /* NTP timestamp */ * and a struct tm that is adjusted for the local timezone */ struct local_tm_nano_sec { - struct tm ansi_tm; /* ANSI C time details */ + std :: tm ansi_tm; /* ANSI C time details */ unsigned long nSec; /* nano seconds extension */ }; @@ -51,7 +55,7 @@ struct local_tm_nano_sec { * and a struct tm that is adjusted for GMT (UTC) */ struct gm_tm_nano_sec { - struct tm ansi_tm; /* ANSI C time details */ + std :: tm ansi_tm; /* ANSI C time details */ unsigned long nSec; /* nano seconds extension */ }; @@ -61,7 +65,7 @@ struct gm_tm_nano_sec { * conversions to occur */ struct time_t_wrapper { - time_t ts; + std :: time_t ts; }; class epicsShareClass epicsTimeEvent @@ -244,8 +248,10 @@ epicsShareFunc void epicsShareAPI epicsTimeShow ( /* OS dependent reentrant versions of the ANSI C interface because */ /* vxWorks gmtime_r interface does not match POSIX standards */ -epicsShareFunc int epicsShareAPI epicsTime_localtime ( const time_t * clock, struct tm * result ); -epicsShareFunc int epicsShareAPI epicsTime_gmtime ( const time_t * clock, struct tm * result ); +epicsShareFunc int epicsShareAPI + epicsTime_localtime ( const time_t * clock, struct tm * result ); +epicsShareFunc int epicsShareAPI + epicsTime_gmtime ( const time_t * clock, struct tm * result ); #ifdef __cplusplus } diff --git a/src/libCom/osi/os/WIN32/osdProcess.c b/src/libCom/osi/os/WIN32/osdProcess.c index fd680307d..f2d67ff2a 100644 --- a/src/libCom/osi/os/WIN32/osdProcess.c +++ b/src/libCom/osi/os/WIN32/osdProcess.c @@ -64,90 +64,76 @@ epicsShareFunc osiSpawnDetachedProcessReturn epicsShareAPI osiSpawnDetachedProce startupInfo.wShowWindow = SW_SHOWMINNOACTIVE; status = CreateProcess ( - NULL, /* pointer to name of executable module (not required if command line is specified) */ - (char *) pBaseExecutableName, /* pointer to command line string */ - NULL, /* pointer to process security attributes */ - NULL, /* pointer to thread security attributes */ - FALSE, /* handle inheritance flag */ - CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS, /* creation flags */ - NULL, /* pointer to new environment block (defaults to caller's environement) */ - NULL, /* pointer to current directory name (defaults to caller's current directory) */ - &startupInfo, /* pointer to STARTUPINFO */ - &processInfo /* pointer to PROCESS_INFORMATION */ - ); - if ( status == 0 ) { - DWORD W32status; - LPVOID errStrMsgBuf; - LPVOID complteMsgBuf; + NULL, /* pointer to name of executable module (not required if command line is specified) */ + (char *) pBaseExecutableName, /* pointer to command line string */ + NULL, /* pointer to process security attributes */ + NULL, /* pointer to thread security attributes */ + FALSE, /* handle inheritance flag */ + CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS, /* creation flags */ + NULL, /* pointer to new environment block (defaults to caller's environement) */ + NULL, /* pointer to current directory name (defaults to caller's current directory) */ + &startupInfo, /* pointer to STARTUPINFO */ + &processInfo /* pointer to PROCESS_INFORMATION */ + ); + if ( status == 0 ) { + DWORD W32status; + LPVOID errStrMsgBuf; + LPVOID complteMsgBuf; + + W32status = FormatMessage ( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + GetLastError (), + MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ + (LPTSTR) &errStrMsgBuf, + 0, + NULL + ); - W32status = FormatMessage ( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - GetLastError (), - MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ - (LPTSTR) &errStrMsgBuf, - 0, - NULL - ); - - if ( W32status ) { - char *pFmtArgs[6]; + if ( W32status ) { + char *pFmtArgs[6]; pFmtArgs[0] = "Failed to start executable -"; pFmtArgs[1] = (char *) pBaseExecutableName; pFmtArgs[2] = errStrMsgBuf; pFmtArgs[3] = "Changes may be required in your \"path\" environment variable."; pFmtArgs[4] = "PATH = "; pFmtArgs[5] = getenv ("path"); - if ( pFmtArgs[5] == NULL ) { - pFmtArgs[5] = ""; - } - - W32status = FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING | - FORMAT_MESSAGE_ARGUMENT_ARRAY | 80, - "%1 \"%2\". %3 %4 %5 \"%6\"", - 0, - MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ - (LPTSTR) &complteMsgBuf, - 0, - pFmtArgs - ); - if (W32status) { - /* Display the string. */ - MessageBox (NULL, complteMsgBuf, "Configuration Problem", - MB_OK | MB_ICONINFORMATION); - LocalFree (complteMsgBuf); - } - else { - /* Display the string. */ - MessageBox (NULL, errStrMsgBuf, "Failed to start executable", - MB_OK | MB_ICONINFORMATION); - } - - /* Free the buffer. */ - LocalFree (errStrMsgBuf); - } - else { - errlogPrintf ("!!WARNING!!\n"); - errlogPrintf ("Unable to locate executable \"%s\".\n", pBaseExecutableName); - errlogPrintf ("You may need to modify your environment.\n"); - } + if ( pFmtArgs[5] == NULL ) { + pFmtArgs[5] = ""; + } + + W32status = FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING | + FORMAT_MESSAGE_ARGUMENT_ARRAY | 80, + "%1 \"%2\". %3 %4 %5 \"%6\"", + 0, + MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ + (LPTSTR) &complteMsgBuf, + 0, + pFmtArgs + ); + if (W32status) { + /* Display the string. */ + MessageBox (NULL, complteMsgBuf, "Configuration Problem", + MB_OK | MB_ICONINFORMATION); + LocalFree (complteMsgBuf); + } + else { + /* Display the string. */ + MessageBox (NULL, errStrMsgBuf, "Failed to start executable", + MB_OK | MB_ICONINFORMATION); + } + + /* Free the buffer. */ + LocalFree (errStrMsgBuf); + } + else { + errlogPrintf ("!!WARNING!!\n"); + errlogPrintf ("Unable to locate executable \"%s\".\n", pBaseExecutableName); + errlogPrintf ("You may need to modify your \"path\"venvironment variable.\n"); + } return osiSpawnDetachedProcessFail; - } + } return osiSpawnDetachedProcessSuccess; - - /* - use of spawn here causes problems when the ca repeater - inherits open files (and sockets) from the spawning - process - - status = _spawnlp (_P_DETACH, pBaseExecutableName, pBaseExecutableName, NULL); - if (status<0) { - errlogPrintf ("!!WARNING!!\n"); - errlogPrintf ("Unable to locate the EPICS executable \"%s\".\n", - pBaseExecutableName); - errlogPrintf ("You may need to modify your environment.\n"); - } - */ } diff --git a/src/libCom/osi/os/WIN32/osdTime.cpp b/src/libCom/osi/os/WIN32/osdTime.cpp index 33a63b873..877311ffa 100644 --- a/src/libCom/osi/os/WIN32/osdTime.cpp +++ b/src/libCom/osi/os/WIN32/osdTime.cpp @@ -17,10 +17,10 @@ // // ANSI C // -#include -#include -#include -#include +#include +#include +#include +#include // // WIN32 @@ -28,6 +28,7 @@ #define VC_EXTRALEAN #define STRICT #include +#include // // EPICS @@ -46,19 +47,26 @@ # define debugPrintf(argsInParen) #endif +extern "C" void setThreadName ( DWORD dwThreadID, LPCSTR szThreadName ); + static int osdTimeGetCurrent ( epicsTimeStamp *pDest ); // for mingw #if !defined ( MAXLONGLONG ) -#define MAXLONGLONG 0x7fffffffffffffffLL +# define MAXLONGLONG 0x7fffffffffffffffLL #endif #if !defined ( MINLONGLONG ) -#define MINLONGLONG (~0x7fffffffffffffffLL) +# define MINLONGLONG ~0x7fffffffffffffffLL +#endif +#ifndef STACK_SIZE_PARAM_IS_A_RESERVATION +# define STACK_SIZE_PARAM_IS_A_RESERVATION 0x00010000 #endif static const LONGLONG epicsEpochInFileTime = 0x01b41e2a18d64000LL; -class currentTime : public epicsTimerNotify { +static unsigned __stdcall _pllThreadEntry ( void * pCurrentTimeIn ); + +class currentTime { public: currentTime (); ~currentTime (); @@ -72,20 +80,24 @@ private: LONGLONG perfCounterFreqPLL; LONGLONG lastPerfCounterPLL; LONGLONG lastFileTimePLL; - epicsTimerQueueActive * pTimerQueue; - epicsTimer * pTimer; + HANDLE threadHandle; + unsigned threadId; bool perfCtrPresent; + bool threadShutdownCmd; + bool threadHasExited; + void updatePLL (); static const int pllDelay; /* integer seconds */ - epicsTimerNotify::expireStatus expire ( const epicsTime & ); + // cant be static because of diff btw __stdcall and __cdecl + friend unsigned __stdcall _pllThreadEntry ( void * pCurrentTimeIn ); }; +const int currentTime :: pllDelay = 5; + static currentTime * pCurrentTime = 0; static const LONGLONG FILE_TIME_TICKS_PER_SEC = 10000000; static const LONGLONG EPICS_TIME_TICKS_PER_SEC = 1000000000; static const LONGLONG ET_TICKS_PER_FT_TICK = EPICS_TIME_TICKS_PER_SEC / FILE_TIME_TICKS_PER_SEC; - -const int currentTime :: pllDelay = 5; // // Start and register time provider @@ -185,8 +197,8 @@ int epicsShareAPI epicsTime_localtime ( } // - // There are remarkable weaknessess in the FileTimeToLocalFileTime - // interface so we dont use it here. Unfortunately, there is no + // There are remarkable weaknesses in the FileTimeToLocalFileTime + // interface so we don't use it here. Unfortunately, there is no // corresponding function that works on file time. // SYSTEMTIME st; @@ -263,9 +275,11 @@ currentTime::currentTime () : perfCounterFreqPLL ( 0 ), lastPerfCounterPLL ( 0 ), lastFileTimePLL ( 0 ), - pTimerQueue ( 0 ), - pTimer ( 0 ), - perfCtrPresent ( false ) + threadHandle ( 0 ), + threadId ( 0 ), + perfCtrPresent ( false ), + threadShutdownCmd ( false ), + threadHasExited ( false ) { InitializeCriticalSection ( & this->mutex ); @@ -308,15 +322,34 @@ currentTime::currentTime () : this->lastFileTimePLL = liFileTime.QuadPart; } +void currentTime :: startPLL () +{ + // create frequency estimation thread when needed + if ( this->perfCtrPresent && ! this->threadHandle ) { + this->threadHandle = (HANDLE) + _beginthreadex ( 0, 4096, _pllThreadEntry, this, + CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION, + & this->threadId ); + assert ( this->threadHandle ); + BOOL bstat = SetThreadPriority ( + this->threadHandle, THREAD_PRIORITY_HIGHEST ); + assert ( bstat ); + DWORD wstat = ResumeThread ( this->threadHandle ); + assert ( wstat != 0xFFFFFFFF ); + } +} + currentTime::~currentTime () { + EnterCriticalSection ( & this->mutex ); + this->threadShutdownCmd = true; + while ( ! this->threadHasExited ) { + LeaveCriticalSection ( & this->mutex ); + Sleep ( 250 /* mS */ ); + EnterCriticalSection ( & this->mutex ); + } + LeaveCriticalSection ( & this->mutex ); DeleteCriticalSection ( & this->mutex ); - if ( this->pTimer ) { - this->pTimer->destroy (); - } - if ( this->pTimerQueue ) { - this->pTimerQueue->release (); - } } void currentTime::getCurrentTime ( epicsTimeStamp & dest ) @@ -386,7 +419,7 @@ void currentTime::getCurrentTime ( epicsTimeStamp & dest ) // Maintain corrected version of the performance counter's frequency using // a phase locked loop. This approach is similar to NTP's. // -epicsTimerNotify::expireStatus currentTime::expire ( const epicsTime & ) +void currentTime :: updatePLL () { EnterCriticalSection ( & this->mutex ); @@ -431,7 +464,7 @@ epicsTimerNotify::expireStatus currentTime::expire ( const epicsTime & ) if ( fileTimeDiff <= 0 ) { LeaveCriticalSection( & this->mutex ); debugPrintf ( ( "currentTime: file time difference in PLL was less than zero\n" ) ); - return expireStatus ( restart, pllDelay /* sec */ ); + return; } LONGLONG freq = ( FILE_TIME_TICKS_PER_SEC * perfCounterDiff ) / fileTimeDiff; @@ -445,7 +478,7 @@ epicsTimerNotify::expireStatus currentTime::expire ( const epicsTime & ) static_cast < int > ( -bound ), static_cast < int > ( delta ), static_cast < int > ( bound ) ) ); - return expireStatus ( restart, pllDelay /* sec */ ); + return; } // update feedback loop estimating the performance counter's frequency @@ -482,7 +515,7 @@ epicsTimerNotify::expireStatus currentTime::expire ( const epicsTime & ) debugPrintf ( ( "perf ctr measured delay out of bounds m=%d max=%d\n", static_cast < int > ( perfCounterDiffSinceLastFetch ), static_cast < int > ( expectedDly + bnd ) ) ); - return expireStatus ( restart, pllDelay /* sec */ ); + return; } } @@ -521,9 +554,9 @@ epicsTimerNotify::expireStatus currentTime::expire ( const epicsTime & ) delta = epicsTimeFromCurrentFileTime - this->epicsTimeLast; if ( delta > EPICS_TIME_TICKS_PER_SEC || delta < -EPICS_TIME_TICKS_PER_SEC ) { - // When there is an abrupt shift in the current computed time vs - // the time derived from the current file time then someone has - // probabably adjusted the real time clock and the best reaction + // When there is an abrupt shift in the current computed time vs + // the time derived from the current file time then someone has + // probably adjusted the real time clock and the best reaction // is to just assume the new time base this->epicsTimeLast = epicsTimeFromCurrentFileTime; this->perfCounterFreq = this->perfCounterFreqPLL; @@ -563,24 +596,31 @@ epicsTimerNotify::expireStatus currentTime::expire ( const epicsTime & ) ( this->perfCounterFreqPLL - sysFreq.QuadPart ); freqEstDiff /= sysFreq.QuadPart; freqEstDiff *= 100.0; - debugPrintf ( ( "currentTime: freq delta %f %% freq est delta %f %% time delta %f sec\n", - freqDiff, freqEstDiff, static_cast < double > ( delta ) / EPICS_TIME_TICKS_PER_SEC ) ); + debugPrintf ( ( "currentTime: freq delta %f %% freq est " + "delta %f %% time delta %f sec\n", + freqDiff, + freqEstDiff, + static_cast < double > ( delta ) / + EPICS_TIME_TICKS_PER_SEC ) ); # endif } LeaveCriticalSection ( & this->mutex ); - - return expireStatus ( restart, pllDelay /* sec */ ); } -void currentTime::startPLL () +static unsigned __stdcall _pllThreadEntry ( void * pCurrentTimeIn ) { - // create frequency estimation timer when needed - if ( this->perfCtrPresent && ! this->pTimerQueue ) { - this->pTimerQueue = & epicsTimerQueueActive::allocate ( true ); - this->pTimer = & this->pTimerQueue->createTimer (); - this->pTimer->start ( *this, pllDelay ); + currentTime * pCT = + reinterpret_cast < currentTime * > ( pCurrentTimeIn ); + setThreadName ( pCT->threadId, "EPICS Time PLL" ); + while ( ! pCT->threadShutdownCmd ) { + Sleep ( currentTime :: pllDelay * 1000 /* mS */ ); + pCT->updatePLL (); } + EnterCriticalSection ( & pCT->mutex ); + pCT->threadHasExited = true; + LeaveCriticalSection ( & pCT->mutex ); + return 1; } epicsTime::operator FILETIME () const diff --git a/src/libCom/osi/os/vxWorks/osdSock.c b/src/libCom/osi/os/vxWorks/osdSock.c index 13798803b..a0f5e8ec5 100644 --- a/src/libCom/osi/os/vxWorks/osdSock.c +++ b/src/libCom/osi/os/vxWorks/osdSock.c @@ -115,18 +115,11 @@ epicsShareFunc unsigned epicsShareAPI ipAddrToHostName epicsShareFunc int epicsShareAPI hostToIPAddr(const char *pHostName, struct in_addr *pIPA) { - int addr; - - addr = hostGetByName((char *)pHostName); - if (addr != ERROR) { - pIPA->s_addr = (unsigned long) addr; - } - else if (inet_aton((char *)pHostName, pIPA) == ERROR) { - /* - * return indicating an error - */ + int addr = hostGetByName ( (char *) pHostName ); + if ( addr == ERROR ) { return -1; } + pIPA->s_addr = (unsigned long) addr; /* * success diff --git a/src/libCom/osi/osiNTPTime.c b/src/libCom/osi/osiNTPTime.c index d085cca31..be22c22d2 100644 --- a/src/libCom/osi/osiNTPTime.c +++ b/src/libCom/osi/osiNTPTime.c @@ -18,6 +18,7 @@ #include #include +#define epicsExportSharedSymbos #include "epicsEvent.h" #include "epicsExit.h" #include "epicsTypes.h" diff --git a/src/libCom/test/blockingSockTest.cpp b/src/libCom/test/blockingSockTest.cpp index fa0a8d626..17e46ad15 100644 --- a/src/libCom/test/blockingSockTest.cpp +++ b/src/libCom/test/blockingSockTest.cpp @@ -22,8 +22,8 @@ epicsAssert(__FILE__, __LINE__, #exp, epicsAssertAuthor)) union address { - struct sockaddr_in ia; - struct sockaddr sa; + struct sockaddr_in m_ia; + struct sockaddr m_sa; }; class circuit { @@ -37,10 +37,10 @@ public: bool sendWakeupDetected () const; virtual const char * pName () = 0; protected: - SOCKET sock; - epicsThreadId id; - bool recvWakeup; - bool sendWakeup; + SOCKET m_sock; + epicsThreadId m_id; + bool m_recvWakeup; + bool m_sendWakeup; protected: virtual ~circuit() {} }; @@ -61,48 +61,50 @@ private: class server { public: - server ( address & ); + server ( const address & ); void start (); void daemon (); + address addr () const; protected: - SOCKET sock; - epicsThreadId id; - bool exit; + address m_addr; + SOCKET m_sock; + epicsThreadId m_id; + bool m_exit; }; circuit::circuit ( SOCKET sockIn ) : - sock ( sockIn ), - id ( 0 ), - recvWakeup ( false ), - sendWakeup ( false ) + m_sock ( sockIn ), + m_id ( 0 ), + m_recvWakeup ( false ), + m_sendWakeup ( false ) { - verify ( this->sock != INVALID_SOCKET ); + verify ( m_sock != INVALID_SOCKET ); } bool circuit::recvWakeupDetected () const { - return this->recvWakeup; + return m_recvWakeup; } bool circuit::sendWakeupDetected () const { - return this->sendWakeup; + return m_sendWakeup; } void circuit::shutdown () { - int status = ::shutdown ( this->sock, SHUT_RDWR ); + int status = ::shutdown ( m_sock, SHUT_RDWR ); verify ( status == 0 ); } void circuit::signal () { - epicsSignalRaiseSigAlarm ( this->id ); + epicsSignalRaiseSigAlarm ( m_id ); } void circuit::close () { - epicsSocketDestroy ( this->sock ); + epicsSocketDestroy ( m_sock ); } void circuit::recvTest () @@ -110,11 +112,11 @@ void circuit::recvTest () epicsSignalInstallSigAlarmIgnore (); char buf [1]; while ( true ) { - int status = recv ( this->sock, + int status = recv ( m_sock, buf, (int) sizeof ( buf ), 0 ); if ( status == 0 ) { testDiag ( "%s was disconnected", this->pName () ); - this->recvWakeup = true; + m_recvWakeup = true; break; } else if ( status > 0 ) { @@ -126,7 +128,7 @@ void circuit::recvTest () sockErrBuf, sizeof ( sockErrBuf ) ); testDiag ( "%s socket recv() error was \"%s\"\n", this->pName (), sockErrBuf ); - this->recvWakeup = true; + m_recvWakeup = true; break; } } @@ -143,15 +145,15 @@ clientCircuit::clientCircuit ( const address & addrIn ) : { address tmpAddr = addrIn; int status = ::connect ( - this->sock, & tmpAddr.sa, sizeof ( tmpAddr ) ); + m_sock, & tmpAddr.m_sa, sizeof ( tmpAddr ) ); verify ( status == 0 ); circuit * pCir = this; - this->id = epicsThreadCreate ( + m_id = epicsThreadCreate ( "client circuit", epicsThreadPriorityMedium, epicsThreadGetStackSize(epicsThreadStackMedium), socketRecvTest, pCir ); - verify ( this->id ); + verify ( m_id ); } @@ -165,56 +167,62 @@ extern "C" void serverDaemon ( void * pParam ) { pSrv->daemon (); } -server::server ( address & addrIn ) : - sock ( epicsSocketCreate ( AF_INET, SOCK_STREAM, IPPROTO_TCP ) ), - id ( 0 ), exit ( false ) +server::server ( const address & addrIn ) : + m_addr ( addrIn ), + m_sock ( epicsSocketCreate ( AF_INET, SOCK_STREAM, IPPROTO_TCP ) ), + m_id ( 0 ), m_exit ( false ) { - verify ( this->sock != INVALID_SOCKET ); + verify ( m_sock != INVALID_SOCKET ); // setup server side - int status = bind ( this->sock, - & addrIn.sa, sizeof ( addrIn ) ); + int status = bind ( m_sock, + & m_addr.m_sa, sizeof ( m_addr ) ); if ( status ) { testDiag ( "bind to server socket failed, status = %d", status ); } - osiSocklen_t slen = sizeof ( addrIn ); - if ( getsockname(this->sock, &addrIn.sa, &slen) != 0 ) { + osiSocklen_t slen = sizeof ( m_addr ); + if ( getsockname(m_sock, &m_addr.m_sa, &slen) != 0 ) { testAbort ( "Failed to read socket address" ); } - status = listen ( this->sock, 10 ); + status = listen ( m_sock, 10 ); verify ( status == 0 ); } void server::start () { - this->id = epicsThreadCreate ( - "server daemon", epicsThreadPriorityMedium, - epicsThreadGetStackSize(epicsThreadStackMedium), + m_id = epicsThreadCreate ( + "server daemon", epicsThreadPriorityMedium, + epicsThreadGetStackSize(epicsThreadStackMedium), serverDaemon, this ); - verify ( this->id ); + verify ( m_id ); } -void server::daemon () +void server::daemon () { - while ( ! this->exit ) { + while ( ! m_exit ) { // accept client side address addr; osiSocklen_t addressSize = sizeof ( addr ); - SOCKET ns = accept ( this->sock, - & addr.sa, & addressSize ); + SOCKET ns = accept ( m_sock, + & m_addr.m_sa, & addressSize ); verify ( ns != INVALID_SOCKET ); circuit * pCir = new serverCircuit ( ns ); verify ( pCir ); } } +address server::addr () const +{ + return m_addr; +} + serverCircuit::serverCircuit ( SOCKET sockIn ) : circuit ( sockIn ) { circuit * pCir = this; - epicsThreadId threadId = epicsThreadCreate ( - "server circuit", epicsThreadPriorityMedium, - epicsThreadGetStackSize(epicsThreadStackMedium), + epicsThreadId threadId = epicsThreadCreate ( + "server circuit", epicsThreadPriorityMedium, + epicsThreadGetStackSize(epicsThreadStackMedium), socketRecvTest, pCir ); verify ( threadId ); } @@ -235,7 +243,7 @@ static const char *mechName(int mech) {esscimqi_socketBothShutdownRequired, "esscimqi_socketBothShutdownRequired" }, {esscimqi_socketSigAlarmRequired, "esscimqi_socketSigAlarmRequired" } }; - + for (unsigned i=0; i < (sizeof(mechs) / sizeof(mechs[0])); ++i) { if (mech == mechs[i].mech) return mechs[i].name; @@ -249,12 +257,13 @@ MAIN(blockingSockTest) address addr; memset ( (char *) & addr, 0, sizeof ( addr ) ); - addr.ia.sin_family = AF_INET; - addr.ia.sin_addr.s_addr = htonl ( INADDR_LOOPBACK ); - addr.ia.sin_port = 0; + addr.m_ia.sin_family = AF_INET; + addr.m_ia.sin_addr.s_addr = htonl ( INADDR_LOOPBACK ); + addr.m_ia.sin_port = 0; server srv ( addr ); srv.start (); + addr = srv.addr (); clientCircuit client ( addr ); epicsThreadSleep ( 1.0 ); diff --git a/src/libCom/test/epicsTimeTest.cpp b/src/libCom/test/epicsTimeTest.cpp index c108eca7f..416e63a09 100644 --- a/src/libCom/test/epicsTimeTest.cpp +++ b/src/libCom/test/epicsTimeTest.cpp @@ -9,11 +9,6 @@ /* * Authors: Jeff Hill, Marty Kraimer and Andrew Johnson */ - -#ifdef __SUNPRO_CC -using namespace std; -#endif - #include #include #include @@ -45,7 +40,7 @@ static const double precisionEPICS = 1.0 / nSecPerSec; MAIN(epicsTimeTest) { - const int wasteTime = 100000; + const int wasteTime = 100000u; const int nTimes = 10; testPlan(12 + nTimes * 18); From 36d801682b50d9f117a9b7548e6990b03575d0c8 Mon Sep 17 00:00:00 2001 From: Jeff Hill Date: Thu, 7 Nov 2013 14:59:30 -0700 Subject: [PATCH 2/7] oops, variable used to be unsigned; changed to signed constant --- src/libCom/test/epicsTimeTest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libCom/test/epicsTimeTest.cpp b/src/libCom/test/epicsTimeTest.cpp index 416e63a09..d1ade8e10 100644 --- a/src/libCom/test/epicsTimeTest.cpp +++ b/src/libCom/test/epicsTimeTest.cpp @@ -40,7 +40,7 @@ static const double precisionEPICS = 1.0 / nSecPerSec; MAIN(epicsTimeTest) { - const int wasteTime = 100000u; + const int wasteTime = 100000; const int nTimes = 10; testPlan(12 + nTimes * 18); From 6f67091628bdb2a46346e80598ec0f2b7268c357 Mon Sep 17 00:00:00 2001 From: Jeff Hill Date: Thu, 7 Nov 2013 17:37:17 -0700 Subject: [PATCH 3/7] fixed ms compiler build --- src/libCom/misc/aToIPAddr.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/libCom/misc/aToIPAddr.c b/src/libCom/misc/aToIPAddr.c index 7753675ee..e7f9b49c5 100644 --- a/src/libCom/misc/aToIPAddr.c +++ b/src/libCom/misc/aToIPAddr.c @@ -54,11 +54,13 @@ static int initIPAddr ( struct in_addr ipAddr, unsigned port, if ( port > 0xffff ) { return -1; } - uint16_t port_16 = (uint16_t) port; - memset (pIP, '\0', sizeof(*pIP)); - pIP->sin_family = AF_INET; - pIP->sin_port = htons(port_16); - pIP->sin_addr = ipAddr; + { + uint16_t port_16 = (uint16_t) port; + memset (pIP, '\0', sizeof(*pIP)); + pIP->sin_family = AF_INET; + pIP->sin_port = htons(port_16); + pIP->sin_addr = ipAddr; + } return 0; } From f1a59aa64a9985a93be8a59b0fcaa4a18f71fa32 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Sat, 2 Aug 2014 13:09:07 -0500 Subject: [PATCH 4/7] Use epicsUInt types, stdint.h is not found on all platforms --- src/libCom/misc/aToIPAddr.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libCom/misc/aToIPAddr.c b/src/libCom/misc/aToIPAddr.c index e7f9b49c5..c21b574f6 100644 --- a/src/libCom/misc/aToIPAddr.c +++ b/src/libCom/misc/aToIPAddr.c @@ -13,9 +13,9 @@ */ #include #include -#include #define epicsExportSharedSymbols +#include "epicsTypes.h" #include "osiSock.h" #ifndef NELEMENTS @@ -29,14 +29,14 @@ static int addrArrayToUL ( const unsigned *pAddr, unsigned nElements, struct in_addr *pIpAddr ) { unsigned i; - uint32_t addr = 0ul; + epicsUInt32 addr = 0ul; for ( i=0u; i < nElements; i++ ) { if ( pAddr[i] > 0xff ) { return -1; } addr <<= 8; - addr |= ( uint32_t ) pAddr[i]; + addr |= ( epicsUInt32 ) pAddr[i]; } pIpAddr->s_addr = htonl ( addr ); @@ -55,7 +55,7 @@ static int initIPAddr ( struct in_addr ipAddr, unsigned port, return -1; } { - uint16_t port_16 = (uint16_t) port; + epicsUInt16 port_16 = (epicsUInt16) port; memset (pIP, '\0', sizeof(*pIP)); pIP->sin_family = AF_INET; pIP->sin_port = htons(port_16); @@ -131,7 +131,7 @@ aToIPAddr( const char *pAddrString, unsigned short defaultPort, } port = defaultPort; { - uint32_t rawAddr_32 = ( uint32_t ) rawAddr; + epicsUInt32 rawAddr_32 = ( epicsUInt32 ) rawAddr; ina.s_addr = htonl ( rawAddr_32 ); return initIPAddr ( ina, port, pIP ); } @@ -152,7 +152,7 @@ aToIPAddr( const char *pAddrString, unsigned short defaultPort, return -1; } { - uint32_t rawAddr_32 = ( uint32_t ) rawAddr; + epicsUInt32 rawAddr_32 = ( epicsUInt32 ) rawAddr; ina.s_addr = htonl ( rawAddr_32 ); return initIPAddr ( ina, port, pIP ); } From 8d5cdc37475fd05d0e5d241c618c2467d7324e87 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Sat, 2 Aug 2014 13:13:49 -0500 Subject: [PATCH 5/7] Fix typo in macro name Not that it really matters since only VxWorks and RTEMS actually compile this file and they don't have shared libraries... --- src/libCom/osi/osiNTPTime.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libCom/osi/osiNTPTime.c b/src/libCom/osi/osiNTPTime.c index be22c22d2..42b7a390c 100644 --- a/src/libCom/osi/osiNTPTime.c +++ b/src/libCom/osi/osiNTPTime.c @@ -18,7 +18,7 @@ #include #include -#define epicsExportSharedSymbos +#define epicsExportSharedSymbols #include "epicsEvent.h" #include "epicsExit.h" #include "epicsTypes.h" From b7f8f172273c3580c57be9b24c6cc6cb16573377 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Sat, 2 Aug 2014 14:02:43 -0500 Subject: [PATCH 6/7] blockingSockTest: Undo member renames using m_ prefix Using the m_ prefix to denote class data members is dangerous in code that has to compile on VxWorks 5.5 (which 3.15 does) because the net/mbuf.h header contains the following macro definitions: #define m_next mBlkHdr.mNext #define m_len mBlkHdr.mLen #define m_data mBlkHdr.mData #define m_type mBlkHdr.mType #define m_flags mBlkHdr.mFlags #define m_nextpkt mBlkHdr.mNextPkt #define m_act m_nextpkt #define m_pkthdr mBlkPktHdr #define m_ext pClBlk #define m_extBuf m_ext->clNode.pClBuf #define m_extFreeRtn m_ext->pClFreeRtn #define m_extSize m_ext->clSize #define m_extRefCnt m_ext->clRefCnt #define m_extArg1 m_ext->clFreeArg1 #define m_extArg2 m_ext->clFreeArg2 #define m_extArg3 m_ext->clFreeArg3 #define m_copy(m, o, l) m_copym((m), (o), (l), M_DONTWAIT) #define m_copym(m, o, l, w) netMblkChainDup(_pNetDpool, (m), (o), (l), (w)) #define m_freem(m) netMblkClChainFree(m) #define m_free(m) netMblkClFree(m) #define m_mbufs mNum #define m_drops mDrops #define m_wait mWait #define m_drain mDrain #define m_mtypes mTypes While the names in the original change all appear to be safe, I don't want us to start using this convention because we will then have to police commits more closely or risk build failures in the future when someone who doesn't know about or remember the issue can't or doesn't try building their code against VxWorks 5.5. I don't particularly like the this-> convention to mark member names either, but until the VxWorks 5.5 support requirement goes away the m_ convention is worse. Another common convention of using a leading underscore is not safe either, those names are reserved for the C/C++ implementation. --- src/libCom/test/blockingSockTest.cpp | 91 ++++++++++++++-------------- 1 file changed, 45 insertions(+), 46 deletions(-) diff --git a/src/libCom/test/blockingSockTest.cpp b/src/libCom/test/blockingSockTest.cpp index 17e46ad15..1243b75c0 100644 --- a/src/libCom/test/blockingSockTest.cpp +++ b/src/libCom/test/blockingSockTest.cpp @@ -22,8 +22,8 @@ epicsAssert(__FILE__, __LINE__, #exp, epicsAssertAuthor)) union address { - struct sockaddr_in m_ia; - struct sockaddr m_sa; + struct sockaddr_in ia; + struct sockaddr sa; }; class circuit { @@ -37,10 +37,10 @@ public: bool sendWakeupDetected () const; virtual const char * pName () = 0; protected: - SOCKET m_sock; - epicsThreadId m_id; - bool m_recvWakeup; - bool m_sendWakeup; + SOCKET sock; + epicsThreadId id; + bool recvWakeup; + bool sendWakeup; protected: virtual ~circuit() {} }; @@ -66,45 +66,45 @@ public: void daemon (); address addr () const; protected: - address m_addr; - SOCKET m_sock; - epicsThreadId m_id; - bool m_exit; + address srvaddr; + SOCKET sock; + epicsThreadId id; + bool exit; }; circuit::circuit ( SOCKET sockIn ) : - m_sock ( sockIn ), - m_id ( 0 ), - m_recvWakeup ( false ), - m_sendWakeup ( false ) + sock ( sockIn ), + id ( 0 ), + recvWakeup ( false ), + sendWakeup ( false ) { - verify ( m_sock != INVALID_SOCKET ); + verify ( this->sock != INVALID_SOCKET ); } bool circuit::recvWakeupDetected () const { - return m_recvWakeup; + return this->recvWakeup; } bool circuit::sendWakeupDetected () const { - return m_sendWakeup; + return this->sendWakeup; } void circuit::shutdown () { - int status = ::shutdown ( m_sock, SHUT_RDWR ); + int status = ::shutdown ( this->sock, SHUT_RDWR ); verify ( status == 0 ); } void circuit::signal () { - epicsSignalRaiseSigAlarm ( m_id ); + epicsSignalRaiseSigAlarm ( this->id ); } void circuit::close () { - epicsSocketDestroy ( m_sock ); + epicsSocketDestroy ( this->sock ); } void circuit::recvTest () @@ -112,11 +112,11 @@ void circuit::recvTest () epicsSignalInstallSigAlarmIgnore (); char buf [1]; while ( true ) { - int status = recv ( m_sock, + int status = recv ( this->sock, buf, (int) sizeof ( buf ), 0 ); if ( status == 0 ) { testDiag ( "%s was disconnected", this->pName () ); - m_recvWakeup = true; + this->recvWakeup = true; break; } else if ( status > 0 ) { @@ -128,7 +128,7 @@ void circuit::recvTest () sockErrBuf, sizeof ( sockErrBuf ) ); testDiag ( "%s socket recv() error was \"%s\"\n", this->pName (), sockErrBuf ); - m_recvWakeup = true; + this->recvWakeup = true; break; } } @@ -145,15 +145,15 @@ clientCircuit::clientCircuit ( const address & addrIn ) : { address tmpAddr = addrIn; int status = ::connect ( - m_sock, & tmpAddr.m_sa, sizeof ( tmpAddr ) ); + this->sock, & tmpAddr.sa, sizeof ( tmpAddr ) ); verify ( status == 0 ); circuit * pCir = this; - m_id = epicsThreadCreate ( + this->id = epicsThreadCreate ( "client circuit", epicsThreadPriorityMedium, epicsThreadGetStackSize(epicsThreadStackMedium), socketRecvTest, pCir ); - verify ( m_id ); + verify ( this->id ); } @@ -168,43 +168,42 @@ extern "C" void serverDaemon ( void * pParam ) { } server::server ( const address & addrIn ) : - m_addr ( addrIn ), - m_sock ( epicsSocketCreate ( AF_INET, SOCK_STREAM, IPPROTO_TCP ) ), - m_id ( 0 ), m_exit ( false ) + srvaddr ( addrIn ), + sock ( epicsSocketCreate ( AF_INET, SOCK_STREAM, IPPROTO_TCP ) ), + id ( 0 ), exit ( false ) { - verify ( m_sock != INVALID_SOCKET ); + verify ( this->sock != INVALID_SOCKET ); // setup server side - int status = bind ( m_sock, - & m_addr.m_sa, sizeof ( m_addr ) ); + osiSocklen_t slen = sizeof ( this->srvaddr ); + int status = bind ( this->sock, & this->srvaddr.sa, slen ); if ( status ) { testDiag ( "bind to server socket failed, status = %d", status ); } - osiSocklen_t slen = sizeof ( m_addr ); - if ( getsockname(m_sock, &m_addr.m_sa, &slen) != 0 ) { + if ( getsockname(this->sock, & this->srvaddr.sa, & slen) != 0 ) { testAbort ( "Failed to read socket address" ); } - status = listen ( m_sock, 10 ); + status = listen ( this->sock, 10 ); verify ( status == 0 ); } void server::start () { - m_id = epicsThreadCreate ( - "server daemon", epicsThreadPriorityMedium, - epicsThreadGetStackSize(epicsThreadStackMedium), + this->id = epicsThreadCreate ( + "server daemon", epicsThreadPriorityMedium, + epicsThreadGetStackSize(epicsThreadStackMedium), serverDaemon, this ); - verify ( m_id ); + verify ( this->id ); } void server::daemon () { - while ( ! m_exit ) { + while ( ! this->exit ) { // accept client side address addr; osiSocklen_t addressSize = sizeof ( addr ); - SOCKET ns = accept ( m_sock, - & m_addr.m_sa, & addressSize ); + SOCKET ns = accept ( this->sock, + & addr.sa, & addressSize ); verify ( ns != INVALID_SOCKET ); circuit * pCir = new serverCircuit ( ns ); verify ( pCir ); @@ -213,7 +212,7 @@ void server::daemon () address server::addr () const { - return m_addr; + return this->srvaddr; } serverCircuit::serverCircuit ( SOCKET sockIn ) : @@ -257,9 +256,9 @@ MAIN(blockingSockTest) address addr; memset ( (char *) & addr, 0, sizeof ( addr ) ); - addr.m_ia.sin_family = AF_INET; - addr.m_ia.sin_addr.s_addr = htonl ( INADDR_LOOPBACK ); - addr.m_ia.sin_port = 0; + addr.ia.sin_family = AF_INET; + addr.ia.sin_addr.s_addr = htonl ( INADDR_LOOPBACK ); + addr.ia.sin_port = 0; server srv ( addr ); srv.start (); From 9079c8aa538f991b415db43bf5b1c7fec5d0d32f Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Mon, 18 Aug 2014 22:55:07 -0500 Subject: [PATCH 7/7] Reverted changes to epicsTime.h and epicsThread.h --- src/libCom/osi/epicsThread.h | 9 +-------- src/libCom/osi/epicsTime.h | 18 ++++++------------ 2 files changed, 7 insertions(+), 20 deletions(-) diff --git a/src/libCom/osi/epicsThread.h b/src/libCom/osi/epicsThread.h index 9102ec734..d7be5d197 100644 --- a/src/libCom/osi/epicsThread.h +++ b/src/libCom/osi/epicsThread.h @@ -10,12 +10,7 @@ #ifndef epicsThreadh #define epicsThreadh -#ifdef __cplusplus -#include -using std :: size_t; -#else #include -#endif #include "shareLib.h" @@ -43,9 +38,7 @@ typedef void (*EPICSTHREADFUNC)(void *parm); /* stack sizes for each stackSizeClass are implementation and CPU dependent */ typedef enum { - epicsThreadStackSmall, - epicsThreadStackMedium, - epicsThreadStackBig + epicsThreadStackSmall, epicsThreadStackMedium, epicsThreadStackBig } epicsThreadStackSizeClass; typedef enum { diff --git a/src/libCom/osi/epicsTime.h b/src/libCom/osi/epicsTime.h index 3f83d74d4..a36d6afe3 100644 --- a/src/libCom/osi/epicsTime.h +++ b/src/libCom/osi/epicsTime.h @@ -12,11 +12,7 @@ #ifndef epicsTimehInclude #define epicsTimehInclude -#ifdef __cplusplus -# include -#else -# include -#endif +#include #include "shareLib.h" #include "epicsTypes.h" @@ -46,7 +42,7 @@ struct l_fp; /* NTP timestamp */ * and a struct tm that is adjusted for the local timezone */ struct local_tm_nano_sec { - std :: tm ansi_tm; /* ANSI C time details */ + struct tm ansi_tm; /* ANSI C time details */ unsigned long nSec; /* nano seconds extension */ }; @@ -55,7 +51,7 @@ struct local_tm_nano_sec { * and a struct tm that is adjusted for GMT (UTC) */ struct gm_tm_nano_sec { - std :: tm ansi_tm; /* ANSI C time details */ + struct tm ansi_tm; /* ANSI C time details */ unsigned long nSec; /* nano seconds extension */ }; @@ -65,7 +61,7 @@ struct gm_tm_nano_sec { * conversions to occur */ struct time_t_wrapper { - std :: time_t ts; + time_t ts; }; class epicsShareClass epicsTimeEvent @@ -248,10 +244,8 @@ epicsShareFunc void epicsShareAPI epicsTimeShow ( /* OS dependent reentrant versions of the ANSI C interface because */ /* vxWorks gmtime_r interface does not match POSIX standards */ -epicsShareFunc int epicsShareAPI - epicsTime_localtime ( const time_t * clock, struct tm * result ); -epicsShareFunc int epicsShareAPI - epicsTime_gmtime ( const time_t * clock, struct tm * result ); +epicsShareFunc int epicsShareAPI epicsTime_localtime ( const time_t * clock, struct tm * result ); +epicsShareFunc int epicsShareAPI epicsTime_gmtime ( const time_t * clock, struct tm * result ); #ifdef __cplusplus }