Browse Source

Add reentrant versions of ctime, localtime, gmtime, asctime.

These cannot be implemented platform-independent, so we fall back to the native
non-reentrant versions, but lock during each access (only if ZTS is used).

To initialize/destroy the used data structures, you need to call
reentrancy_startup() before sapi_startup(), and reentrancy_shutdown() after
sapi_shutdown().
experimetnal/RETURN_REF_PATCH
Sascha Schumann 26 years ago
parent
commit
35b30a8d0c
  1. 2
      Makefile.am
  2. 4
      configure.in
  3. 1
      main/php.h
  4. 2
      main/php_globals.h
  5. 53
      main/php_reentrancy.h
  6. 124
      main/reentrancy.c
  7. 3
      sapi/aolserver/aolserver.c

2
Makefile.am

@ -11,7 +11,7 @@ libphp4_la_SOURCES = \
configuration-parser.y configuration-scanner.l request_info.c \
safe_mode.c fopen-wrappers.c php3_realpath.c alloca.c \
php_ini.c SAPI.c rfc1867.c dlist.c php_content_types.c strlcpy.c \
strlcat.c mergesort.c
strlcat.c mergesort.c strtok_r.c reentrancy.c
libphp4_la_DEPENDENCIES = \
libzend/libzend.la \

4
configure.in

@ -292,15 +292,19 @@ AC_CHECK_TYPE( ulong, unsigned long )
dnl Checks for library functions.
AC_FUNC_VPRINTF
AC_CHECK_FUNCS(
asctime_r \
crypt \
ctime_r \
cuserid \
flock \
gcvt \
getlogin \
gethostbyaddr \
gettimeofday \
gmtime_r \
inet_aton \
link \
localtime_r \
lockf \
lrand48 \
memcpy \

1
main/php.h

@ -343,6 +343,7 @@ PHPAPI int cfg_get_string(char *varname, char **result);
#define PHP_CONNECTION_ABORTED 1
#define PHP_CONNECTION_TIMEOUT 2
#include "php_reentrancy.h"
/* Finding offsets of elements within structures.
* Taken from the Apache code, which in turn, was taken from X code...

2
main/php_globals.h

@ -72,6 +72,8 @@ struct _php_core_globals {
char *upload_tmp_dir;
long upload_max_filesize;
char *current_dir;
char *auto_prepend_file;
char *auto_append_file;

53
main/php_reentrancy.h

@ -0,0 +1,53 @@
#ifndef PHP_REENTRANCY_H
#define PHP_REENTRANCY_H
#include "php_config.h"
#include <time.h>
/* currently, PHP does not check for these functions, but assumes
that they are available on all systems. */
#define HAVE_LOCALTIME 1
#define HAVE_GMTIME 1
#define HAVE_ASCTIME 1
#define HAVE_CTIME 1
#if !defined(HAVE_LOCALTIME_R) && defined(HAVE_LOCALTIME)
#define PHP_NEED_REENTRANCY 1
#define localtime_r php_localtime_r
struct tm *localtime_r(const time_t *const timep, struct tm *p_tm);
#endif
#if !defined(HAVE_CTIME_R) && defined(HAVE_CTIME)
#define PHP_NEED_REENTRANCY 1
#define ctime_r php_ctime_r
char *ctime_r(const time_t *clock, char *buf);
#endif
#if !defined(HAVE_ASCTIME_R) && defined(HAVE_ASCTIME)
#define PHP_NEED_REENTRANCY 1
#define asctime_r php_asctime_r
char *asctime_r(const struct tm *tm, char *buf);
#endif
#if !defined(HAVE_GMTIME_R) && defined(HAVE_GMTIME)
#define PHP_NEED_REENTRANCY 1
#define gmtime_r php_gmtime_r
struct tm *gmtime_r(const time_t *const timep, struct tm *p_tm);
#endif
#if defined(ZTS) && defined(PHP_NEED_REENTRANCY)
void reentrancy_startup(void);
void reentrancy_shutdown(void);
#else
#define reentrancy_startup()
#define reentrancy_shutdown()
#endif
#endif

124
main/reentrancy.c

@ -0,0 +1,124 @@
#include "php_reentrancy.h"
#include <string.h>
enum {
LOCALTIME_R,
CTIME_R,
ASCTIME_R,
GMTIME_R,
NUMBER_OF_LOCKS
};
#if defined(ZTS)
#include <TSRM.h>
static MUTEX_T reentrant_locks[NUMBER_OF_LOCKS];
#define local_lock(x) tsrm_mutex_lock(reentrant_locks[x])
#define local_unlock(x) tsrm_mutex_unlock(reentrant_locks[x])
#else
#define local_lock(x)
#define local_unlock(x)
#endif
#if !defined(HAVE_LOCALTIME_R) && defined(HAVE_LOCALTIME)
struct tm *localtime_r(const time_t *const timep, struct tm *p_tm)
{
struct tm *tmp;
local_lock(LOCALTIME_R);
tmp = localtime(timep);
memcpy(p_tm, tmp, sizeof(struct tm));
local_unlock(LOCALTIME_R);
return p_tm;
}
#endif
#if !defined(HAVE_CTIME_R) && defined(HAVE_CTIME)
char *ctime_r(const time_t *clock, char *buf)
{
char *tmp;
local_lock(CTIME_R);
tmp = ctime(clock);
strcpy(buf, tmp);
local_unlock(CTIME_R);
return buf;
}
#endif
#if !defined(HAVE_ASCTIME_R) && defined(HAVE_ASCTIME)
char *asctime_r(const struct tm *tm, char *buf)
{
char *tmp;
local_lock(ASCTIME_R);
tmp = asctime(tm);
strcpy(buf, tmp);
local_unlock(ASCTIME_R);
return buf;
}
#endif
#if !defined(HAVE_GMTIME_R) && defined(HAVE_GMTIME)
struct tm *gmtime_r(const time_t *const timep, struct tm *p_tm)
{
struct tm *tmp;
local_lock(GMTIME_R);
tmp = gmtime(timep);
memcpy(p_tm, tmp, sizeof(struct tm));
local_unlock(GMTIME_R);
return p_tm;
}
#endif
#if defined(PHP_NEED_REENTRANCY) && defined(ZTS)
void reentrancy_shutdown(void)
{
int i;
for (i = 0; i < NUMBER_OF_LOCKS; i++) {
tsrm_mutex_init(reentrant_locks[i]);
}
}
void reentrancy_shutdown(void)
{
int i;
for (i = 0; i < NUMBER_OF_LOCKS; i++) {
tsrm_mutex_destroy(reentrant_locks[i]);
}
}
#endif

3
sapi/aolserver/aolserver.c

@ -288,6 +288,7 @@ static sapi_module_struct sapi_module = {
* with a number of variables. HTTP_* variables are created for
* the HTTP header data, so that a script can access these.
*/
#define ADD_STRING(name) \
MAKE_STD_ZVAL(pval); \
pval->type = IS_STRING; \
@ -541,6 +542,7 @@ php_ns_server_shutdown(void *context)
ctx->sapi_module->shutdown(ctx->sapi_module);
sapi_shutdown();
reentrancy_shutdown();
tsrm_shutdown();
free(ctx->ns_module);
@ -560,6 +562,7 @@ int Ns_ModuleInit(char *server, char *module)
php_ns_context *ctx;
tsrm_startup(1, 1, 0);
reentrancy_startup();
sapi_startup(&sapi_module);
sapi_module.startup(&sapi_module);

Loading…
Cancel
Save