diff options
| author | Edward Welbourne <edward.welbourne@qt.io> | 2023-02-02 13:54:13 +0100 |
|---|---|---|
| committer | Edward Welbourne <edward.welbourne@qt.io> | 2023-02-03 14:45:31 +0100 |
| commit | b62ac40987e4a53be912227230c4914e77c74e88 (patch) | |
| tree | 7ce6679ad4cda94f5fac9f7e005593586192f9f0 /src/corelib/global/qtenvironmentvariables.cpp | |
| parent | 9d1a3582f33a0820a4f0f5b7fe84a22a8c8d967b (diff) | |
Move qtLocalTime() to qtenvironmentvariables.cpp as qLocalTime()
The new name better matches the names of existing functions there.
A comment on the old code noted that such a move should really be
done, so as to correctly share the environment-mutex locking.
In the process, move the (now three) time-related internal functions
from qglobal_p.h to a new qtenvironmentvariables_p.h since that's the
natural place for them given where they're defined (and the fact that
they're for internal use only).
Change-Id: Ib028baebaf31a806a2c0c97caaaba0a466c11cea
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/global/qtenvironmentvariables.cpp')
| -rw-r--r-- | src/corelib/global/qtenvironmentvariables.cpp | 50 |
1 files changed, 44 insertions, 6 deletions
diff --git a/src/corelib/global/qtenvironmentvariables.cpp b/src/corelib/global/qtenvironmentvariables.cpp index 4046beae1f4..4f2a263cc43 100644 --- a/src/corelib/global/qtenvironmentvariables.cpp +++ b/src/corelib/global/qtenvironmentvariables.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qtenvironmentvariables.h" +#include "qtenvironmentvariables_p.h" #include <qplatformdefs.h> #include <QtCore/qbytearray.h> @@ -330,9 +331,11 @@ bool qunsetenv(const char *varName) #endif } -/* - Wraps tzset(), which accesses the environment, so should only be called while - we hold the lock on the environment mutex. +/* Various time-related APIs that need to consult system settings also need + protection with the same lock as the environment, since those system settings + include part of the environment (principally TZ). + + First, tzset(), which POSIX explicitly says accesses the environment. */ void qTzSet() { @@ -344,9 +347,8 @@ void qTzSet() #endif // Q_OS_WIN } -/* - Wrap mktime(), which is specified to behave as if it called tzset(), hence - shares its implicit environment-dependence. +/* Wrap mktime(), which is specified to behave as if it called tzset(), hence + shares its implicit environment-dependence. */ time_t qMkTime(struct tm *when) { @@ -354,4 +356,40 @@ time_t qMkTime(struct tm *when) return mktime(when); } +/* For localtime(), POSIX mandates that it behave as if it called tzset(). + For the alternatives to it, we need (if only for compatibility) to do the + same explicitly, which should ensure a re-parse of timezone info. +*/ +bool qLocalTime(time_t utc, struct tm *local) +{ + const auto locker = qt_scoped_lock(environmentMutex); +#if defined(Q_OS_WIN) + // The doc of localtime_s() says that it corrects for the same things + // _tzset() sets the globals for, but QTBUG-109974 reveals a need for an + // explicit call, all the same. + _tzset(); + return !localtime_s(local, &utc); +#elif QT_CONFIG(thread) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) + // Use the reentrant version of localtime() where available, as it is + // thread-safe and doesn't use a shared static data area. + // As localtime_r() is not specified to work as if it called tzset(), + // make an explicit call. + tzset(); + if (tm *res = localtime_r(&utc, local)) { + Q_ASSERT(res == local); + return true; + } + return false; +#else + // POSIX mandates that localtime() behaves as if it called tzset(). + // Returns shared static data which may be overwritten at any time (albeit + // our lock probably keeps it safe). So copy the result promptly: + if (tm *res = localtime(&utc)) { + *local = *res; + return true; + } + return false; +#endif +} + QT_END_NAMESPACE |
