Merge lp:~epics-core/epics-base/epicsTime-status into lp:~epics-core/epics-base/3.16

Proposed by Andrew Johnson
Status: Merged
Merged at revision: 12656
Proposed branch: lp:~epics-core/epics-base/epicsTime-status
Merge into: lp:~epics-core/epics-base/3.16
Diff against target: 550 lines (+85/-48)
12 files modified
documentation/RELEASE_NOTES.html (+22/-0)
src/libCom/error/Makefile (+1/-0)
src/libCom/error/errMdef.h (+1/-0)
src/libCom/osi/epicsGeneralTime.c (+22/-18)
src/libCom/osi/epicsTime.cpp (+11/-11)
src/libCom/osi/epicsTime.h (+9/-2)
src/libCom/osi/os/Darwin/osdTime.cpp (+3/-2)
src/libCom/osi/os/RTEMS/osdTime.cpp (+2/-2)
src/libCom/osi/os/WIN32/osdTime.cpp (+7/-7)
src/libCom/osi/os/posix/osdTime.cpp (+4/-3)
src/libCom/osi/osiNTPTime.c (+2/-2)
src/std/dev/devGeneralTime.c (+1/-1)
To merge this branch: bzr merge lp:~epics-core/epics-base/epicsTime-status
Reviewer Review Type Date Requested Status
mdavidsaver Approve
Review via email: mp+243463@code.launchpad.net

Description of the change

The return value epicsTimeERROR is useless when trying to track down a fault.
This branch replaces it with specific status values for the different kinds of errors.

To post a comment you must log in.
Revision history for this message
mdavidsaver (mdavidsaver) wrote :

I like the idea of more specific errors, but I'd like to keep the definition of epicsTimeERROR to maintain source compatibility with external code (ie. the time provider in mrfioc2). Perhaps epicsTimeERROR can be an alias for an S_ error code (S_time_legacy?).

Otherwise no problem. I can make the change if Andrew approves a name.

review: Needs Fixing
12623. By Andrew Johnson

Show how to make time providers backwards-compatible

Revision history for this message
Andrew Johnson (anj) wrote :

The problem with keeping the epicsTimeERROR definition is that any code that equality compares it with a returned status value will stop working. Several such uses were fixed in this branch, for example this code would still compile with the requested change but needs to be modified to work properly:
  if (epicsTimeFromTimespec(&timeNow, &timespecNow) == epicsTimeERROR) { ... }
since epicsTimeFromTimespec() now returns S_time_conversion on error.

It could be rewritten as either
  if (epicsTimeFromTimespec(&timeNow, &timespecNow) != epicsTimeOK) { ... }
or
  if (epicsTimeFromTimespec(&timeNow, &timespecNow)) { ... }
both of which are backwards compatible.

Time providers that have to return a status and need to be backwards compatible could do this:

#include "epicsTime.h"
#ifndef M_time
/* S_time_... status values were not provided before Base 3.16 */
#define S_time_unsynchronized epicsTimeERROR
#define S_time_...whatever... epicsTimeERROR
#endif

I added the above suggestion for time provider code to the release notes.

Revision history for this message
mdavidsaver (mdavidsaver) wrote :

> The problem with keeping the epicsTimeERROR definition is that any code that equality compares it with a returned status value will stop working.

Good point.

FYI the case I have is:

https://github.com/epics-modules/mrfioc2/blob/master/evrApp/src/evrGTIF.cpp

The important thing is to have code which works for both <=3.15 and >=3.16, which could be done the in way you mention.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'documentation/RELEASE_NOTES.html'
2--- documentation/RELEASE_NOTES.html 2015-04-16 23:12:59 +0000
3+++ documentation/RELEASE_NOTES.html 2015-06-03 05:15:51 +0000
4@@ -20,6 +20,28 @@
5
6 -->
7
8+<h3>epicsTime API return status</h3>
9+
10+<p>The epicsTime routines that used to return epicsTimeERROR now return a specific
11+S_time_ status value, allowing the caller to discover the reason for any failure.
12+The identifier <tt>epicsTimeERROR</tt> is no longer defined, so any references to
13+it in source code will no longer compile. The identifier epicsTimeOK still exists
14+and has the value 0 as before, so most code that uses these APIs can be changed in
15+a way that is backwards-compatible with the previous return status.</p>
16+
17+<p>Time providers that have to return a status value and still need to be built
18+with earlier versions of Base can define the necessary status symbols like this:</p>
19+
20+<blockquote><pre>
21+#include "epicsTime.h"
22+
23+#ifndef M_time
24+/* S_time_... status values were not provided before Base 3.16 */
25+#define S_time_unsynchronized epicsTimeERROR
26+#define S_time_...whatever... epicsTimeERROR
27+#endif
28+</pre></blockquote>
29+
30 <h3>Callback subsystem API</h3>
31
32 <p>Added a new macro <tt>callbackGetPriority(prio, callback)</tt> to the
33
34=== modified file 'src/libCom/error/Makefile'
35--- src/libCom/error/Makefile 2014-08-01 22:55:53 +0000
36+++ src/libCom/error/Makefile 2015-06-03 05:15:51 +0000
37@@ -22,6 +22,7 @@
38 # For bldErrSymTbl
39 #
40 ERR_S_FILES += $(LIBCOM)/osi/devLib.h
41+ERR_S_FILES += $(LIBCOM)/osi/epicsTime.h
42 ERR_S_FILES += $(LIBCOM)/as/asLib.h
43 ERR_S_FILES += $(LIBCOM)/misc/epicsStdlib.h
44 ERR_S_FILES += $(LIBCOM)/pool/epicsThreadPool.h
45
46=== modified file 'src/libCom/error/errMdef.h'
47--- src/libCom/error/errMdef.h 2014-08-01 22:55:53 +0000
48+++ src/libCom/error/errMdef.h 2015-06-03 05:15:51 +0000
49@@ -50,6 +50,7 @@
50 #define M_gddFuncTbl (526 <<16) /*gdd jump table*/
51 #define M_stdlib (527 <<16) /*EPICS Standard library*/
52 #define M_pool (528 <<16) /*Thread pool*/
53+#define M_time (529 <<16) /*epicsTime*/
54
55 epicsShareFunc void epicsShareAPI errSymLookup(long status, char *pBuf, unsigned bufLength);
56 epicsShareFunc void epicsShareAPI errSymTest(unsigned short modnum, unsigned short begErrNum, unsigned short endErrNum);
57
58=== modified file 'src/libCom/osi/epicsGeneralTime.c'
59--- src/libCom/osi/epicsGeneralTime.c 2013-12-11 23:50:29 +0000
60+++ src/libCom/osi/epicsGeneralTime.c 2015-06-03 05:15:51 +0000
61@@ -86,7 +86,7 @@
62 int generalTimeGetExceptPriority(epicsTimeStamp *pDest, int *pPrio, int ignore)
63 {
64 gtProvider *ptp;
65- int status = epicsTimeERROR;
66+ int status = S_time_noProvider;
67
68 generalTime_Init();
69
70@@ -107,6 +107,7 @@
71 *pPrio = ptp->priority;
72 } else {
73 int key;
74+
75 *pDest = gtPvt.lastProvidedTime;
76 if (pPrio)
77 *pPrio = gtPvt.lastTimeProvider->priority;
78@@ -117,8 +118,7 @@
79 break;
80 }
81 }
82- if (status == epicsTimeERROR &&
83- ignore == 0)
84+ if (status && ignore == 0)
85 gtPvt.lastTimeProvider = NULL;
86 epicsMutexUnlock(gtPvt.timeListLock);
87
88@@ -135,7 +135,8 @@
89 gtProvider *ptp = gtPvt.lastTimeProvider;
90
91 if (ptp == NULL ||
92- ptp->getInt.Time == NULL) return epicsTimeERROR;
93+ ptp->getInt.Time == NULL)
94+ return S_time_noProvider;
95
96 return ptp->getInt.Time(pDest);
97 }
98@@ -145,20 +146,20 @@
99 int *pPrio)
100 {
101 gtProvider *ptp;
102- int status = epicsTimeERROR;
103+ int status = S_time_noProvider;
104
105 generalTime_Init();
106
107 if ((eventNumber < 0 || eventNumber >= NUM_TIME_EVENTS) &&
108 (eventNumber != epicsTimeEventBestTime))
109- return status;
110+ return S_time_badEvent;
111
112 epicsMutexMustLock(gtPvt.eventListLock);
113 for (ptp = (gtProvider *)ellFirst(&gtPvt.eventProviders);
114 ptp; ptp = (gtProvider *)ellNext(&ptp->node)) {
115
116 status = ptp->get.Event(pDest, eventNumber);
117- if (status != epicsTimeERROR) {
118+ if (status == epicsTimeOK) {
119 gtPvt.lastEventProvider = ptp;
120 if (pPrio)
121 *pPrio = ptp->priority;
122@@ -169,6 +170,7 @@
123 gtPvt.lastProvidedBestTime = *pDest;
124 } else {
125 int key;
126+
127 *pDest = gtPvt.lastProvidedBestTime;
128 key = epicsInterruptLock();
129 gtPvt.ErrorCounts++;
130@@ -180,6 +182,7 @@
131 gtPvt.eventTime[eventNumber] = *pDest;
132 } else {
133 int key;
134+
135 *pDest = gtPvt.eventTime[eventNumber];
136 key = epicsInterruptLock();
137 gtPvt.ErrorCounts++;
138@@ -189,7 +192,7 @@
139 break;
140 }
141 }
142- if (status == epicsTimeERROR)
143+ if (status)
144 gtPvt.lastEventProvider = NULL;
145 epicsMutexUnlock(gtPvt.eventListLock);
146
147@@ -213,7 +216,8 @@
148 gtProvider *ptp = gtPvt.lastEventProvider;
149
150 if (ptp == NULL ||
151- ptp->getInt.Event == NULL) return epicsTimeERROR;
152+ ptp->getInt.Event == NULL)
153+ return S_time_noProvider;
154
155 return ptp->getInt.Event(pDest, eventNumber);
156 }
157@@ -271,11 +275,11 @@
158 generalTime_Init();
159
160 if (name == NULL || getEvent == NULL)
161- return epicsTimeERROR;
162+ return S_time_badArgs;
163
164 ptp = (gtProvider *)malloc(sizeof(gtProvider));
165 if (ptp == NULL)
166- return epicsTimeERROR;
167+ return S_time_noMemory;
168
169 ptp->name = epicsStrDup(name);
170 ptp->priority = priority;
171@@ -293,7 +297,7 @@
172 gtProvider *ptp = findProvider(&gtPvt.eventProviders, gtPvt.eventListLock,
173 name, priority);
174 if (ptp == NULL)
175- return epicsTimeERROR;
176+ return S_time_noProvider;
177
178 ptp->getInt.Event = getEvent;
179
180@@ -308,11 +312,11 @@
181 generalTime_Init();
182
183 if (name == NULL || getTime == NULL)
184- return epicsTimeERROR;
185+ return S_time_badArgs;
186
187 ptp = (gtProvider *)malloc(sizeof(gtProvider));
188 if (ptp == NULL)
189- return epicsTimeERROR;
190+ return S_time_noMemory;
191
192 ptp->name = epicsStrDup(name);
193 ptp->priority = priority;
194@@ -330,7 +334,7 @@
195 gtProvider *ptp = findProvider(&gtPvt.timeProviders, gtPvt.timeListLock,
196 name, priority);
197 if (ptp == NULL)
198- return epicsTimeERROR;
199+ return S_time_noProvider;
200
201 ptp->getInt.Time = getTime;
202
203@@ -388,7 +392,7 @@
204 if (!message) {
205 epicsMutexUnlock(gtPvt.timeListLock);
206 printf("Out of memory\n");
207- return epicsTimeERROR;
208+ return S_time_noMemory;
209 }
210
211 pout = message;
212@@ -399,7 +403,7 @@
213 ptp->name, ptp->priority);
214 if (level) {
215 epicsTimeStamp tempTS;
216- if (ptp->get.Time(&tempTS) != epicsTimeERROR) {
217+ if (ptp->get.Time(&tempTS) == epicsTimeOK) {
218 char tempTSText[40];
219 epicsTimeToStrftime(tempTSText, sizeof(tempTSText),
220 "%Y-%m-%d %H:%M:%S.%06f", &tempTS);
221@@ -430,7 +434,7 @@
222 if (!message) {
223 epicsMutexUnlock(gtPvt.eventListLock);
224 printf("Out of memory\n");
225- return epicsTimeERROR;
226+ return S_time_noMemory;
227 }
228
229 pout = message;
230
231=== modified file 'src/libCom/osi/epicsTime.cpp'
232--- src/libCom/osi/epicsTime.cpp 2014-08-25 21:27:18 +0000
233+++ src/libCom/osi/epicsTime.cpp 2015-06-03 05:15:51 +0000
234@@ -284,7 +284,7 @@
235 local_tm_nano_sec tm;
236
237 int status = epicsTime_localtime ( &ansiTimeTicks.ts, &tm.ansi_tm );
238- if ( status != epicsTimeOK ) {
239+ if ( status ) {
240 throw std::logic_error ( "epicsTime_localtime failed" );
241 }
242
243@@ -303,7 +303,7 @@
244 gm_tm_nano_sec tm;
245
246 int status = epicsTime_gmtime ( &ansiTimeTicks.ts, &tm.ansi_tm );
247- if ( status != epicsTimeOK ) {
248+ if ( status ) {
249 throw std::logic_error ( "epicsTime_gmtime failed" );
250 }
251
252@@ -891,7 +891,7 @@
253 *pDest = dst.ts;
254 }
255 catch (...) {
256- return epicsTimeERROR;
257+ return S_time_conversion;
258 }
259 return epicsTimeOK;
260 }
261@@ -903,7 +903,7 @@
262 *pDest = epicsTime ( dst );
263 }
264 catch (...) {
265- return epicsTimeERROR;
266+ return S_time_conversion;
267 }
268 return epicsTimeOK;
269 }
270@@ -915,7 +915,7 @@
271 *pNSecDest = tmns.nSec;
272 }
273 catch (...) {
274- return epicsTimeERROR;
275+ return S_time_conversion;
276 }
277 return epicsTimeOK;
278 }
279@@ -927,7 +927,7 @@
280 *pNSecDest = gmtmns.nSec;
281 }
282 catch (...) {
283- return epicsTimeERROR;
284+ return S_time_conversion;
285 }
286 return epicsTimeOK;
287 }
288@@ -940,7 +940,7 @@
289 *pDest = epicsTime (tmns);
290 }
291 catch (...) {
292- return epicsTimeERROR;
293+ return S_time_conversion;
294 }
295 return epicsTimeOK;
296 }
297@@ -950,7 +950,7 @@
298 *pDest = epicsTime (*pSrc);
299 }
300 catch (...) {
301- return epicsTimeERROR;
302+ return S_time_conversion;
303 }
304 return epicsTimeOK;
305 }
306@@ -960,7 +960,7 @@
307 *pDest = epicsTime (*pSrc);
308 }
309 catch (...) {
310- return epicsTimeERROR;
311+ return S_time_conversion;
312 }
313 return epicsTimeOK;
314 }
315@@ -970,7 +970,7 @@
316 *pDest = epicsTime (*pSrc);
317 }
318 catch (...) {
319- return epicsTimeERROR;
320+ return S_time_conversion;
321 }
322 return epicsTimeOK;
323 }
324@@ -980,7 +980,7 @@
325 *pDest = epicsTime (*pSrc);
326 }
327 catch (...) {
328- return epicsTimeERROR;
329+ return S_time_conversion;
330 }
331 return epicsTimeOK;
332 }
333
334=== modified file 'src/libCom/osi/epicsTime.h'
335--- src/libCom/osi/epicsTime.h 2014-08-19 03:55:07 +0000
336+++ src/libCom/osi/epicsTime.h 2015-06-03 05:15:51 +0000
337@@ -17,6 +17,7 @@
338 #include "shareLib.h"
339 #include "epicsTypes.h"
340 #include "osdTime.h"
341+#include "errMdef.h"
342
343 /* The EPICS Epoch is 00:00:00 Jan 1, 1990 UTC */
344 #define POSIX_TIME_AT_EPICS_EPOCH 631152000u
345@@ -170,9 +171,15 @@
346 extern "C" {
347 #endif /* __cplusplus */
348
349-/* All epicsTime routines return (-1,0) for (failure,success) */
350+/* epicsTime routines return S_time_ error status values */
351 #define epicsTimeOK 0
352-#define epicsTimeERROR (-1)
353+#define S_time_noProvider (M_time| 1) /*No time provider*/
354+#define S_time_badEvent (M_time| 2) /*Bad event number*/
355+#define S_time_badArgs (M_time| 3) /*Invalid arguments*/
356+#define S_time_noMemory (M_time| 4) /*Out of memory*/
357+#define S_time_unsynchronized (M_time| 5) /*Provider not synchronized*/
358+#define S_time_timezone (M_time| 6) /*Invalid timeone*/
359+#define S_time_conversion (M_time| 7) /*Time conversion error*/
360
361 /*Some special values for eventNumber*/
362 #define epicsTimeEventCurrentTime 0
363
364=== modified file 'src/libCom/osi/os/Darwin/osdTime.cpp'
365--- src/libCom/osi/os/Darwin/osdTime.cpp 2013-03-13 19:48:34 +0000
366+++ src/libCom/osi/os/Darwin/osdTime.cpp 2015-06-03 05:15:51 +0000
367@@ -11,6 +11,7 @@
368 #include <stdlib.h>
369 #include <stdio.h>
370 #include <string.h>
371+#include <errno.h>
372 #include <mach/mach.h>
373 #include <mach/clock.h>
374
375@@ -52,13 +53,13 @@
376 int epicsTime_gmtime(const time_t *pAnsiTime, struct tm *pTM)
377 {
378 return gmtime_r(pAnsiTime, pTM) ?
379- epicsTimeOK : epicsTimeERROR;
380+ epicsTimeOK : errno;
381 }
382
383 int epicsTime_localtime(const time_t *clock, struct tm *result)
384 {
385 return localtime_r(clock, result) ?
386- epicsTimeOK : epicsTimeERROR;
387+ epicsTimeOK : errno;
388 }
389
390 extern "C" epicsShareFunc void
391
392=== modified file 'src/libCom/osi/os/RTEMS/osdTime.cpp'
393--- src/libCom/osi/os/RTEMS/osdTime.cpp 2011-08-23 18:20:00 +0000
394+++ src/libCom/osi/os/RTEMS/osdTime.cpp 2015-06-03 05:15:51 +0000
395@@ -91,7 +91,7 @@
396 return epicsTimeOK;
397 }
398 else {
399- return epicsTimeERROR;
400+ return errno;
401 }
402 }
403
404@@ -102,7 +102,7 @@
405 return epicsTimeOK;
406 }
407 else {
408- return epicsTimeERROR;
409+ return errno;
410 }
411 }
412
413
414=== modified file 'src/libCom/osi/os/WIN32/osdTime.cpp'
415--- src/libCom/osi/os/WIN32/osdTime.cpp 2015-03-13 16:50:26 +0000
416+++ src/libCom/osi/os/WIN32/osdTime.cpp 2015-06-03 05:15:51 +0000
417@@ -164,7 +164,7 @@
418 SYSTEMTIME st;
419 BOOL status = FileTimeToSystemTime ( &ft, &st );
420 if ( ! status ) {
421- return epicsTimeERROR;
422+ return S_time_conversion;
423 }
424
425 pTM->tm_sec = st.wSecond; // seconds after the minute - [0,59]
426@@ -193,7 +193,7 @@
427 TIME_ZONE_INFORMATION tzInfo;
428 DWORD tzStatus = GetTimeZoneInformation ( & tzInfo );
429 if ( tzStatus == TIME_ZONE_ID_INVALID ) {
430- return epicsTimeERROR;
431+ return S_time_timezone;
432 }
433
434 //
435@@ -204,13 +204,13 @@
436 SYSTEMTIME st;
437 BOOL success = FileTimeToSystemTime ( & ft, & st );
438 if ( ! success ) {
439- return epicsTimeERROR;
440+ return S_time_conversion;
441 }
442 SYSTEMTIME lst;
443 success = SystemTimeToTzSpecificLocalTime (
444 & tzInfo, & st, & lst );
445 if ( ! success ) {
446- return epicsTimeERROR;
447+ return S_time_conversion;
448 }
449
450 //
451@@ -220,7 +220,7 @@
452 FILETIME lft;
453 success = SystemTimeToFileTime ( & lst, & lft );
454 if ( ! success ) {
455- return epicsTimeERROR;
456+ return S_time_conversion;
457 }
458
459 int is_dst = -1; // unknown state of dst
460@@ -234,14 +234,14 @@
461 success = SystemTimeToFileTime (
462 & tzInfo.StandardDate, & StandardDateFT );
463 if ( ! success ) {
464- return epicsTimeERROR;
465+ return S_time_conversion;
466 }
467 tzInfo.DaylightDate.wYear = st.wYear;
468 FILETIME DaylightDateFT;
469 success = SystemTimeToFileTime (
470 & tzInfo.DaylightDate, & DaylightDateFT );
471 if ( ! success ) {
472- return epicsTimeERROR;
473+ return S_time_conversion;
474 }
475 if ( CompareFileTime ( & lft, & DaylightDateFT ) >= 0
476 && CompareFileTime ( & lft, & StandardDateFT ) < 0 ) {
477
478=== modified file 'src/libCom/osi/os/posix/osdTime.cpp'
479--- src/libCom/osi/os/posix/osdTime.cpp 2013-03-15 20:23:55 +0000
480+++ src/libCom/osi/os/posix/osdTime.cpp 2015-06-03 05:15:51 +0000
481@@ -11,6 +11,7 @@
482 #include <stdlib.h>
483 #include <stdio.h>
484 #include <string.h>
485+#include <errno.h>
486
487 #include "osiSock.h"
488
489@@ -36,7 +37,7 @@
490 struct timezone tz;
491
492 if (gettimeofday (&tv, &tz))
493- return epicsTimeERROR;
494+ return errno;
495
496 *pDest = epicsTime(tv);
497 return epicsTimeOK;
498@@ -68,7 +69,7 @@
499 return epicsTimeOK;
500 }
501 else {
502- return epicsTimeERROR;
503+ return errno;
504 }
505 }
506
507@@ -80,7 +81,7 @@
508 return epicsTimeOK;
509 }
510 else {
511- return epicsTimeERROR;
512+ return errno;
513 }
514 }
515
516
517=== modified file 'src/libCom/osi/osiNTPTime.c'
518--- src/libCom/osi/osiNTPTime.c 2014-08-25 21:27:18 +0000
519+++ src/libCom/osi/osiNTPTime.c 2015-06-03 05:15:51 +0000
520@@ -164,7 +164,7 @@
521 }
522
523 if (timespecNow.tv_sec <= POSIX_TIME_AT_EPICS_EPOCH ||
524- epicsTimeFromTimespec(&timeNow, &timespecNow) == epicsTimeERROR) {
525+ epicsTimeFromTimespec(&timeNow, &timespecNow) != epicsTimeOK) {
526 errlogPrintf("NTPTimeSync: Bad time received from NTP server\n");
527 NTPTimePvt.synchronized = 0;
528 continue;
529@@ -213,7 +213,7 @@
530 epicsUInt32 ticksSince;
531
532 if (!NTPTimePvt.synchronized)
533- return epicsTimeERROR;
534+ return S_time_unsynchronized;
535
536 epicsMutexMustLock(NTPTimePvt.lock);
537
538
539=== modified file 'src/std/dev/devGeneralTime.c'
540--- src/std/dev/devGeneralTime.c 2013-12-17 18:54:04 +0000
541+++ src/std/dev/devGeneralTime.c 2015-06-03 05:15:51 +0000
542@@ -37,7 +37,7 @@
543 {
544 epicsTimeStamp ts;
545
546- if (epicsTimeERROR != epicsTimeGetCurrent(&ts)) {
547+ if (epicsTimeOK == epicsTimeGetCurrent(&ts)) {
548 *pseconds = ts.secPastEpoch + ((double)(ts.nsec)) * 1e-9;
549 return 0;
550 }

Subscribers

People subscribed via source and target branches