summaryrefslogtreecommitdiff
path: root/time/localtime.c
diff options
context:
space:
mode:
Diffstat (limited to 'time/localtime.c')
-rw-r--r--time/localtime.c78
1 files changed, 52 insertions, 26 deletions
diff --git a/time/localtime.c b/time/localtime.c
index 5e1dd0a5b5..f228776952 100644
--- a/time/localtime.c
+++ b/time/localtime.c
@@ -1,4 +1,4 @@
-/* localtime -- convert `time_t' to `struct tm' in local time zone
+/* Convert `time_t' to `struct tm' in local time zone.
Copyright (C) 1991, 92, 93, 95, 96 Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -26,29 +26,22 @@ struct tm _tmbuf;
/* Prototype for the internal function to get information based on TZ. */
extern void __tzset_internal __P ((void));
+extern int __tz_compute __P ((time_t timer, struct tm *tp));
+extern int __tzfile_compute __P ((time_t timer,
+ long int *leap_correct, int *leap_hit));
+extern int __use_tzfile;
-/* Return the `struct tm' representation of *TIMER in the local timezone. */
-struct tm *
-localtime (timer)
- const time_t *timer;
-{
- return __localtime_r (timer, &_tmbuf);
-}
+/* This lock is defined in tzset.c and locks all the data defined there
+ and in tzfile.c; the internal functions do no locking themselves.
+ This lock is only taken here and in `tzset'. */
+__libc_lock_define (extern, __tzset_lock)
-struct tm *
-__localtime_r (timer, tp)
- const time_t *timer;
- struct tm *tp;
+
+/* Return the `struct tm' representation of *TIMER in the local timezone. */
+static struct tm *
+localtime_internal (const time_t *timer, struct tm *tp)
{
- /* This lock is defined in tzset.c and locks all the data defined there
- and in tzfile.c; the internal functions do no locking themselves.
- This lock is only taken here and in `tzset'. */
- __libc_lock_define (extern, __tzset_lock)
- extern int __use_tzfile;
- extern int __tz_compute __P ((time_t timer, struct tm *tp));
- extern int __tzfile_compute __P ((time_t timer,
- long int *leap_correct, int *leap_hit));
long int leap_correction;
int leap_extra_secs;
@@ -58,11 +51,6 @@ __localtime_r (timer, tp)
return NULL;
}
- __libc_lock_lock (__tzset_lock);
-
- /* Make sure the database is initialized. */
- __tzset_internal ();
-
if (__use_tzfile)
{
if (! __tzfile_compute (*timer, &leap_correction, &leap_extra_secs))
@@ -86,8 +74,46 @@ __localtime_r (timer, tp)
tp->tm_zone = __tzname[__daylight];
}
+ return tp;
+}
+
+
+/* POSIX.1 8.3.7.2 says that localtime_r is not required to set
+ tzname. This is a good idea since this allows at least a bit more
+ parallelism. */
+
+struct tm *
+localtime (timer)
+ const time_t *timer;
+{
+ struct tm *result;
+
+ __libc_lock_lock (__tzset_lock);
+
+ /* Make sure the database is initialized. */
+ __tzset_internal ();
+
+ result = localtime_internal (timer, &_tmbuf);
+
__libc_lock_unlock (__tzset_lock);
- return tp;
+ return result;
+}
+
+
+struct tm *
+__localtime_r (timer, tp)
+ const time_t *timer;
+ struct tm *tp;
+{
+ struct tm *result;
+
+ __libc_lock_lock (__tzset_lock);
+
+ result = localtime_internal (timer, tp);
+
+ __libc_lock_unlock (__tzset_lock);
+
+ return result;
}
weak_alias (__localtime_r, localtime_r)