On 2019-08-17 18:38, Paul Eggert wrote:
Brian Inglis wrote:
WG14/C is looking at: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2402.pdf which seems somewhat based on the POSIX standard.
Thanks for the heads-up. I see that this WG14/C draft is calling localtime_r "reentrant", but it's not: in POSIX, localtime_r relies on global state to obtain the time zone, and behavior is undefined if one thread calls localtime_r while another thread is changing the time zone. Similarly for some of the other "reentrant" functions mentioned in that draft.
If WG14 wants reentrant, it should standardize localtime_rz etc. a la tzcode and NetBSD. These functions avoid the races inherent to localtime_r etc. I'll cc. this to Jens Gustedt to give the draft's author a heads-up. Even if WG14 decides to stick with POSIXish rather than reentrant functions, the rationale document should explain why.
To me and probably most, *thread safe* also implies ability to safely call any other function, including changing the time zone per thread: either constraint, for support, or its lack, of different time zones (or anything else relevant) per thread, should be explicitly specified and referenced in any "thread safe" interface definition, or possibly punted to have the implementation so specify. [Despite the mooted "unpopularity" of C with developers, it's still not looking like anything could replace it for core libraries, utilities, and systems, in the next few decades, so adding robustness to the specifications should be a focus, in the ways suggested below. Adding bounds checking interfaces a la Annex K.3.8 with rsize_t AKA size_t, and errno_t ...time_s() functions, which I have not seen mentioned in any time.h I have come across since 2011 (it appears MS had something like this around 2005), may be more useful and successful if it were limited to only adding constraints to widely existing implementations like ...time_rz() or strftime_l(). If innovating interfaces, such as e.g. timespec_get(), using POSIX struct timespec, rather than POSIX clock_gettime(), add value with generality and longevity (as with GNU libraries and utilities), not just a different interface to existing function e.g. extend and fix struct time {time_t t_s; time_as t_as;} where time_as is in attoseconds ~1e18/s ~2^60/s, similar to previous extensions (unless there are reasons to prefer the NTP datestamp-like seconds fraction with the MSB .5s and the LSB ~0.05as), with prototypes like time_get( struct time t [static 1], enum time_base base), and add things like tm_as to struct tm (time_t tm_sec would also be welcome), with some new %fw.pX strftime format, and/or e.g. %fw.pS, %fw.ps. For features, remove months and maybe also years from yyyymmL dates that nobody remembers, specify simple numbers for versions like __STDC_VERSION_TIME_H__ 2 or provide simple equivalents enumerating the versions for tests e.g. __STDC_VERSION_TIME_H_2__. Add symbols for all the magic numbers still littering function specifications, including parameter and return values like 0/-1, as their meanings are very context dependent: e.g. _TIME_SUCCESS and _TIME_FAILURE, or if necessary _LOCALTIME_SUCCESS and _LOCALTIME_FAILURE, ..., etc. These should all be pre-specified in the library feature interface headers, rather than being hard coded, enumerated or defined by ourselves in company, project, site, group, or developer local headers wrapping uses of the standard headers.] -- Take care. Thanks, Brian Inglis, Calgary, Alberta, Canada This email may be disturbing to some readers as it contains too much technical detail. Reader discretion is advised.