rbb 99/10/05 23:48:52
Modified: src/lib/apr acconfig.h configure.in
src/lib/apr/include apr_config.h.in apr_errno.h
src/lib/apr/time/unix time.c
Log:
Make time functions threadsafe in APR. This is the current way to make
a function thread-safe, when the C Run-Time function it relies on is NOT
thread-safe. For more information, please read the message that will be
posted to [email protected] regarding this topic.
Revision Changes Path
1.3 +34 -0 apache-2.0/src/lib/apr/acconfig.h
Index: acconfig.h
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/acconfig.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- acconfig.h 1999/08/19 13:31:08 1.2
+++ acconfig.h 1999/10/06 06:48:49 1.3
@@ -66,5 +66,39 @@
Sigfunc *signal(int signo, Sigfunc * func);
#endif
+#ifndef _POSIX_THREAD_SAFE_FUNCTIONS
+#define SAFETY_LOCK(func_name, cnt, name_str) \
+ { \
+ struct lock_t *funclock = lock_##func_name; \
+ if (funclock == NULL) \
+ if (ap_create_lock(cnt, APR_MUTEX, APR_LOCKALL, name_str, &funclock)
!= APR_SUCCESS) \
+ return APR_NOTTHREADSAFE; \
+ if (ap_lock(funclock) != APR_SUCCESS) \
+ return APR_NOTTHREADSAFE; \
+ }
+#else
+#define SAFETY_LOCK(func_name, cnt)
+#endif
+
+#ifndef _POSIX_THREAD_SAFE_FUNCTIONS
+#define SAFETY_UNLOCK(func_name) \
+ if (ap_unlock(lock_##func_name) != APR_SUCCESS) { \
+ return APR_NOTTHREADSAFE; \
+ }
+#else
+#define SAFETY_UNLOCK(func_name, cnt)
+#endif
+
+#ifdef HAVE_GMTIME_R
+#define GMTIME_R(x, y) gmtime_r(x, y)
+#else
+#define GMTIME_R(x, y) memcpy(y, gmtime(x), sizeof(y))
+#endif
+
+#ifdef HAVE_LOCALTIME_R
+#define LOCALTIME_R(x, y) localtime_r(x, y)
+#else
+#define LOCALTIME_R(x, y) memcpy(y, localtime(x), sizeof(y))
+#endif
#endif /* APR_CONFIG_H */
1.14 +2 -0 apache-2.0/src/lib/apr/configure.in
Index: configure.in
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/configure.in,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- configure.in 1999/10/01 09:47:08 1.13
+++ configure.in 1999/10/06 06:48:49 1.14
@@ -198,6 +198,8 @@
AC_CHECK_FUNCS(getpass)
AC_CHECK_FUNC(_getch)
+AC_CHECK_FUNCS(gmtime_r localtime_r)
+
dnl Start building stuff from our information
AC_SUBST(LDLIBS)
AC_SUBST(OPTIM)
1.8 +40 -0 apache-2.0/src/lib/apr/include/apr_config.h.in
Index: apr_config.h.in
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/include/apr_config.h.in,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- apr_config.h.in 1999/09/12 12:12:00 1.7
+++ apr_config.h.in 1999/10/06 06:48:50 1.8
@@ -103,6 +103,12 @@
/* Define if you have the getpass function. */
#undef HAVE_GETPASS
+/* Define if you have the gmtime_r function. */
+#undef HAVE_GMTIME_R
+
+/* Define if you have the localtime_r function. */
+#undef HAVE_LOCALTIME_R
+
/* Define if you have the poll function. */
#undef HAVE_POLL
@@ -317,5 +323,39 @@
Sigfunc *signal(int signo, Sigfunc * func);
#endif
+#ifndef _POSIX_THREAD_SAFE_FUNCTIONS
+#define SAFETY_LOCK(func_name, cnt, name_str) \
+ { \
+ struct lock_t *funclock = lock_##func_name; \
+ if (funclock == NULL) \
+ if (ap_create_lock(cnt, APR_MUTEX, APR_LOCKALL, name_str, &funclock)
!= APR_SUCCESS) \
+ return APR_NOTTHREADSAFE; \
+ if (ap_lock(funclock) != APR_SUCCESS) \
+ return APR_NOTTHREADSAFE; \
+ }
+#else
+#define SAFETY_LOCK(func_name, cnt)
+#endif
+
+#ifndef _POSIX_THREAD_SAFE_FUNCTIONS
+#define SAFETY_UNLOCK(func_name) \
+ if (ap_unlock(lock_##func_name) != APR_SUCCESS) { \
+ return APR_NOTTHREADSAFE; \
+ }
+#else
+#define SAFETY_UNLOCK(func_name, cnt)
+#endif
+
+#ifdef HAVE_GMTIME_R
+#define GMTIME_R(x, y) gmtime_r(x, y)
+#else
+#define GMTIME_R(x, y) memcpy(y, gmtime(x), sizeof(y))
+#endif
+
+#ifdef HAVE_LOCALTIME_R
+#define LOCALTIME_R(x, y) localtime_r(x, y)
+#else
+#define LOCALTIME_R(x, y) memcpy(y, localtime(x), sizeof(y))
+#endif
#endif /* APR_CONFIG_H */
1.3 +1 -0 apache-2.0/src/lib/apr/include/apr_errno.h
Index: apr_errno.h
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/include/apr_errno.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- apr_errno.h 1999/09/04 00:21:15 1.2
+++ apr_errno.h 1999/10/06 06:48:51 1.3
@@ -396,6 +396,7 @@
#define APR_ENOSOCKET 4011
#define APR_ENOTHREAD 4012
#define APR_ENOTHDKEY 4013
+#define APR_NOTTHREADSAFE 4014
/* APR STATUS VALUES */
#define APR_INCHILD 5001
1.5 +10 -2 apache-2.0/src/lib/apr/time/unix/time.c
Index: time.c
===================================================================
RCS file: /home/cvs/apache-2.0/src/lib/apr/time/unix/time.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- time.c 1999/10/04 16:37:46 1.4
+++ time.c 1999/10/06 06:48:52 1.5
@@ -62,6 +62,10 @@
#include <errno.h>
#include <string.h>
+static ap_lock_t *lock_gmtime = NULL;
+static ap_lock_t *lock_localtime = NULL;
+
+
/* ***APRDOC********************************************************
* ap_status_t ap_make_time(ap_context_t *, ap_time_t *)
* Create a time entity.
@@ -107,11 +111,15 @@
{
switch (type) {
case APR_LOCALTIME: {
- atime->explodedtime = localtime(&atime->currtime->tv_sec);
+ SAFETY_LOCK(localtime, atime->cntxt, "localtimefile");
+ LOCALTIME_R(&atime->currtime->tv_sec, atime->explodedtime);
+ SAFETY_UNLOCK(localtime);
break;
}
case APR_UTCTIME: {
- atime->explodedtime = gmtime(&atime->currtime->tv_sec);
+ SAFETY_LOCK(gmtime, atime->cntxt, "gmtimefile");
+ GMTIME_R(&atime->currtime->tv_sec, atime->explodedtime);
+ SAFETY_UNLOCK(gmtime);
break;
}
}