2
2
3
3
#include "Python.h"
4
4
#include "pycore_fileutils.h" // _Py_BEGIN_SUPPRESS_IPH
5
+ #include "pycore_moduleobject.h" // _PyModule_GetState()
5
6
#include "pycore_namespace.h" // _PyNamespace_New()
6
7
7
8
#include <ctype.h>
64
65
static int pysleep (_PyTime_t timeout );
65
66
66
67
68
+ typedef struct {
69
+ PyTypeObject * struct_time_type ;
70
+ } time_module_state ;
71
+
72
+ static inline time_module_state *
73
+ get_time_state (PyObject * module )
74
+ {
75
+ void * state = _PyModule_GetState (module );
76
+ assert (state != NULL );
77
+ return (time_module_state * )state ;
78
+ }
79
+
80
+
67
81
static PyObject *
68
82
_PyFloat_FromPyTime (_PyTime_t t )
69
83
{
@@ -405,9 +419,6 @@ static PyStructSequence_Desc struct_time_type_desc = {
405
419
9 ,
406
420
};
407
421
408
- static int initialized ;
409
- static PyTypeObject StructTimeType ;
410
-
411
422
#if defined(MS_WINDOWS )
412
423
#ifndef CREATE_WAITABLE_TIMER_HIGH_RESOLUTION
413
424
#define CREATE_WAITABLE_TIMER_HIGH_RESOLUTION 0x00000002
@@ -417,13 +428,13 @@ static DWORD timer_flags = (DWORD)-1;
417
428
#endif
418
429
419
430
static PyObject *
420
- tmtotuple (struct tm * p
431
+ tmtotuple (time_module_state * state , struct tm * p
421
432
#ifndef HAVE_STRUCT_TM_TM_ZONE
422
433
, const char * zone , time_t gmtoff
423
434
#endif
424
435
)
425
436
{
426
- PyObject * v = PyStructSequence_New (& StructTimeType );
437
+ PyObject * v = PyStructSequence_New (state -> struct_time_type );
427
438
if (v == NULL )
428
439
return NULL ;
429
440
@@ -480,7 +491,7 @@ parse_time_t_args(PyObject *args, const char *format, time_t *pwhen)
480
491
}
481
492
482
493
static PyObject *
483
- time_gmtime (PyObject * self , PyObject * args )
494
+ time_gmtime (PyObject * module , PyObject * args )
484
495
{
485
496
time_t when ;
486
497
struct tm buf ;
@@ -491,10 +502,12 @@ time_gmtime(PyObject *self, PyObject *args)
491
502
errno = 0 ;
492
503
if (_PyTime_gmtime (when , & buf ) != 0 )
493
504
return NULL ;
505
+
506
+ time_module_state * state = get_time_state (module );
494
507
#ifdef HAVE_STRUCT_TM_TM_ZONE
495
- return tmtotuple (& buf );
508
+ return tmtotuple (state , & buf );
496
509
#else
497
- return tmtotuple (& buf , "UTC" , 0 );
510
+ return tmtotuple (state , & buf , "UTC" , 0 );
498
511
#endif
499
512
}
500
513
@@ -522,7 +535,7 @@ If the platform supports the tm_gmtoff and tm_zone, they are available as\n\
522
535
attributes only." );
523
536
524
537
static PyObject *
525
- time_localtime (PyObject * self , PyObject * args )
538
+ time_localtime (PyObject * module , PyObject * args )
526
539
{
527
540
time_t when ;
528
541
struct tm buf ;
@@ -531,16 +544,18 @@ time_localtime(PyObject *self, PyObject *args)
531
544
return NULL ;
532
545
if (_PyTime_localtime (when , & buf ) != 0 )
533
546
return NULL ;
547
+
548
+ time_module_state * state = get_time_state (module );
534
549
#ifdef HAVE_STRUCT_TM_TM_ZONE
535
- return tmtotuple (& buf );
550
+ return tmtotuple (state , & buf );
536
551
#else
537
552
{
538
553
struct tm local = buf ;
539
554
char zone [100 ];
540
555
time_t gmtoff ;
541
556
strftime (zone , sizeof (zone ), "%Z" , & buf );
542
557
gmtoff = timegm (& buf ) - when ;
543
- return tmtotuple (& local , zone , gmtoff );
558
+ return tmtotuple (state , & local , zone , gmtoff );
544
559
}
545
560
#endif
546
561
}
@@ -560,7 +575,8 @@ When 'seconds' is not passed in, convert the current time instead.");
560
575
* an exception and return 0 on error.
561
576
*/
562
577
static int
563
- gettmarg (PyObject * args , struct tm * p , const char * format )
578
+ gettmarg (time_module_state * state , PyObject * args ,
579
+ struct tm * p , const char * format )
564
580
{
565
581
int y ;
566
582
@@ -588,7 +604,7 @@ gettmarg(PyObject *args, struct tm *p, const char *format)
588
604
p -> tm_wday = (p -> tm_wday + 1 ) % 7 ;
589
605
p -> tm_yday -- ;
590
606
#ifdef HAVE_STRUCT_TM_TM_ZONE
591
- if (Py_IS_TYPE (args , & StructTimeType )) {
607
+ if (Py_IS_TYPE (args , state -> struct_time_type )) {
592
608
PyObject * item ;
593
609
item = PyStructSequence_GET_ITEM (args , 9 );
594
610
if (item != Py_None ) {
@@ -729,7 +745,7 @@ the C library strftime function.\n"
729
745
#endif
730
746
731
747
static PyObject *
732
- time_strftime (PyObject * self , PyObject * args )
748
+ time_strftime (PyObject * module , PyObject * args )
733
749
{
734
750
PyObject * tup = NULL ;
735
751
struct tm buf ;
@@ -753,12 +769,13 @@ time_strftime(PyObject *self, PyObject *args)
753
769
if (!PyArg_ParseTuple (args , "U|O:strftime" , & format_arg , & tup ))
754
770
return NULL ;
755
771
772
+ time_module_state * state = get_time_state (module );
756
773
if (tup == NULL ) {
757
774
time_t tt = time (NULL );
758
775
if (_PyTime_localtime (tt , & buf ) != 0 )
759
776
return NULL ;
760
777
}
761
- else if (!gettmarg (tup , & buf ,
778
+ else if (!gettmarg (state , tup , & buf ,
762
779
"iiiiiiiii;strftime(): illegal time tuple argument" ) ||
763
780
!checktm (& buf ))
764
781
{
@@ -941,19 +958,21 @@ _asctime(struct tm *timeptr)
941
958
}
942
959
943
960
static PyObject *
944
- time_asctime (PyObject * self , PyObject * args )
961
+ time_asctime (PyObject * module , PyObject * args )
945
962
{
946
963
PyObject * tup = NULL ;
947
964
struct tm buf ;
948
965
949
966
if (!PyArg_UnpackTuple (args , "asctime" , 0 , 1 , & tup ))
950
967
return NULL ;
968
+
969
+ time_module_state * state = get_time_state (module );
951
970
if (tup == NULL ) {
952
971
time_t tt = time (NULL );
953
972
if (_PyTime_localtime (tt , & buf ) != 0 )
954
973
return NULL ;
955
974
}
956
- else if (!gettmarg (tup , & buf ,
975
+ else if (!gettmarg (state , tup , & buf ,
957
976
"iiiiiiiii;asctime(): illegal time tuple argument" ) ||
958
977
!checktm (& buf ))
959
978
{
@@ -990,12 +1009,13 @@ not present, current time as returned by localtime() is used.");
990
1009
991
1010
#ifdef HAVE_MKTIME
992
1011
static PyObject *
993
- time_mktime (PyObject * self , PyObject * tm_tuple )
1012
+ time_mktime (PyObject * module , PyObject * tm_tuple )
994
1013
{
995
1014
struct tm tm ;
996
1015
time_t tt ;
997
1016
998
- if (!gettmarg (tm_tuple , & tm ,
1017
+ time_module_state * state = get_time_state (module );
1018
+ if (!gettmarg (state , tm_tuple , & tm ,
999
1019
"iiiiiiiii;mktime(): illegal time tuple argument" ))
1000
1020
{
1001
1021
return NULL ;
@@ -1888,6 +1908,7 @@ if it is -1, mktime() should guess based on the date and time.\n");
1888
1908
static int
1889
1909
time_exec (PyObject * module )
1890
1910
{
1911
+ time_module_state * state = get_time_state (module );
1891
1912
#if defined(__APPLE__ ) && defined(HAVE_CLOCK_GETTIME )
1892
1913
if (HAVE_CLOCK_GETTIME_RUNTIME ) {
1893
1914
/* pass: ^^^ cannot use '!' here */
@@ -2001,21 +2022,18 @@ time_exec(PyObject *module)
2001
2022
2002
2023
#endif /* defined(HAVE_CLOCK_GETTIME) || defined(HAVE_CLOCK_SETTIME) || defined(HAVE_CLOCK_GETRES) */
2003
2024
2004
- if (!initialized ) {
2005
- if (PyStructSequence_InitType2 (& StructTimeType ,
2006
- & struct_time_type_desc ) < 0 ) {
2007
- return -1 ;
2008
- }
2009
- }
2010
2025
if (PyModule_AddIntConstant (module , "_STRUCT_TM_ITEMS" , 11 )) {
2011
2026
return -1 ;
2012
2027
}
2013
- Py_INCREF (& StructTimeType );
2014
- if (PyModule_AddObject (module , "struct_time" , (PyObject * ) & StructTimeType )) {
2015
- Py_DECREF (& StructTimeType );
2028
+
2029
+ // struct_time type
2030
+ state -> struct_time_type = PyStructSequence_NewType (& struct_time_type_desc );
2031
+ if (state -> struct_time_type == NULL ) {
2032
+ return -1 ;
2033
+ }
2034
+ if (PyModule_AddType (module , state -> struct_time_type )) {
2016
2035
return -1 ;
2017
2036
}
2018
- initialized = 1 ;
2019
2037
2020
2038
#if defined(__linux__ ) && !defined(__GLIBC__ )
2021
2039
struct tm tm ;
@@ -2044,21 +2062,47 @@ time_exec(PyObject *module)
2044
2062
return 0 ;
2045
2063
}
2046
2064
2065
+
2066
+ static int
2067
+ time_module_traverse (PyObject * module , visitproc visit , void * arg )
2068
+ {
2069
+ time_module_state * state = get_time_state (module );
2070
+ Py_VISIT (state -> struct_time_type );
2071
+ return 0 ;
2072
+ }
2073
+
2074
+
2075
+ static int
2076
+ time_module_clear (PyObject * module )
2077
+ {
2078
+ time_module_state * state = get_time_state (module );
2079
+ Py_CLEAR (state -> struct_time_type );
2080
+ return 0 ;
2081
+ }
2082
+
2083
+
2084
+ static void
2085
+ time_module_free (void * module )
2086
+ {
2087
+ time_module_clear ((PyObject * )module );
2088
+ }
2089
+
2090
+
2047
2091
static struct PyModuleDef_Slot time_slots [] = {
2048
2092
{Py_mod_exec , time_exec },
2049
2093
{0 , NULL }
2050
2094
};
2051
2095
2052
2096
static struct PyModuleDef timemodule = {
2053
2097
PyModuleDef_HEAD_INIT ,
2054
- "time" ,
2055
- module_doc ,
2056
- 0 ,
2057
- time_methods ,
2058
- time_slots ,
2059
- NULL ,
2060
- NULL ,
2061
- NULL
2098
+ . m_name = "time" ,
2099
+ . m_doc = module_doc ,
2100
+ . m_size = sizeof ( time_module_state ) ,
2101
+ . m_methods = time_methods ,
2102
+ . m_slots = time_slots ,
2103
+ . m_traverse = time_module_traverse ,
2104
+ . m_clear = time_module_clear ,
2105
+ . m_free = time_module_free ,
2062
2106
};
2063
2107
2064
2108
PyMODINIT_FUNC
0 commit comments