Skip to content

Refactor basic time usages #19202

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions Zend/Optimizer/zend_func_infos.h
Original file line number Diff line number Diff line change
Expand Up @@ -559,10 +559,8 @@ static const func_info_t func_infos[] = {
F1("dechex", MAY_BE_STRING),
F1("base_convert", MAY_BE_STRING),
F1("number_format", MAY_BE_STRING),
#if defined(HAVE_GETTIMEOFDAY)
F1("microtime", MAY_BE_STRING|MAY_BE_DOUBLE),
F1("gettimeofday", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_DOUBLE),
#endif
#if defined(HAVE_GETRUSAGE)
F1("getrusage", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_FALSE),
#endif
Expand Down Expand Up @@ -597,9 +595,7 @@ static const func_info_t func_infos[] = {
F1("stream_resolve_include_path", MAY_BE_STRING|MAY_BE_FALSE),
F1("stream_get_wrappers", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING),
F1("stream_get_transports", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_OF_STRING),
#if defined(HAVE_GETTIMEOFDAY)
F1("uniqid", MAY_BE_STRING),
#endif
F1("parse_url", MAY_BE_LONG|MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_NULL|MAY_BE_FALSE),
F1("urlencode", MAY_BE_STRING),
F1("urldecode", MAY_BE_STRING),
Expand Down
78 changes: 78 additions & 0 deletions Zend/zend_time.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
+----------------------------------------------------------------------+
| Copyright (c) The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| https://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| [email protected] so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Marc Bennewitz <[email protected]> |
+----------------------------------------------------------------------+
*/

#include "zend_time.h"

ZEND_API time_t zend_realtime_get(time_t *sec, long *nsec) {
if (!nsec) {
return time(sec);
}

#if defined(HAVE_CLOCK_GETTIME)

struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
if (sec) *sec = ts.tv_sec;
*nsec = ts.tv_nsec;
return ts.tv_sec;

#elif defined(HAVE_TIMESPEC_GET)

struct timespec ts;
timespec_get(&ts, TIME_UTC);
if (sec) *sec = ts.tv_sec;
*nsec = ts.tv_nsec;
return ts.tv_sec;

#elif defined(HAVE_GETTIMEOFDAY)

struct timeval tv;
gettimeofday(&tv, NULL);

if (sec) *sec = tv.tv_sec;
*nsec = tv.tv_usec * 1000;
return tv.tv_sec;

#else

*nsec = 0;
return time(sec);

#endif
}

ZEND_API void zend_realtime_spec(struct timespec *ts) {
#if defined(HAVE_CLOCK_GETTIME)

clock_gettime(CLOCK_REALTIME, ts);

#elif defined(HAVE_TIMESPEC_GET)

timespec_get(ts, TIME_UTC);

#elif defined(HAVE_GETTIMEOFDAY)

struct timeval tv;
gettimeofday(&tv, NULL);
zend_time_val2spec(tv, ts);

#else

ts->tv_sec = time(NULL);
ts->tv_nsec = 0;

#endif
}
95 changes: 95 additions & 0 deletions Zend/zend_time.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
+----------------------------------------------------------------------+
| Copyright (c) The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| https://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| [email protected] so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Marc Bennewitz <[email protected]> |
+----------------------------------------------------------------------+
*/

#ifndef ZEND_TIME_H
#define ZEND_TIME_H

#include "zend_portability.h"

#ifdef PHP_WIN32
# include "win32/time.h"
#endif
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#include <time.h>

#include "zend_hrtime.h"

#define ZEND_MILLI_IN_SEC 1000U
#define ZEND_MICRO_IN_SEC 1000000U

#ifndef PHP_WIN32

/* Helper macro to assign seconds to timeval */
# define zend_time_sec2val(s, tv) \
(tv).tv_sec = (time_t) (s); \
(tv).tv_usec = 0;

/* Helper macro to assign microseconds to timeval */
# define zend_time_usec2val(usec, tv) \
(tv).tv_sec = (time_t) ((usec) / ZEND_MICRO_IN_SEC); \
(tv).tv_usec = (suseconds_t) ((usec) % ZEND_MICRO_IN_SEC);

/* Helper macro to assign double (seconds) to timeval */
# define zend_time_dbl2val(d, tv) \
(tv).tv_sec = (time_t) (d); \
(tv).tv_usec = (suseconds_t) (((d) - (tv).tv_sec) * ZEND_MICRO_IN_SEC);

#else

# define zend_time_sec2val(s, tv) \
(tv).tv_sec = (long) (s); \
(tv).tv_usec = 0;

# define zend_time_usec2val(usec, tv) \
(tv).tv_sec = (long) ((usec) / ZEND_MICRO_IN_SEC); \
(tv).tv_usec = (long) ((usec) % ZEND_MICRO_IN_SEC);

# define zend_time_dbl2val(d, tv) \
(tv).tv_sec = (long) (d); \
(tv).tv_usec = (long) (((d) - (tv).tv_sec) * ZEND_MICRO_IN_SEC);

#endif

/* Helper macro to copy timeval to timespec */
#define zend_time_val2spec(tv, ts) \
(ts).tv_sec = (time_t) (tv).tv_sec; \
(ts).tv_nsec = (long) ((tv).tv_usec * 1000);

BEGIN_EXTERN_C()

/* Like time() but with up to nanosecond */
ZEND_API time_t zend_realtime_get(time_t *sec, long *nsec);

/* wrapper around clock_gettime/timestamp_get/gettimeofday/time */
ZEND_API void zend_realtime_spec(struct timespec *ts);

/* Monotonic time in nanoseconds with a fallback to real/wall-time
if no monotonic timer is available */
#if ZEND_HRTIME_AVAILABLE
# define zend_monotime_fallback() (uint64_t)zend_hrtime()
#else
ZEND_API zend_always_inline uint64_t zend_monotime_fallback(void) {
struct timespec ts;
zend_realtime_spec(&ts);
return ((uint64_t) ts.tv_sec * ZEND_NANO_IN_SEC) + ts.tv_nsec;
}
#endif

END_EXTERN_C()

#endif // ZEND_TIME_H
5 changes: 5 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,8 @@ AC_CHECK_FUNCS(m4_normalize([
asctime_r
asprintf
chroot
clock_gettime
clock_getres
ctime_r
explicit_memset
fdatasync
Expand Down Expand Up @@ -580,6 +582,8 @@ AC_CHECK_FUNCS(m4_normalize([
strptime
strtok_r
symlink
timespec_get
timespec_getres
tzset
unsetenv
usleep
Expand Down Expand Up @@ -1748,6 +1752,7 @@ PHP_ADD_SOURCES([Zend], m4_normalize([
zend_generators.c
zend_hash.c
zend_highlight.c
zend_time.c
zend_hrtime.c
zend_inheritance.c
zend_ini_parser.c
Expand Down
2 changes: 1 addition & 1 deletion docs-old/streams.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ PHPAPI php_stream *php_stream_sock_open_from_socket(int socket, int persistent);
/* Convert a socket into a stream. */

PHPAPI php_stream *php_stream_sock_open_host(const char *host, unsigned short port,
int socktype, int timeout, int persistent);
int socktype, struct timeval *timeout, const char *persistent_id);
/* Open a connection to a host and return a stream. */

PHPAPI php_stream *php_stream_sock_open_unix(const char *path, int persistent,
Expand Down
30 changes: 4 additions & 26 deletions ext/date/php_date.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,9 @@
#include "zend_attributes.h"
#include "zend_interfaces.h"
#include "zend_exceptions.h"
#include "zend_time.h"
#include "lib/timelib.h"
#include "lib/timelib_private.h"
#ifndef PHP_WIN32
#include <time.h>
#else
#include "win32/time.h"
#endif

#ifdef PHP_WIN32
static __inline __int64 php_date_llabs( __int64 i ) { return i >= 0? i: -i; }
Expand All @@ -55,18 +51,7 @@ static inline long long php_date_llabs( long long i ) { return i >= 0 ? i : -i;

PHPAPI time_t php_time(void)
{
#ifdef HAVE_GETTIMEOFDAY
struct timeval tm;

if (UNEXPECTED(gettimeofday(&tm, NULL) != SUCCESS)) {
/* fallback, can't reasonably happen */
return time(NULL);
}

return tm.tv_sec;
#else
return time(NULL);
#endif
}

/*
Expand Down Expand Up @@ -2353,16 +2338,9 @@ static void php_date_set_time_fraction(timelib_time *time, int microsecond)

static void php_date_get_current_time_with_fraction(time_t *sec, suseconds_t *usec)
{
#ifdef HAVE_GETTIMEOFDAY
struct timeval tp = {0}; /* For setting microsecond */

gettimeofday(&tp, NULL);
*sec = tp.tv_sec;
*usec = tp.tv_usec;
#else
*sec = time(NULL);
*usec = 0;
#endif
long nsec;
zend_realtime_get(sec, &nsec);
*usec = nsec / 1000;
}

PHPAPI bool php_date_initialize(php_date_obj *dateobj, const char *time_str, size_t time_str_len, const char *format, zval *timezone_object, int flags) /* {{{ */
Expand Down
9 changes: 2 additions & 7 deletions ext/ftp/ftp.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#endif

#include "php.h"
#include "zend_time.h"

#include <stdio.h>
#include <ctype.h>
Expand All @@ -29,7 +30,6 @@
#endif
#include <fcntl.h>
#include <string.h>
#include <time.h>
#ifdef PHP_WIN32
#include <winsock2.h>
#else
Expand All @@ -43,10 +43,6 @@
#endif
#include <errno.h>

#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif

#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
Expand Down Expand Up @@ -1608,8 +1604,7 @@ static databuf_t* ftp_getdata(ftpbuf_t *ftp)
/* connect */
/* Win 95/98 seems not to like size > sizeof(sockaddr_in) */
size = php_sockaddr_size(&ftp->pasvaddr);
tv.tv_sec = ftp->timeout_sec;
tv.tv_usec = 0;
zend_time_sec2val(ftp->timeout_sec, tv);
if (php_connect_nonb(fd, (struct sockaddr*) &ftp->pasvaddr, size, &tv) == -1) {
php_error_docref(NULL, E_WARNING, "php_connect_nonb() failed: %s (%d)", strerror(errno), errno);
goto bail;
Expand Down
Loading