Avoid excessive locking and calling tzset in time functions.

* libc/time/lcltime_r.c (localtime_r): Call _tzset_unlocked inside
	TZ lock.
	* libc/time/mktime.c (mktime):  Ditto.
	* libc/time/strftime.c (strftime, wcsftime): Ditto.  Guard against
	calling _tzset_unlocked more than once (baring recursion).

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2015-03-31 11:22:50 +02:00
parent 5f4e1e895c
commit 70399a721c
No known key found for this signature in database
GPG Key ID: F536069DAE444FA0
4 changed files with 25 additions and 5 deletions

View File

@ -1,3 +1,11 @@
2015-03-31 Corinna Vinschen <vinschen@redhat.com>
* libc/time/lcltime_r.c (localtime_r): Call _tzset_unlocked inside
TZ lock.
* libc/time/mktime.c (mktime): Ditto.
* libc/time/strftime.c (strftime, wcsftime): Ditto. Guard against
calling _tzset_unlocked more than once (baring recursion).
2015-03-31 Corinna Vinschen <vinschen@redhat.com>
* libc/time/local.h (_tzset_unlocked_r): Add prototype.

View File

@ -31,8 +31,8 @@ _DEFUN (localtime_r, (tim_p, res),
year = res->tm_year + YEAR_BASE;
ip = __month_lengths[isleap(year)];
tzset ();
TZ_LOCK;
_tzset_unlocked ();
if (_daylight)
{
if (year == tz->__tzyear || __tzcalc_limits (year))

View File

@ -197,10 +197,10 @@ _DEFUN(mktime, (tim_p),
/* compute total seconds */
tim += (days * _SEC_IN_DAY);
tzset ();
TZ_LOCK;
_tzset_unlocked ();
if (_daylight)
{
int tm_isdst;

View File

@ -703,6 +703,7 @@ _DEFUN (strftime, (s, maxsize, format, tim_p),
CHAR alt;
CHAR pad;
unsigned long width;
int tzset_called = 0;
struct lc_time_T *_CurrentTimeLocale = __get_current_time_locale ();
for (;;)
@ -1283,7 +1284,13 @@ recurse:
if (tim_p->tm_isdst >= 0)
{
long offset;
tzset ();
TZ_LOCK;
if (!tzset_called)
{
_tzset_unlocked ();
tzset_called = 1;
}
#if defined (__CYGWIN__)
/* Cygwin must check if the application has been built with or
@ -1302,6 +1309,7 @@ recurse:
but have to use __tzrule for daylight savings. */
offset = -tz->__tzrule[tim_p->tm_isdst > 0].offset;
#endif
TZ_UNLOCK;
len = snprintf (&s[count], maxsize - count, CQ("%+03ld%.2ld"),
offset / SECSPERHOUR,
labs (offset / SECSPERMIN) % 60L);
@ -1314,8 +1322,12 @@ recurse:
size_t size;
const char *tznam = NULL;
tzset ();
TZ_LOCK;
if (!tzset_called)
{
_tzset_unlocked ();
tzset_called = 1;
}
#if defined (__CYGWIN__)
/* See above. */
extern const char *__cygwin_gettzname (const struct tm *tmp);