summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2015-03-29 22:09:18 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2015-03-29 22:09:18 (GMT)
commit09e5cf28aef05ad07bf885c1b732eb567470199a (patch)
treee6c02fd1e758f7f6312d1651e20703565a33efb1
parent10915aa85cf264caf6e606a10f1dd204663d6d5a (diff)
downloadcpython-09e5cf28aef05ad07bf885c1b732eb567470199a.zip
cpython-09e5cf28aef05ad07bf885c1b732eb567470199a.tar.gz
cpython-09e5cf28aef05ad07bf885c1b732eb567470199a.tar.bz2
Issue #22117: Use the _PyTime_t API in _datetime.datetime() constructor
* Remove _PyTime_gettimeofday() * Add _PyTime_GetSystemClock()
-rw-r--r--Include/pytime.h20
-rw-r--r--Modules/_datetimemodule.c18
-rw-r--r--Modules/_testcapimodule.c2
-rw-r--r--Python/pytime.c119
4 files changed, 35 insertions, 124 deletions
diff --git a/Include/pytime.h b/Include/pytime.h
index 0ff009a..919ba30 100644
--- a/Include/pytime.h
+++ b/Include/pytime.h
@@ -13,15 +13,6 @@ functions and constants
extern "C" {
#endif
-#ifdef HAVE_GETTIMEOFDAY
-typedef struct timeval _PyTime_timeval;
-#else
-typedef struct {
- time_t tv_sec; /* seconds since Jan. 1, 1970 */
- long tv_usec; /* and microseconds */
-} _PyTime_timeval;
-#endif
-
/* Structure used by time.get_clock_info() */
typedef struct {
const char *implementation;
@@ -30,11 +21,6 @@ typedef struct {
double resolution;
} _Py_clock_info_t;
-/* Similar to POSIX gettimeofday but cannot fail. If system gettimeofday
- * fails or is not available, fall back to lower resolution clocks.
- */
-PyAPI_FUNC(void) _PyTime_gettimeofday(_PyTime_timeval *tp);
-
typedef enum {
/* Round towards zero. */
_PyTime_ROUND_DOWN=0,
@@ -134,6 +120,12 @@ PyAPI_FUNC(int) _PyTime_AsTimespec(_PyTime_t t, struct timespec *ts);
#endif
/* Get the current time from the system clock.
+
+ The function cannot fail. _PyTime_Init() ensures that the system clock
+ works. */
+PyAPI_FUNC(_PyTime_t) _PyTime_GetSystemClock(void);
+
+/* Get the current time from the system clock.
* Fill clock information if info is not NULL.
* Raise an exception and return -1 on error, return 0 on success.
*/
diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c
index 09285d9..c3e54f7 100644
--- a/Modules/_datetimemodule.c
+++ b/Modules/_datetimemodule.c
@@ -7,6 +7,10 @@
#include <time.h>
+#ifdef MS_WINDOWS
+# include <winsock2.h> /* struct timeval */
+#endif
+
/* Differentiate between building the core module and building extension
* modules.
*/
@@ -4093,6 +4097,8 @@ datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp,
if (_PyTime_ObjectToTimeval(timestamp, &timet, &us, _PyTime_ROUND_DOWN) == -1)
return NULL;
+ assert(0 <= us && us <= 999999);
+
return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo);
}
@@ -4103,10 +4109,14 @@ datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp,
static PyObject *
datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
{
- _PyTime_timeval t;
- _PyTime_gettimeofday(&t);
- return datetime_from_timet_and_us(cls, f, t.tv_sec, (int)t.tv_usec,
- tzinfo);
+ _PyTime_t ts = _PyTime_GetSystemClock();
+ struct timeval tv;
+
+ if (_PyTime_AsTimeval(ts, &tv, _PyTime_ROUND_FLOOR) < 0)
+ return NULL;
+ assert(0 <= tv.tv_usec && tv.tv_usec <= 999999);
+
+ return datetime_from_timet_and_us(cls, f, tv.tv_sec, tv.tv_usec, tzinfo);
}
/*[clinic input]
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index 5c54ad6..9abb7cc 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -15,7 +15,7 @@
#include <signal.h>
#ifdef MS_WINDOWS
-# include <winsock2.h>
+# include <winsock2.h> /* struct timeval */
#endif
#ifdef WITH_THREAD
diff --git a/Python/pytime.c b/Python/pytime.c
index d23d9d3..11e3a62 100644
--- a/Python/pytime.c
+++ b/Python/pytime.c
@@ -19,106 +19,6 @@
#define MS_TO_NS (MS_TO_US * US_TO_NS)
#define SEC_TO_NS (SEC_TO_MS * MS_TO_NS)
-static int
-pygettimeofday(_PyTime_timeval *tp, _Py_clock_info_t *info, int raise)
-{
-#ifdef MS_WINDOWS
- FILETIME system_time;
- ULARGE_INTEGER large;
- ULONGLONG microseconds;
-
- assert(info == NULL || raise);
-
- GetSystemTimeAsFileTime(&system_time);
- large.u.LowPart = system_time.dwLowDateTime;
- large.u.HighPart = system_time.dwHighDateTime;
- /* 11,644,473,600,000,000: number of microseconds between
- the 1st january 1601 and the 1st january 1970 (369 years + 89 leap
- days). */
- microseconds = large.QuadPart / 10 - 11644473600000000;
- tp->tv_sec = microseconds / SEC_TO_US;
- tp->tv_usec = microseconds % SEC_TO_US;
- if (info) {
- DWORD timeAdjustment, timeIncrement;
- BOOL isTimeAdjustmentDisabled, ok;
-
- info->implementation = "GetSystemTimeAsFileTime()";
- info->monotonic = 0;
- ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement,
- &isTimeAdjustmentDisabled);
- if (!ok) {
- PyErr_SetFromWindowsErr(0);
- return -1;
- }
- info->resolution = timeIncrement * 1e-7;
- info->adjustable = 1;
- }
-
-#else /* MS_WINDOWS */
- int err;
-#ifdef HAVE_CLOCK_GETTIME
- struct timespec ts;
-#endif
-
- assert(info == NULL || raise);
-
-#ifdef HAVE_CLOCK_GETTIME
- err = clock_gettime(CLOCK_REALTIME, &ts);
- if (err) {
- if (raise)
- PyErr_SetFromErrno(PyExc_OSError);
- return -1;
- }
- tp->tv_sec = ts.tv_sec;
- tp->tv_usec = ts.tv_nsec / US_TO_NS;
-
- if (info) {
- struct timespec res;
- info->implementation = "clock_gettime(CLOCK_REALTIME)";
- info->monotonic = 0;
- info->adjustable = 1;
- if (clock_getres(CLOCK_REALTIME, &res) == 0)
- info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
- else
- info->resolution = 1e-9;
- }
-#else /* HAVE_CLOCK_GETTIME */
-
- /* test gettimeofday() */
-#ifdef GETTIMEOFDAY_NO_TZ
- err = gettimeofday(tp);
-#else
- err = gettimeofday(tp, (struct timezone *)NULL);
-#endif
- if (err) {
- if (raise)
- PyErr_SetFromErrno(PyExc_OSError);
- return -1;
- }
-
- if (info) {
- info->implementation = "gettimeofday()";
- info->resolution = 1e-6;
- info->monotonic = 0;
- info->adjustable = 1;
- }
-#endif /* !HAVE_CLOCK_GETTIME */
-#endif /* !MS_WINDOWS */
- assert(0 <= tp->tv_usec && tp->tv_usec < SEC_TO_US);
- return 0;
-}
-
-void
-_PyTime_gettimeofday(_PyTime_timeval *tp)
-{
- if (pygettimeofday(tp, NULL, 0) < 0) {
- /* cannot happen, _PyTime_Init() checks that pygettimeofday() works */
- assert(0);
- tp->tv_sec = 0;
- tp->tv_usec = 0;
- }
-}
-
static void
error_time_t_overflow(void)
{
@@ -577,6 +477,20 @@ pygettimeofday_new(_PyTime_t *tp, _Py_clock_info_t *info, int raise)
return 0;
}
+_PyTime_t
+_PyTime_GetSystemClock(void)
+{
+ _PyTime_t t;
+ if (pygettimeofday_new(&t, NULL, 0) < 0) {
+ /* should not happen, _PyTime_Init() checked the clock at startup */
+ assert(0);
+
+ /* use a fixed value instead of a random value from the stack */
+ t = 0;
+ }
+ return t;
+}
+
int
_PyTime_GetSystemClockWithInfo(_PyTime_t *t, _Py_clock_info_t *info)
{
@@ -715,14 +629,9 @@ _PyTime_GetMonotonicClockWithInfo(_PyTime_t *tp, _Py_clock_info_t *info)
int
_PyTime_Init(void)
{
- _PyTime_timeval tv;
_PyTime_t t;
/* ensure that the system clock works */
- if (pygettimeofday(&tv, NULL, 1) < 0)
- return -1;
-
- /* ensure that the system clock works */
if (_PyTime_GetSystemClockWithInfo(&t, NULL) < 0)
return -1;