diff options
author | Sascha Schumann <sas@php.net> | 1999-11-26 17:07:41 +0000 |
---|---|---|
committer | Sascha Schumann <sas@php.net> | 1999-11-26 17:07:41 +0000 |
commit | 35b30a8d0c506c861475fa5ce394900adfb2f0ed (patch) | |
tree | 262f8ec640709e73f5249b5691df06c632a48ed9 /main/reentrancy.c | |
parent | 2f6ded9ac9bb8826eb9b3b79b8cdc018c90aff54 (diff) | |
download | php-git-35b30a8d0c506c861475fa5ce394900adfb2f0ed.tar.gz |
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().
Diffstat (limited to 'main/reentrancy.c')
-rw-r--r-- | main/reentrancy.c | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/main/reentrancy.c b/main/reentrancy.c new file mode 100644 index 0000000000..a828e0f6e1 --- /dev/null +++ b/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 |