diff --git a/configure/CONFIG b/configure/CONFIG index 17440a39e..580b58767 100644 --- a/configure/CONFIG +++ b/configure/CONFIG @@ -73,17 +73,17 @@ ifdef T_A # -include $(CONFIG)/os/CONFIG.$(EPICS_HOST_ARCH).$(T_A) + # Site specific target and host-target definitions and overrides + # + -include $(CONFIG)/os/CONFIG_SITE.Common.$(T_A) + -include $(CONFIG)/os/CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A) + # RELEASE file specific definitions # ifneq ($(CONFIG),$(TOP)/configure) -include $(CONFIG)/CONFIG_APP_INCLUDE endif - # Site specific target and host-target definitions - # - -include $(CONFIG)/os/CONFIG_SITE.Common.$(T_A) - -include $(CONFIG)/os/CONFIG_SITE.$(EPICS_HOST_ARCH).$(T_A) - endif # ifdef T_A diff --git a/documentation/RELEASE_NOTES.html b/documentation/RELEASE_NOTES.html index 7c5ade339..111c604d3 100644 --- a/documentation/RELEASE_NOTES.html +++ b/documentation/RELEASE_NOTES.html @@ -597,6 +597,17 @@ tells git to ignore all configure/*.local files.

+

Extend maximum Posix epicsEventWaitWithTimeout() delay

+ +

The Posix implementation of epicsEventWaitWithTimeout() was limiting the +timeout delay to at most 60 minutes (3600.0 seconds). This has been changed to +10 years; significantly longer maximum delays cause problems on systems where +time_t is still a signed 32-bit integer so cannot represent absolute +time-stamps after 2038-01-19. Our assumption is that such 32-bit systems will +have been retired before the year 2028, but some additional tests have been +added to the epicsTimeTest program to detect and fail if this assumption is +violated.

+

New test-related make targets

This release adds several new make targets intended for use by developers diff --git a/src/libCom/fdmgr/fdManager.cpp b/src/libCom/fdmgr/fdManager.cpp index ff5022d81..00f4d4a87 100644 --- a/src/libCom/fdmgr/fdManager.cpp +++ b/src/libCom/fdmgr/fdManager.cpp @@ -113,7 +113,7 @@ epicsShareFunc void fdManager::process (double delay) if ( ioPending ) { struct timeval tv; - tv.tv_sec = static_cast ( minDelay ); + tv.tv_sec = static_cast ( minDelay ); tv.tv_usec = static_cast ( (minDelay-tv.tv_sec) * uSecPerSec ); fd_set * pReadSet = & this->fdSetsPtr[fdrRead]; diff --git a/src/libCom/osi/os/Darwin/osdTime.cpp b/src/libCom/osi/os/Darwin/osdTime.cpp index c4a7e838c..72b3dc874 100644 --- a/src/libCom/osi/os/Darwin/osdTime.cpp +++ b/src/libCom/osi/os/Darwin/osdTime.cpp @@ -68,14 +68,14 @@ convertDoubleToWakeTime(double timeout, struct timespec *wakeTime) mach_timespec_t now; struct timespec wait; + if (timeout < 0.0) + timeout = 0.0; + else if (timeout > 60 * 60 * 24 * 3652.5) + timeout = 60 * 60 * 24 * 3652.5; /* 10 years */ + clock_get_time(host_clock, &now); - if (timeout<0.0) - timeout = 0.0; - else if(timeout>3600.0) - timeout = 3600.0; - - wait.tv_sec = static_cast< long >(timeout); + wait.tv_sec = static_cast< time_t >(timeout); wait.tv_nsec = static_cast< long >((timeout - (double)wait.tv_sec) * 1e9); wakeTime->tv_sec = now.tv_sec + wait.tv_sec; diff --git a/src/libCom/osi/os/posix/osdTime.cpp b/src/libCom/osi/os/posix/osdTime.cpp index 2d98cf3ae..d5fb05a1c 100644 --- a/src/libCom/osi/os/posix/osdTime.cpp +++ b/src/libCom/osi/os/posix/osdTime.cpp @@ -88,30 +88,35 @@ int epicsTime_localtime ( const time_t *clock, extern "C" epicsShareFunc void convertDoubleToWakeTime(double timeout,struct timespec *wakeTime) { - struct timespec wait; + struct timespec now, wait; int status; - if(timeout<0.0) timeout = 0.0; - else if(timeout>3600.0) timeout = 3600.0; + if (timeout < 0.0) + timeout = 0.0; + else if (timeout > 60 * 60 * 24 * 3652.5) + timeout = 60 * 60 * 24 * 3652.5; /* 10 years */ + #ifdef CLOCK_REALTIME - status = clock_gettime(CLOCK_REALTIME, wakeTime); + status = clock_gettime(CLOCK_REALTIME, &now); #else { struct timeval tv; struct timezone tz; status = gettimeofday(&tv, &tz); - wakeTime->tv_sec = tv.tv_sec; - wakeTime->tv_nsec = tv.tv_usec * 1000; + now.tv_sec = tv.tv_sec; + now.tv_nsec = tv.tv_usec * 1000; } #endif if (status) { perror("convertDoubleToWakeTime"); cantProceed("convertDoubleToWakeTime"); } - wait.tv_sec = static_cast< long >(timeout); + + wait.tv_sec = static_cast< time_t >(timeout); wait.tv_nsec = static_cast< long >((timeout - (double)wait.tv_sec) * 1e9); - wakeTime->tv_sec += wait.tv_sec; - wakeTime->tv_nsec += wait.tv_nsec; + + wakeTime->tv_sec = now.tv_sec + wait.tv_sec; + wakeTime->tv_nsec = now.tv_nsec + wait.tv_nsec; if (wakeTime->tv_nsec >= 1000000000L) { wakeTime->tv_nsec -= 1000000000L; ++wakeTime->tv_sec; diff --git a/src/libCom/test/epicsTimeTest.cpp b/src/libCom/test/epicsTimeTest.cpp index ec5da4c78..55ad43cdd 100644 --- a/src/libCom/test/epicsTimeTest.cpp +++ b/src/libCom/test/epicsTimeTest.cpp @@ -43,7 +43,7 @@ MAIN(epicsTimeTest) const int wasteTime = 100000; const int nTimes = 10; - testPlan(15 + nTimes * 19); + testPlan(17 + nTimes * 19); try { const epicsTimeStamp epochTS = {0, 0}; @@ -211,5 +211,35 @@ MAIN(epicsTimeTest) testOk1(beginTS + diff == now); } + epicsTime ten_years_hence; + try { + now = epicsTime::getCurrent(); + ten_years_hence = now + 60 * 60 * 24 * 3652.5; + testPass("epicsTime can represent 10 years hence"); + } + catch ( ... ) { + testFail("epicsTime exception for value 10 years hence"); + } + + try { + /* This test exists because in libCom/osi/os/posix/osdTime.cpp + * the convertDoubleToWakeTime() routine limits the timeout delay + * to 10 years. libCom/timer/timerQueue.cpp returns DBL_MAX for + * queues with no timers present, and convertDoubleToWakeTime() + * has to return an absolute Posix timestamp. On 2028-01-19 any + * systems that still implement time_t as a signed 32-bit integer + * will be unable to represent that timestamp, so this will fail. + */ + time_t_wrapper os_time_t = ten_years_hence; + epicsTime then = os_time_t; // No fractional seconds + double delta = ten_years_hence - then; + + testOk(delta >= 0 && delta < 1.0, + "OS time_t can represent 10 years hence"); + } + catch ( ... ) { + testFail("OS time_t conversion exception for value 10 years hence"); + } + return testDone(); } diff --git a/src/libCom/test/fdmgrTest.c b/src/libCom/test/fdmgrTest.c index 86857c6f5..e41784ccf 100644 --- a/src/libCom/test/fdmgrTest.c +++ b/src/libCom/test/fdmgrTest.c @@ -74,13 +74,13 @@ void testTimer (fdctx *pfdm, double delay) epicsTimeGetCurrent (&begin); cbs.done = 0; - tmo.tv_sec = (unsigned long) delay; + tmo.tv_sec = (time_t) delay; tmo.tv_usec = (unsigned long) ((delay - tmo.tv_sec) * uSecPerSec); aid = fdmgr_add_timeout (pfdm, &tmo, alarmCB, &cbs); verify (aid!=fdmgrNoAlarm); while (!cbs.done) { - tmo.tv_sec = (unsigned long) delay; + tmo.tv_sec = (time_t) delay; tmo.tv_usec = (unsigned long) ((delay - tmo.tv_sec) * uSecPerSec); status = fdmgr_pend_event (pfdm, &tmo); verify (status==0); diff --git a/src/libCom/timer/timerPrivate.h b/src/libCom/timer/timerPrivate.h index c60939851..55291309c 100644 --- a/src/libCom/timer/timerPrivate.h +++ b/src/libCom/timer/timerPrivate.h @@ -105,7 +105,7 @@ private: epicsTime exceptMsgTimeStamp; bool cancelPending; static const double exceptMsgMinPeriod; - void printExceptMsg ( const char * pName, + void printExceptMsg ( const char * pName, const type_info & type ); timerQueue ( const timerQueue & ); timerQueue & operator = ( const timerQueue & );