From: Bruno Haible <bruno@clisp.org>
To: bug-gnulib@gnu.org
Subject: Re: MT-unsafe time modules
Date: Sat, 10 Feb 2024 12:10:44 +0100 [thread overview]
Message-ID: <2364117.OYXXYNVTWy@nimes> (raw)
In-Reply-To: <3755090.VQhiAETyHQ@nimes>
> * These need to be made MT-safe:
>
> mktime, mktime-internal
> timegm
>
> time_r
>
> time_rz
> c-nstrftime, nstrftime
> parse-datetime, parse-datetime2
For these modules, the next function to provide in an MT-safe way is
localtime_r. On native Windows, when the 'localtime_s' function [1][2]
is not available, such as on the older Windows versions that Emacs cares
about, the solution is to use GetTimeZoneInformation [3].
The next function, then, is a localtime_r variant with time zone argument.
It's needed
* for implementing 'localtime_rz', in the 'time_rz' module.
* as a 'convert' subroutine for the 'mktime_z' function, in the 'time_rz'
module.
* indirectly by nstrftime, c-nstrftime, fprintftime, parse-datetime,
that all rely on 'time_rz'.
Such a localtime_r variant with time zone argument needs to use the
time zone database that the system has access to. But the only public
API that the system offers (localtime{,_r}) relies on the environment "TZ"
variable "TZ" and some global variables (tzname, timezone, daylight)
derived from it, and changing an environment variable is not MT-safe.
So, there are only two approaches that I can see:
(a) Read the time zone database information into memory from a file
shipped together with Gnulib. This is how the libstdc++ implementation
of the C++ time zone functionality [4] does it [5][6].
(b) Read the time zone database information into memory from the
system locations, in a platform dependent way.
The code for doing this exists in glibc and libstdc++ and would need to be
adapted.
BUT this is a major project: it would take several weeks.
And it is overkill for
- the proposed safer_ctime function,
- most practical uses of nstrftime, c_nstrftime.
Namely, for these cases, a general timezone_t is not needed, only a boolean
that covers the case of local time and GMT/UTC. And these cases *can* be
done in a multithread-safe way:
- The value of "TZ" does not need to be changed on the fly.
- The values of the global variables (tzname, timezone, daylight) may
be set through tzset(), in a thread, but these values are OK for the
other threads as well, since getenv ("TZ") is the same in all threads.
- The GMT/UTC case can be implemented by not looking at "TZ" nor the
global variables.
I therefore intend to do this latter part:
1) Make localtime_r on native Windows MT-safe.
2) Document which LGPLed interfaces are not MT-safe.
3) Provide an MT-safe and bug-fixed 'strftime' function (that assumes
local time, no time zone argument).
4) Provide an analogous 'c_strftime' function that does not even access
"TZ".
5) The proposed safer_ctime, based on localtime_r and c_strftime.
Bruno
[1] https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/localtime-s-localtime32-s-localtime64-s
[2] https://learn.microsoft.com/en-us/previous-versions/a442x3ye
[3] https://learn.microsoft.com/en-us/windows/win32/api/timezoneapi/nf-timezoneapi-gettimezoneinformation
[4] https://en.cppreference.com/w/cpp/chrono
[5] https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=libstdc%2B%2B-v3/include/std/chrono
[6] https://gcc.gnu.org/git/?p=gcc.git;a=tree;f=libstdc%2B%2B-v3/src/c%2B%2B20
next prev parent reply other threads:[~2024-02-10 11:11 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-02-09 17:43 MT-unsafe time modules Bruno Haible
2024-02-09 20:22 ` Bruno Haible
2024-02-10 11:10 ` Bruno Haible [this message]
2024-02-11 12:46 ` localtime on native Windows Bruno Haible
2024-02-13 2:02 ` Paul Eggert
2024-02-18 2:38 ` Bruno Haible
2024-02-18 4:50 ` Paul Eggert
2024-02-18 14:38 ` Bruno Haible
2024-02-18 19:05 ` Paul Eggert
2024-02-11 10:43 ` MT-unsafe time modules Bruno Haible
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://lists.gnu.org/mailman/listinfo/bug-gnulib
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=2364117.OYXXYNVTWy@nimes \
--to=bruno@clisp.org \
--cc=bug-gnulib@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).