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:
3
NEWS
3
NEWS
@ -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
|
||||
|
||||
|
||||
12
localtime.c
12
localtime.c
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user