mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
MFC 199607, 200797, 201270, 201669:
Use pthread_once() to initialize the thread-local storage for localtime() and gmtime() and _once() to initialize gmt state rather than home-rolled versions using pthread mutex locks.
This commit is contained in:
parent
d46150d432
commit
8e42544da7
1 changed files with 41 additions and 40 deletions
|
|
@ -235,9 +235,14 @@ static struct state gmtmem;
|
|||
|
||||
static char lcl_TZname[TZ_STRLEN_MAX + 1];
|
||||
static int lcl_is_set;
|
||||
static int gmt_is_set;
|
||||
static pthread_once_t gmt_once = PTHREAD_ONCE_INIT;
|
||||
static pthread_rwlock_t lcl_rwlock = PTHREAD_RWLOCK_INITIALIZER;
|
||||
static pthread_mutex_t gmt_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_once_t gmtime_once = PTHREAD_ONCE_INIT;
|
||||
static pthread_key_t gmtime_key;
|
||||
static int gmtime_key_error;
|
||||
static pthread_once_t localtime_once = PTHREAD_ONCE_INIT;
|
||||
static pthread_key_t localtime_key;
|
||||
static int localtime_key_error;
|
||||
|
||||
char * tzname[2] = {
|
||||
wildabbr,
|
||||
|
|
@ -1407,27 +1412,24 @@ struct tm * const tmp;
|
|||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
localtime_key_init(void)
|
||||
{
|
||||
|
||||
localtime_key_error = _pthread_key_create(&localtime_key, free);
|
||||
}
|
||||
|
||||
struct tm *
|
||||
localtime(timep)
|
||||
const time_t * const timep;
|
||||
{
|
||||
static pthread_mutex_t localtime_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_key_t localtime_key = -1;
|
||||
struct tm *p_tm;
|
||||
int r;
|
||||
|
||||
if (__isthreaded != 0) {
|
||||
if (localtime_key < 0) {
|
||||
_pthread_mutex_lock(&localtime_mutex);
|
||||
if (localtime_key < 0) {
|
||||
if ((r = _pthread_key_create(&localtime_key,
|
||||
free)) != 0) {
|
||||
_pthread_mutex_unlock(&localtime_mutex);
|
||||
errno = r;
|
||||
return(NULL);
|
||||
}
|
||||
}
|
||||
_pthread_mutex_unlock(&localtime_mutex);
|
||||
_pthread_once(&localtime_once, localtime_key_init);
|
||||
if (localtime_key_error != 0) {
|
||||
errno = localtime_key_error;
|
||||
return(NULL);
|
||||
}
|
||||
p_tm = _pthread_getspecific(localtime_key);
|
||||
if (p_tm == NULL) {
|
||||
|
|
@ -1464,6 +1466,17 @@ struct tm * tmp;
|
|||
return tmp;
|
||||
}
|
||||
|
||||
static void
|
||||
gmt_init(void)
|
||||
{
|
||||
|
||||
#ifdef ALL_STATE
|
||||
gmtptr = (struct state *) malloc(sizeof *gmtptr);
|
||||
if (gmtptr != NULL)
|
||||
#endif /* defined ALL_STATE */
|
||||
gmtload(gmtptr);
|
||||
}
|
||||
|
||||
/*
|
||||
** gmtsub is to gmtime as localsub is to localtime.
|
||||
*/
|
||||
|
|
@ -1476,16 +1489,7 @@ struct tm * const tmp;
|
|||
{
|
||||
register struct tm * result;
|
||||
|
||||
_MUTEX_LOCK(&gmt_mutex);
|
||||
if (!gmt_is_set) {
|
||||
#ifdef ALL_STATE
|
||||
gmtptr = (struct state *) malloc(sizeof *gmtptr);
|
||||
if (gmtptr != NULL)
|
||||
#endif /* defined ALL_STATE */
|
||||
gmtload(gmtptr);
|
||||
gmt_is_set = TRUE;
|
||||
}
|
||||
_MUTEX_UNLOCK(&gmt_mutex);
|
||||
_once(&gmt_once, gmt_init);
|
||||
result = timesub(timep, offset, gmtptr, tmp);
|
||||
#ifdef TM_ZONE
|
||||
/*
|
||||
|
|
@ -1509,27 +1513,24 @@ struct tm * const tmp;
|
|||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
gmtime_key_init(void)
|
||||
{
|
||||
|
||||
gmtime_key_error = _pthread_key_create(&gmtime_key, free);
|
||||
}
|
||||
|
||||
struct tm *
|
||||
gmtime(timep)
|
||||
const time_t * const timep;
|
||||
{
|
||||
static pthread_mutex_t gmtime_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_key_t gmtime_key = -1;
|
||||
struct tm *p_tm;
|
||||
int r;
|
||||
|
||||
if (__isthreaded != 0) {
|
||||
if (gmtime_key < 0) {
|
||||
_pthread_mutex_lock(&gmtime_mutex);
|
||||
if (gmtime_key < 0) {
|
||||
if ((r = _pthread_key_create(&gmtime_key,
|
||||
free)) != 0) {
|
||||
_pthread_mutex_unlock(&gmtime_mutex);
|
||||
errno = r;
|
||||
return(NULL);
|
||||
}
|
||||
}
|
||||
_pthread_mutex_unlock(&gmtime_mutex);
|
||||
_pthread_once(&gmtime_once, gmtime_key_init);
|
||||
if (gmtime_key_error != 0) {
|
||||
errno = gmtime_key_error;
|
||||
return(NULL);
|
||||
}
|
||||
/*
|
||||
* Changed to follow POSIX.1 threads standard, which
|
||||
|
|
|
|||
Loading…
Reference in a new issue