gh-81057: Move OS-Related Globals to _PyRuntimeState (gh-100082)

https://github.com/python/cpython/issues/81057
This commit is contained in:
Eric Snow 2022-12-08 15:38:06 -07:00 committed by GitHub
parent c85be734d1
commit cda9f0236f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 107 additions and 27 deletions

View File

@ -1051,6 +1051,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(node_offset)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(node_offset));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(ns)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(ns));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(nstype)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(nstype));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(nt));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(null)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(null));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(number)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(number));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(obj)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(obj));
@ -1089,6 +1090,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(pos)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(pos));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(pos1)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(pos1));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(pos2)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(pos2));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(posix));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(print_file_and_line)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(print_file_and_line));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(priority)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(priority));
_PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(progress)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(progress));

View File

@ -537,6 +537,7 @@ struct _Py_global_strings {
STRUCT_FOR_ID(node_offset) STRUCT_FOR_ID(node_offset)
STRUCT_FOR_ID(ns) STRUCT_FOR_ID(ns)
STRUCT_FOR_ID(nstype) STRUCT_FOR_ID(nstype)
STRUCT_FOR_ID(nt)
STRUCT_FOR_ID(null) STRUCT_FOR_ID(null)
STRUCT_FOR_ID(number) STRUCT_FOR_ID(number)
STRUCT_FOR_ID(obj) STRUCT_FOR_ID(obj)
@ -575,6 +576,7 @@ struct _Py_global_strings {
STRUCT_FOR_ID(pos) STRUCT_FOR_ID(pos)
STRUCT_FOR_ID(pos1) STRUCT_FOR_ID(pos1)
STRUCT_FOR_ID(pos2) STRUCT_FOR_ID(pos2)
STRUCT_FOR_ID(posix)
STRUCT_FOR_ID(print_file_and_line) STRUCT_FOR_ID(print_file_and_line)
STRUCT_FOR_ID(priority) STRUCT_FOR_ID(priority)
STRUCT_FOR_ID(progress) STRUCT_FOR_ID(progress)

View File

@ -0,0 +1,38 @@
#ifndef Py_INTERNAL_OS_H
#define Py_INTERNAL_OS_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef Py_BUILD_CORE
# error "this header requires Py_BUILD_CORE define"
#endif
#ifndef MS_WINDOWS
#define _OS_NEED_TICKS_PER_SECOND
# define need_ticks_per_second_STATE \
long ticks_per_second;
# define need_ticks_per_second_INIT \
.ticks_per_second = -1,
#else
# define need_ticks_per_second_STATE
# define need_ticks_per_second_INIT
#endif /* MS_WINDOWS */
struct _os_runtime_state {
int _not_used;
need_ticks_per_second_STATE
};
# define _OS_RUNTIME_INIT \
{ \
._not_used = 0, \
need_ticks_per_second_INIT \
}
#ifdef __cplusplus
}
#endif
#endif /* !Py_INTERNAL_OS_H */

View File

@ -21,6 +21,7 @@ extern "C" {
#include "pycore_pymem.h" // struct _pymem_allocators #include "pycore_pymem.h" // struct _pymem_allocators
#include "pycore_pyhash.h" // struct pyhash_runtime_state #include "pycore_pyhash.h" // struct pyhash_runtime_state
#include "pycore_obmalloc.h" // struct obmalloc_state #include "pycore_obmalloc.h" // struct obmalloc_state
#include "pycore_os.h" // struct _os_runtime_state
#include "pycore_unicodeobject.h" // struct _Py_unicode_runtime_ids #include "pycore_unicodeobject.h" // struct _Py_unicode_runtime_ids
struct _getargs_runtime_state { struct _getargs_runtime_state {
@ -103,6 +104,7 @@ typedef struct pyruntimestate {
* KeyboardInterrupt exception, suggesting the user pressed ^C. */ * KeyboardInterrupt exception, suggesting the user pressed ^C. */
int unhandled_keyboard_interrupt; int unhandled_keyboard_interrupt;
} signals; } signals;
struct _os_runtime_state os;
struct pyinterpreters { struct pyinterpreters {
PyThread_type_lock mutex; PyThread_type_lock mutex;

View File

@ -26,6 +26,7 @@ extern "C" {
}, \ }, \
.obmalloc = _obmalloc_state_INIT(runtime.obmalloc), \ .obmalloc = _obmalloc_state_INIT(runtime.obmalloc), \
.pyhash_state = pyhash_state_INIT, \ .pyhash_state = pyhash_state_INIT, \
.os = _OS_RUNTIME_INIT, \
.interpreters = { \ .interpreters = { \
/* This prevents interpreters from getting created \ /* This prevents interpreters from getting created \
until _PyInterpreterState_Enable() is called. */ \ until _PyInterpreterState_Enable() is called. */ \

View File

@ -1043,6 +1043,7 @@ extern "C" {
INIT_ID(node_offset), \ INIT_ID(node_offset), \
INIT_ID(ns), \ INIT_ID(ns), \
INIT_ID(nstype), \ INIT_ID(nstype), \
INIT_ID(nt), \
INIT_ID(null), \ INIT_ID(null), \
INIT_ID(number), \ INIT_ID(number), \
INIT_ID(obj), \ INIT_ID(obj), \
@ -1081,6 +1082,7 @@ extern "C" {
INIT_ID(pos), \ INIT_ID(pos), \
INIT_ID(pos1), \ INIT_ID(pos1), \
INIT_ID(pos2), \ INIT_ID(pos2), \
INIT_ID(posix), \
INIT_ID(print_file_and_line), \ INIT_ID(print_file_and_line), \
INIT_ID(priority), \ INIT_ID(priority), \
INIT_ID(progress), \ INIT_ID(progress), \

View File

@ -980,6 +980,8 @@ _PyUnicode_InitStaticStrings(void) {
PyUnicode_InternInPlace(&string); PyUnicode_InternInPlace(&string);
string = &_Py_ID(nstype); string = &_Py_ID(nstype);
PyUnicode_InternInPlace(&string); PyUnicode_InternInPlace(&string);
string = &_Py_ID(nt);
PyUnicode_InternInPlace(&string);
string = &_Py_ID(null); string = &_Py_ID(null);
PyUnicode_InternInPlace(&string); PyUnicode_InternInPlace(&string);
string = &_Py_ID(number); string = &_Py_ID(number);
@ -1056,6 +1058,8 @@ _PyUnicode_InitStaticStrings(void) {
PyUnicode_InternInPlace(&string); PyUnicode_InternInPlace(&string);
string = &_Py_ID(pos2); string = &_Py_ID(pos2);
PyUnicode_InternInPlace(&string); PyUnicode_InternInPlace(&string);
string = &_Py_ID(posix);
PyUnicode_InternInPlace(&string);
string = &_Py_ID(print_file_and_line); string = &_Py_ID(print_file_and_line);
PyUnicode_InternInPlace(&string); PyUnicode_InternInPlace(&string);
string = &_Py_ID(priority); string = &_Py_ID(priority);

View File

@ -606,12 +606,13 @@ class StatAttributeTests(unittest.TestCase):
def test_stat_result_pickle(self): def test_stat_result_pickle(self):
result = os.stat(self.fname) result = os.stat(self.fname)
for proto in range(pickle.HIGHEST_PROTOCOL + 1): for proto in range(pickle.HIGHEST_PROTOCOL + 1):
p = pickle.dumps(result, proto) with self.subTest(f'protocol {proto}'):
self.assertIn(b'stat_result', p) p = pickle.dumps(result, proto)
if proto < 4: self.assertIn(b'stat_result', p)
self.assertIn(b'cos\nstat_result\n', p) if proto < 4:
unpickled = pickle.loads(p) self.assertIn(b'cos\nstat_result\n', p)
self.assertEqual(result, unpickled) unpickled = pickle.loads(p)
self.assertEqual(result, unpickled)
@unittest.skipUnless(hasattr(os, 'statvfs'), 'test needs os.statvfs()') @unittest.skipUnless(hasattr(os, 'statvfs'), 'test needs os.statvfs()')
def test_statvfs_attributes(self): def test_statvfs_attributes(self):

View File

@ -1654,6 +1654,7 @@ PYTHON_HEADERS= \
$(srcdir)/Include/internal/pycore_object.h \ $(srcdir)/Include/internal/pycore_object.h \
$(srcdir)/Include/internal/pycore_obmalloc.h \ $(srcdir)/Include/internal/pycore_obmalloc.h \
$(srcdir)/Include/internal/pycore_obmalloc_init.h \ $(srcdir)/Include/internal/pycore_obmalloc_init.h \
$(srcdir)/Include/internal/pycore_os.h \
$(srcdir)/Include/internal/pycore_pathconfig.h \ $(srcdir)/Include/internal/pycore_pathconfig.h \
$(srcdir)/Include/internal/pycore_pyarena.h \ $(srcdir)/Include/internal/pycore_pyarena.h \
$(srcdir)/Include/internal/pycore_pyerrors.h \ $(srcdir)/Include/internal/pycore_pyerrors.h \

View File

@ -495,9 +495,11 @@ extern char *ctermid_r(char *);
#ifdef MS_WINDOWS #ifdef MS_WINDOWS
# define INITFUNC PyInit_nt # define INITFUNC PyInit_nt
# define MODNAME "nt" # define MODNAME "nt"
# define MODNAME_OBJ &_Py_ID(nt)
#else #else
# define INITFUNC PyInit_posix # define INITFUNC PyInit_posix
# define MODNAME "posix" # define MODNAME "posix"
# define MODNAME_OBJ &_Py_ID(posix)
#endif #endif
#if defined(__sun) #if defined(__sun)
@ -974,6 +976,7 @@ typedef struct {
#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) #if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)
PyObject *SchedParamType; PyObject *SchedParamType;
#endif #endif
newfunc statresult_new_orig;
PyObject *StatResultType; PyObject *StatResultType;
PyObject *StatVFSResultType; PyObject *StatVFSResultType;
PyObject *TerminalSizeType; PyObject *TerminalSizeType;
@ -2225,7 +2228,6 @@ static PyStructSequence_Desc waitid_result_desc = {
5 5
}; };
#endif #endif
static newfunc structseq_new;
static PyObject * static PyObject *
statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds) statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
@ -2233,6 +2235,18 @@ statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
PyStructSequence *result; PyStructSequence *result;
int i; int i;
// ht_module doesn't get set in PyStructSequence_NewType(),
// so we can't use PyType_GetModule().
PyObject *mod = PyImport_GetModule(MODNAME_OBJ);
if (mod == NULL) {
return NULL;
}
_posixstate *state = get_posix_state(mod);
if (state == NULL) {
return NULL;
}
#define structseq_new state->statresult_new_orig
result = (PyStructSequence*)structseq_new(type, args, kwds); result = (PyStructSequence*)structseq_new(type, args, kwds);
if (!result) if (!result)
return NULL; return NULL;
@ -9051,10 +9065,23 @@ build_times_result(PyObject *module, double user, double system,
} }
#ifndef MS_WINDOWS #ifdef _OS_NEED_TICKS_PER_SECOND
#define NEED_TICKS_PER_SECOND #define ticks_per_second _PyRuntime.os.ticks_per_second
static long ticks_per_second = -1; static void
#endif /* MS_WINDOWS */ ticks_per_second_init(void)
{
if (ticks_per_second != -1) {
return;
}
# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
ticks_per_second = sysconf(_SC_CLK_TCK);
# elif defined(HZ)
ticks_per_second = HZ;
# else
ticks_per_second = 60; /* magic fallback value; may be bogus */
# endif
}
#endif
/*[clinic input] /*[clinic input]
os.times os.times
@ -9089,10 +9116,10 @@ os_times_impl(PyObject *module)
(double)0, (double)0,
(double)0); (double)0);
} }
#elif !defined(_OS_NEED_TICKS_PER_SECOND)
# error "missing ticks_per_second"
#else /* MS_WINDOWS */ #else /* MS_WINDOWS */
{ {
struct tms t; struct tms t;
clock_t c; clock_t c;
errno = 0; errno = 0;
@ -15912,7 +15939,7 @@ posixmodule_exec(PyObject *m)
} }
PyModule_AddObject(m, "stat_result", Py_NewRef(StatResultType)); PyModule_AddObject(m, "stat_result", Py_NewRef(StatResultType));
state->StatResultType = StatResultType; state->StatResultType = StatResultType;
structseq_new = ((PyTypeObject *)StatResultType)->tp_new; state->statresult_new_orig = ((PyTypeObject *)StatResultType)->tp_new;
((PyTypeObject *)StatResultType)->tp_new = statresult_new; ((PyTypeObject *)StatResultType)->tp_new = statresult_new;
statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */ statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
@ -15922,14 +15949,9 @@ posixmodule_exec(PyObject *m)
} }
PyModule_AddObject(m, "statvfs_result", Py_NewRef(StatVFSResultType)); PyModule_AddObject(m, "statvfs_result", Py_NewRef(StatVFSResultType));
state->StatVFSResultType = StatVFSResultType; state->StatVFSResultType = StatVFSResultType;
#ifdef NEED_TICKS_PER_SECOND
# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK) #ifdef _OS_NEED_TICKS_PER_SECOND
ticks_per_second = sysconf(_SC_CLK_TCK); ticks_per_second_init();
# elif defined(HZ)
ticks_per_second = HZ;
# else
ticks_per_second = 60; /* magic fallback value; may be bogus */
# endif
#endif #endif
#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM) #if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDULER) || defined(POSIX_SPAWN_SETSCHEDPARAM)

View File

@ -236,6 +236,7 @@
<ClInclude Include="..\Include\internal\pycore_object.h" /> <ClInclude Include="..\Include\internal\pycore_object.h" />
<ClInclude Include="..\Include\internal\pycore_obmalloc.h" /> <ClInclude Include="..\Include\internal\pycore_obmalloc.h" />
<ClInclude Include="..\Include\internal\pycore_obmalloc_init.h" /> <ClInclude Include="..\Include\internal\pycore_obmalloc_init.h" />
<ClInclude Include="..\Include\internal\pycore_os.h" />
<ClInclude Include="..\Include\internal\pycore_pathconfig.h" /> <ClInclude Include="..\Include\internal\pycore_pathconfig.h" />
<ClInclude Include="..\Include\internal\pycore_pyarena.h" /> <ClInclude Include="..\Include\internal\pycore_pyarena.h" />
<ClInclude Include="..\Include\internal\pycore_pyerrors.h" /> <ClInclude Include="..\Include\internal\pycore_pyerrors.h" />

View File

@ -612,6 +612,9 @@
<ClInclude Include="..\Include\internal\pycore_obmalloc_init.h"> <ClInclude Include="..\Include\internal\pycore_obmalloc_init.h">
<Filter>Include\internal</Filter> <Filter>Include\internal</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\Include\internal\pycore_os.h">
<Filter>Include\internal</Filter>
</ClInclude>
<ClInclude Include="..\Include\internal\pycore_pathconfig.h"> <ClInclude Include="..\Include\internal\pycore_pathconfig.h">
<Filter>Include\internal</Filter> <Filter>Include\internal</Filter>
</ClInclude> </ClInclude>

View File

@ -390,9 +390,6 @@ Modules/faulthandler.c - old_stack -
##----------------------- ##-----------------------
## initialized once ## initialized once
Modules/posixmodule.c os_dup2_impl dup3_works -
Modules/posixmodule.c - structseq_new -
Modules/posixmodule.c - ticks_per_second -
Modules/timemodule.c _PyTime_GetClockWithInfo initialized - Modules/timemodule.c _PyTime_GetClockWithInfo initialized -
Modules/timemodule.c _PyTime_GetProcessTimeWithInfo ticks_per_second - Modules/timemodule.c _PyTime_GetProcessTimeWithInfo ticks_per_second -

Can't render this file because it has a wrong number of fields in line 4.

View File

@ -11,14 +11,18 @@ filename funcname name reason
# These are effectively const. # These are effectively const.
##----------------------- ##-----------------------
## process-global resources - set during first init ## process-global resources
## indicators for resource availability/capability ## indicators for resource availability/capability
# (set during first init)
Python/bootstrap_hash.c py_getrandom getrandom_works - Python/bootstrap_hash.c py_getrandom getrandom_works -
Python/fileutils.c - _Py_open_cloexec_works - Python/fileutils.c - _Py_open_cloexec_works -
Python/fileutils.c set_inheritable ioctl_works - Python/fileutils.c set_inheritable ioctl_works -
# (set lazily, *after* first init)
# XXX Is this thread-safe?
Modules/posixmodule.c os_dup2_impl dup3_works -
## resource init ## resource init - set during first init
Python/thread.c - initialized - Python/thread.c - initialized -
Python/thread_pthread.h - condattr_monotonic - Python/thread_pthread.h - condattr_monotonic -
# safe static buffer used during one-time initialization # safe static buffer used during one-time initialization

Can't render this file because it has a wrong number of fields in line 4.