mirror of
https://github.com/postgres/postgres.git
synced 2025-08-18 12:22:09 +03:00
thread-safety: gmtime_r(), localtime_r()
Use gmtime_r() and localtime_r() instead of gmtime() and localtime(), for thread-safety. There are a few affected calls in libpq and ecpg's libpgtypes, which are probably effectively bugs, because those libraries already claim to be thread-safe. There is one affected call in the backend. Most of the backend otherwise uses the custom functions pg_gmtime() and pg_localtime(), which are implemented differently. While we're here, change the call in the backend to gmtime*() instead of localtime*(), since for that use time zone behavior is irrelevant, and this side-steps any questions about when time zones are initialized by localtime_r() vs localtime(). Portability: gmtime_r() and localtime_r() are in POSIX but are not available on Windows. Windows has functions gmtime_s() and localtime_s() that can fulfill the same purpose, so we add some small wrappers around them. (Note that these *_s() functions are also different from the *_s() functions in the bounds-checking extension of C11. We are not using those here.) On MinGW, you can get the POSIX-style *_r() functions by defining _POSIX_C_SOURCE appropriately before including <time.h>. This leads to a conflict at least in plpython because apparently _POSIX_C_SOURCE gets defined in some header there, and then our replacement definitions conflict with the system definitions. To avoid that sort of thing, we now always define _POSIX_C_SOURCE on MinGW and use the POSIX-style functions here. Reviewed-by: Stepan Neretin <sncfmgg@gmail.com> Reviewed-by: Heikki Linnakangas <hlinnaka@iki.fi> Reviewed-by: Thomas Munro <thomas.munro@gmail.com> Discussion: https://www.postgresql.org/message-id/flat/eba1dc75-298e-4c46-8869-48ba8aad7d70@eisentraut.org
This commit is contained in:
@@ -81,6 +81,7 @@ pqTraceFormatTimestamp(char *timestr, size_t ts_len)
|
||||
{
|
||||
struct timeval tval;
|
||||
time_t now;
|
||||
struct tm tmbuf;
|
||||
|
||||
gettimeofday(&tval, NULL);
|
||||
|
||||
@@ -93,7 +94,7 @@ pqTraceFormatTimestamp(char *timestr, size_t ts_len)
|
||||
now = tval.tv_sec;
|
||||
strftime(timestr, ts_len,
|
||||
"%Y-%m-%d %H:%M:%S",
|
||||
localtime(&now));
|
||||
localtime_r(&now, &tmbuf));
|
||||
/* append microseconds */
|
||||
snprintf(timestr + strlen(timestr), ts_len - strlen(timestr),
|
||||
".%06u", (unsigned int) (tval.tv_usec));
|
||||
|
Reference in New Issue
Block a user