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 new-httpd@apache.org 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; } }