1
0
mirror of https://frontier.innolan.net/rainlance/amiga-tz.git synced 2025-11-24 04:32:58 +00:00

port to C11 memory model

We don't know of any problems with the previous code on practical
platforms, but it's safer to be portable.
Problem reported by Andy Heninger in:
http://mm.icann.org/pipermail/tz/2014-September/021599.html
* localtime.c (VOLATILE): Remove.  All uses removed.
(gmtcheck): Don't access gmt_is_set until we have the lock.
This may be significantly slower, but it's safer.
(localtime_tzset): Likewise.  This change isn't significantly
slower, though; it's more of a refactoring.
* NEWS: Document this.
This commit is contained in:
Paul Eggert
2014-09-21 08:29:03 -07:00
parent 0eb01e8a0c
commit 9f224b2078
2 changed files with 6 additions and 9 deletions

3
NEWS
View File

@ -30,9 +30,10 @@ Unreleased, experimental changes
An access to uninitalized data has been fixed.
(Thanks to Jörg Richter for reporting the problem.)
When THREAD_SAFE is defined, the code ports to the C11 memory model.
A memory leak has been fixed if ALL_STATE and THREAD_SAFE are defined
and two threads race to initialize data used by gmtime-like functions.
(Thanks to Andy Heninger for reporting the problem.)
(Thanks to Andy Heninger for reporting the problems.)
Changes affecting build procedure

View File

@ -18,12 +18,10 @@
#if THREAD_SAFE
# include <pthread.h>
# define VOLATILE volatile
static pthread_mutex_t locallock = PTHREAD_MUTEX_INITIALIZER;
static int lock(void) { return pthread_mutex_lock(&locallock); }
static void unlock(void) { pthread_mutex_unlock(&locallock); }
#else
# define VOLATILE
static int lock(void) { return 0; }
static void unlock(void) { }
#endif
@ -176,7 +174,7 @@ static struct state gmtmem;
#endif /* !defined TZ_STRLEN_MAX */
static char lcl_TZname[TZ_STRLEN_MAX + 1];
static int VOLATILE lcl_is_set;
static int lcl_is_set;
char * tzname[2] = {
(char *) wildabbr,
@ -1244,9 +1242,7 @@ tzset(void)
static void
gmtcheck(void)
{
static bool VOLATILE gmt_is_set;
if (gmt_is_set)
return;
static bool gmt_is_set;
if (lock() != 0)
return;
if (! gmt_is_set) {
@ -1400,7 +1396,7 @@ localtime_tzset(time_t const *timep, struct tm *tmp, bool settz, bool setname)
errno = err;
return NULL;
}
if (settz)
if (settz || !lcl_is_set)
tzset_unlocked();
tmp = localsub(lclptr, timep, setname, tmp);
unlock();
@ -1416,7 +1412,7 @@ localtime(const time_t *const timep)
struct tm *
localtime_r(const time_t *const timep, struct tm *tmp)
{
return localtime_tzset(timep, tmp, lcl_is_set == 0, false);
return localtime_tzset(timep, tmp, false, false);
}
/*