summaryrefslogtreecommitdiffstats
path: root/lib/libc/stdtime
diff options
context:
space:
mode:
authorjulian <julian@FreeBSD.org>1996-01-22 00:02:33 +0000
committerjulian <julian@FreeBSD.org>1996-01-22 00:02:33 +0000
commit619b731f5bb5e09dcf1eaf1fbd96383ca64398fd (patch)
treea89c7f50ec371cef4418259b9dccdd31ebb2f61f /lib/libc/stdtime
parent663b14fb2f3198fb0bfb62ae16b6b56c2a4dd055 (diff)
downloadFreeBSD-src-619b731f5bb5e09dcf1eaf1fbd96383ca64398fd.zip
FreeBSD-src-619b731f5bb5e09dcf1eaf1fbd96383ca64398fd.tar.gz
Reviewed by: julian and (hsu?)
Submitted by: John Birrel(L?) changes for threadsafe operations
Diffstat (limited to 'lib/libc/stdtime')
-rw-r--r--lib/libc/stdtime/localtime.c130
1 files changed, 129 insertions, 1 deletions
diff --git a/lib/libc/stdtime/localtime.c b/lib/libc/stdtime/localtime.c
index d6337ff..3507641 100644
--- a/lib/libc/stdtime/localtime.c
+++ b/lib/libc/stdtime/localtime.c
@@ -15,6 +15,10 @@ static char elsieid[] = "@(#)localtime.c 7.44";
#include "private.h"
#include "tzfile.h"
#include "fcntl.h"
+#ifdef _THREAD_SAFE
+#include <pthread.h>
+#include "pthread_private.h"
+#endif
/*
** SunOS 4.1.1 headers lack O_BINARY.
@@ -158,6 +162,10 @@ static struct state gmtmem;
static char lcl_TZname[TZ_STRLEN_MAX + 1];
static int lcl_is_set;
static int gmt_is_set;
+#ifdef _THREAD_SAFE
+static pthread_mutex_t lcl_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t gmt_mutex = PTHREAD_MUTEX_INITIALIZER;
+#endif
char * tzname[2] = {
wildabbr,
@@ -906,8 +914,13 @@ struct state * const sp;
*/
static
#endif /* !defined STD_INSPIRED */
+#ifdef _THREAD_SAFE
+void
+tzsetwall_basic P((void))
+#else
void
tzsetwall P((void))
+#endif
{
if (lcl_is_set < 0)
return;
@@ -927,8 +940,23 @@ tzsetwall P((void))
settzname();
}
+#ifdef _THREAD_SAFE
+void
+tzsetwall P((void))
+{
+ pthread_mutex_lock(&lcl_mutex);
+ tzsetwall_basic();
+ pthread_mutex_unlock(&lcl_mutex);
+}
+#endif
+
+#ifdef _THREAD_SAFE
+static void
+tzset_basic P((void))
+#else
void
tzset P((void))
+#endif
{
register const char * name;
@@ -968,6 +996,16 @@ tzset P((void))
settzname();
}
+#ifdef _THREAD_SAFE
+void
+tzset P((void))
+{
+ pthread_mutex_lock(&lcl_mutex);
+ tzset_basic();
+ pthread_mutex_unlock(&lcl_mutex);
+}
+#endif
+
/*
** The easy way to behave "as if no library function calls" localtime
** is to not call it--so we drop its guts into "localsub", which can be
@@ -1024,13 +1062,55 @@ struct tm * const tmp;
#endif /* defined TM_ZONE */
}
+#ifdef _THREAD_SAFE
+int
+localtime_r(timep, p_tm)
+const time_t * const timep;
+struct tm *p_tm;
+{
+ pthread_mutex_lock(&lcl_mutex);
+ tzset();
+ localsub(timep, 0L, p_tm);
+ pthread_mutex_unlock(&lcl_mutex);
+ return(0);
+}
+#endif
+
struct tm *
localtime(timep)
const time_t * const timep;
{
+#ifdef _THREAD_SAFE
+ static pthread_mutex_t localtime_mutex = PTHREAD_MUTEX_INITIALIZER;
+ static pthread_key_t localtime_key = -1;
+ struct tm *p_tm;
+
+ pthread_mutex_lock(&localtime_mutex);
+ if (localtime_key < 0) {
+ if (pthread_keycreate(&localtime_key, free) < 0) {
+ pthread_mutex_unlock(&localtime_mutex);
+ return(NULL);
+ }
+ }
+ pthread_mutex_unlock(&localtime_mutex);
+ if (pthread_getspecific(localtime_key,(void **) &p_tm) != 0) {
+ return(NULL);
+ } else if (p_tm == NULL) {
+ if ((p_tm = (struct tm *)malloc(sizeof(struct tm))) == NULL) {
+ return(NULL);
+ }
+ pthread_setspecific(localtime_key, p_tm);
+ }
+ pthread_mutex_lock(&lcl_mutex);
+ tzset();
+ localsub(timep, 0L, p_tm);
+ pthread_mutex_unlock(&lcl_mutex);
+ return p_tm;
+#else
tzset();
localsub(timep, 0L, &tm);
return &tm;
+#endif
}
/*
@@ -1043,6 +1123,9 @@ const time_t * const timep;
const long offset;
struct tm * const tmp;
{
+#ifdef _THREAD_SAFE
+ pthread_mutex_lock(&gmt_mutex);
+#endif
if (!gmt_is_set) {
gmt_is_set = TRUE;
#ifdef ALL_STATE
@@ -1051,6 +1134,9 @@ struct tm * const tmp;
#endif /* defined ALL_STATE */
gmtload(gmtptr);
}
+#ifdef _THREAD_SAFE
+ pthread_mutex_unlock(&gmt_mutex);
+#endif
timesub(timep, offset, gmtptr, tmp);
#ifdef TM_ZONE
/*
@@ -1077,9 +1163,43 @@ struct tm *
gmtime(timep)
const time_t * const timep;
{
+#ifdef _THREAD_SAFE
+ static pthread_mutex_t gmtime_mutex = PTHREAD_MUTEX_INITIALIZER;
+ static pthread_key_t gmtime_key = -1;
+ struct tm *p_tm;
+
+ pthread_mutex_lock(&gmtime_mutex);
+ if (gmtime_key < 0) {
+ if (pthread_keycreate(&gmtime_key, free) < 0) {
+ pthread_mutex_unlock(&gmtime_mutex);
+ return(NULL);
+ }
+ }
+ pthread_mutex_unlock(&gmtime_mutex);
+ if (pthread_getspecific(gmtime_key,(void **) &p_tm) != 0) {
+ return(NULL);
+ } else if (p_tm == NULL) {
+ if ((p_tm = (struct tm *)malloc(sizeof(struct tm))) == NULL) {
+ return(NULL);
+ }
+ pthread_setspecific(gmtime_key, p_tm);
+ }
+ gmtsub(timep, 0L, p_tm);
+ return(p_tm);
+#else
gmtsub(timep, 0L, &tm);
return &tm;
+#endif
+}
+
+#ifdef _THREAD_SAFE
+int
+gmtime_r(const time_t * timep, struct tm * tm)
+{
+ gmtsub(timep, 0L, tm);
+ return(0);
}
+#endif
#ifdef STD_INSPIRED
@@ -1482,8 +1602,16 @@ time_t
mktime(tmp)
struct tm * const tmp;
{
+ time_t mktime_return_value;
+#ifdef _THREAD_SAFE
+ pthread_mutex_lock(&lcl_mutex);
+#endif
tzset();
- return time1(tmp, localsub, 0L);
+ mktime_return_value = time1(tmp, localsub, 0L);
+#ifdef _THREAD_SAFE
+ pthread_mutex_unlock(&lcl_mutex);
+#endif
+ return(mktime_return_value);
}
#ifdef STD_INSPIRED
OpenPOWER on IntegriCloud