summaryrefslogtreecommitdiffstats
path: root/unix
diff options
context:
space:
mode:
authorhobbs <hobbs>2002-02-08 09:33:03 (GMT)
committerhobbs <hobbs>2002-02-08 09:33:03 (GMT)
commit7946e043840cfab27940a93f7647d136eda8b6d4 (patch)
treeddc852096661b311770cc5de932600eeb110f05f /unix
parent9b69f5ed87074454c606fad8f9c5f33faa52d88a (diff)
downloadtcl-7946e043840cfab27940a93f7647d136eda8b6d4.zip
tcl-7946e043840cfab27940a93f7647d136eda8b6d4.tar.gz
tcl-7946e043840cfab27940a93f7647d136eda8b6d4.tar.bz2
* unix/tclUnixPort.h:
* unix/tclUnixThrd.c: added thread-safe versions of readdir, localtime, gmtime and inet_ntoa for threaded build. (jgdavidson)
Diffstat (limited to 'unix')
-rw-r--r--unix/tclUnixPort.h10
-rw-r--r--unix/tclUnixThrd.c71
2 files changed, 79 insertions, 2 deletions
diff --git a/unix/tclUnixPort.h b/unix/tclUnixPort.h
index 4ca092a..0fafe9f 100644
--- a/unix/tclUnixPort.h
+++ b/unix/tclUnixPort.h
@@ -19,7 +19,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclUnixPort.h,v 1.18 2001/08/30 08:53:15 vincentdarley Exp $
+ * RCS: @(#) $Id: tclUnixPort.h,v 1.19 2002/02/08 09:33:03 hobbs Exp $
*/
#ifndef _TCLUNIXPORT
@@ -497,6 +497,14 @@ typedef pthread_mutex_t TclpMutex;
EXTERN void TclpMutexInit _ANSI_ARGS_((TclpMutex *mPtr));
EXTERN void TclpMutexLock _ANSI_ARGS_((TclpMutex *mPtr));
EXTERN void TclpMutexUnlock _ANSI_ARGS_((TclpMutex *mPtr));
+EXTERN struct dirent * TclpReaddir(DIR *);
+EXTERN struct tm * TclpLocaltime(time_t *);
+EXTERN struct tm * TclpGmtime(time_t *);
+EXTERN char * TclpInetNtoa(struct in_addr);
+#define readdir(x) TclpReaddir(x)
+#define localtime(x) TclpLocaltime(x)
+#define gmtime(x) TclpGmtime(x)
+#define inet_ntoa(x) TclpInetNtoa(x)
#else
typedef int TclpMutex;
#define TclpMutexInit(a)
diff --git a/unix/tclUnixThrd.c b/unix/tclUnixThrd.c
index ccffe3a..5086b2d 100644
--- a/unix/tclUnixThrd.c
+++ b/unix/tclUnixThrd.c
@@ -19,6 +19,18 @@
#include "tclPort.h"
#include "pthread.h"
+typedef struct ThreadSpecificData {
+ char nabuf[16];
+ struct tm gtbuf;
+ struct tm ltbuf;
+ struct {
+ struct dirent ent;
+ char name[PATH_MAX+1];
+ } rdbuf;
+} ThreadSpecificData;
+
+static Tcl_ThreadDataKey dataKey;
+
/*
* masterLock is used to serialize creation of mutexes, condition
* variables, and thread local storage.
@@ -760,8 +772,65 @@ TclpFinalizeCondition(condPtr)
*condPtr = NULL;
}
}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclpReaddir, TclpLocaltime, TclpGmtime, TclpInetNtoa --
+ *
+ * These procedures replace core C versions to be used in a
+ * threaded environment.
+ *
+ * Results:
+ * See documentation of C functions.
+ *
+ * Side effects:
+ * See documentation of C functions.
+ *
+ *----------------------------------------------------------------------
+ */
+struct dirent *
+TclpReaddir(DIR * dir)
+{
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+ struct dirent *ent;
+ ent = &tsdPtr->rdbuf.ent;
+ if (readdir_r(dir, ent, &ent) != 0) {
+ ent = NULL;
+ }
+ return ent;
+}
-#endif /* TCL_THREADS */
+struct tm *
+TclpLocaltime(time_t * clock)
+{
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+ return localtime_r(clock, &tsdPtr->ltbuf);
+}
+
+struct tm *
+TclpGmtime(time_t * clock)
+{
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+ return gmtime_r(clock, &tsdPtr->gtbuf);
+}
+
+char *
+TclpInetNtoa(struct in_addr addr)
+{
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+ union {
+ unsigned long l;
+ unsigned char b[4];
+ } u;
+
+ u.l = (unsigned long) addr.s_addr;
+ sprintf(tsdPtr->nabuf, "%u.%u.%u.%u", u.b[0], u.b[1], u.b[2], u.b[3]);
+ return tsdPtr->nabuf;
+}
+
+#endif /* TCL_THREADS */