[tz] WG14/C localtime_r draft is not reentrant

Brian Inglis Brian.Inglis at SystematicSw.ab.ca
Sun Aug 18 21:30:26 UTC 2019

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.

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
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

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.

More information about the tz mailing list