Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/newlib
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2015-03-31 12:22:50 +0300
committerCorinna Vinschen <corinna@vinschen.de>2015-04-23 22:57:08 +0300
commitb3a09ae34bd691c95bc41a594a40a808455d748a (patch)
treea5a692e255bbc1ee7473c4a5426e333e51858464 /newlib
parentc11779332651dd2f3b12f5ec48202fa7e547272b (diff)
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>
Diffstat (limited to 'newlib')
-rw-r--r--newlib/ChangeLog8
-rw-r--r--newlib/libc/time/lcltime_r.c2
-rw-r--r--newlib/libc/time/mktime.c4
-rw-r--r--newlib/libc/time/strftime.c16
4 files changed, 25 insertions, 5 deletions
diff --git a/newlib/ChangeLog b/newlib/ChangeLog
index 420354ef6..e615421d1 100644
--- a/newlib/ChangeLog
+++ b/newlib/ChangeLog
@@ -1,5 +1,13 @@
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.
(_tzset_unlocked): Ditto.
* libc/time/tzset.c (_tzset_unlocked): New function, call
diff --git a/newlib/libc/time/lcltime_r.c b/newlib/libc/time/lcltime_r.c
index 8a69e40ee..3342e9906 100644
--- a/newlib/libc/time/lcltime_r.c
+++ b/newlib/libc/time/lcltime_r.c
@@ -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))
diff --git a/newlib/libc/time/mktime.c b/newlib/libc/time/mktime.c
index 8669fbdfb..44c0257f7 100644
--- a/newlib/libc/time/mktime.c
+++ b/newlib/libc/time/mktime.c
@@ -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;
diff --git a/newlib/libc/time/strftime.c b/newlib/libc/time/strftime.c
index 72f06d32e..9e677346e 100644
--- a/newlib/libc/time/strftime.c
+++ b/newlib/libc/time/strftime.c
@@ -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);