Browse Source
Add reentrant versions of ctime, localtime, gmtime, asctime.
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
7 changed files with 188 additions and 1 deletions
-
2Makefile.am
-
4configure.in
-
1main/php.h
-
2main/php_globals.h
-
53main/php_reentrancy.h
-
124main/reentrancy.c
-
3sapi/aolserver/aolserver.c
@ -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 |
|||
@ -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 |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue