Skip to content

Commit

Permalink
Merge branch 'main' into pythongh-99442
Browse files Browse the repository at this point in the history
  • Loading branch information
zooba authored Nov 17, 2022
2 parents e0128ba + 5fdd49d commit 7ecea78
Show file tree
Hide file tree
Showing 44 changed files with 785 additions and 788 deletions.
13 changes: 0 additions & 13 deletions Doc/c-api/init.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1239,25 +1239,12 @@ All of the following functions must be called after :c:func:`Py_Initialize`.
The global interpreter lock need not be held, but may be held if it is
necessary to serialize calls to this function.
.. audit-event:: cpython.PyThreadState_New id c.PyThreadState_New
Raise an auditing event ``cpython.PyThreadState_New`` with Python's thread
id as the argument. The event will be raised from the thread creating the new
``PyThreadState``, which may not be the new thread.
.. c:function:: void PyThreadState_Clear(PyThreadState *tstate)
Reset all information in a thread state object. The global interpreter lock
must be held.
.. audit-event:: cpython.PyThreadState_Clear id c.PyThreadState_Clear
Raise an auditing event ``cpython.PyThreadState_Clear`` with Python's
thread id as the argument. The event may be raised from a different thread
than the one being cleared. Exceptions raised from a hook will be treated
as unraisable and will not abort the operation.
.. versionchanged:: 3.9
This function now calls the :c:member:`PyThreadState.on_delete` callback.
Previously, that happened in :c:func:`PyThreadState_Delete`.
Expand Down
28 changes: 5 additions & 23 deletions Include/internal/pycore_dict.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif

#include "pycore_dict_state.h"
#include "pycore_runtime.h" // _PyRuntime


/* runtime lifecycle */

Expand All @@ -17,25 +20,6 @@ extern void _PyDict_Fini(PyInterpreterState *interp);

/* other API */

#ifndef WITH_FREELISTS
// without freelists
# define PyDict_MAXFREELIST 0
#endif

#ifndef PyDict_MAXFREELIST
# define PyDict_MAXFREELIST 80
#endif

struct _Py_dict_state {
#if PyDict_MAXFREELIST > 0
/* Dictionary reuse scheme to save calls to malloc and free */
PyDictObject *free_list[PyDict_MAXFREELIST];
int numfree;
PyDictKeysObject *keys_free_list[PyDict_MAXFREELIST];
int keys_numfree;
#endif
};

typedef struct {
/* Cached hash code of me_key. */
Py_hash_t me_hash;
Expand Down Expand Up @@ -152,13 +136,11 @@ struct _dictvalues {
(PyDictUnicodeEntry*)(&((int8_t*)((dk)->dk_indices))[(size_t)1 << (dk)->dk_log2_index_bytes]))
#define DK_IS_UNICODE(dk) ((dk)->dk_kind != DICT_KEYS_GENERAL)

extern uint64_t _pydict_global_version;

#define DICT_MAX_WATCHERS 8
#define DICT_VERSION_INCREMENT (1 << DICT_MAX_WATCHERS)
#define DICT_VERSION_MASK (DICT_VERSION_INCREMENT - 1)

#define DICT_NEXT_VERSION() (_pydict_global_version += DICT_VERSION_INCREMENT)
#define DICT_NEXT_VERSION() \
(_PyRuntime.dict_state.global_version += DICT_VERSION_INCREMENT)

void
_PyDict_SendEvent(int watcher_bits,
Expand Down
47 changes: 47 additions & 0 deletions Include/internal/pycore_dict_state.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#ifndef Py_INTERNAL_DICT_STATE_H
#define Py_INTERNAL_DICT_STATE_H
#ifdef __cplusplus
extern "C" {
#endif

#ifndef Py_BUILD_CORE
# error "this header requires Py_BUILD_CORE define"
#endif


struct _Py_dict_runtime_state {
/*Global counter used to set ma_version_tag field of dictionary.
* It is incremented each time that a dictionary is created and each
* time that a dictionary is modified. */
uint64_t global_version;
uint32_t next_keys_version;
};


#ifndef WITH_FREELISTS
// without freelists
# define PyDict_MAXFREELIST 0
#endif

#ifndef PyDict_MAXFREELIST
# define PyDict_MAXFREELIST 80
#endif

#define DICT_MAX_WATCHERS 8

struct _Py_dict_state {
#if PyDict_MAXFREELIST > 0
/* Dictionary reuse scheme to save calls to malloc and free */
PyDictObject *free_list[PyDict_MAXFREELIST];
PyDictKeysObject *keys_free_list[PyDict_MAXFREELIST];
int numfree;
int keys_numfree;
#endif
PyDict_WatchCallback watchers[DICT_MAX_WATCHERS];
};


#ifdef __cplusplus
}
#endif
#endif /* !Py_INTERNAL_DICT_STATE_H */
4 changes: 4 additions & 0 deletions Include/internal/pycore_function.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ extern "C" {
# error "this header requires Py_BUILD_CORE define"
#endif

struct _py_func_runtime_state {
uint32_t next_version;
};

extern PyFunctionObject* _PyFunction_FromConstructor(PyFrameConstructor *constr);

extern uint32_t _PyFunction_GetVersionForCurrentState(PyFunctionObject *func);
Expand Down
4 changes: 1 addition & 3 deletions Include/internal/pycore_interp.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ extern "C" {
#include "pycore_ast_state.h" // struct ast_state
#include "pycore_code.h" // struct callable_cache
#include "pycore_context.h" // struct _Py_context_state
#include "pycore_dict.h" // struct _Py_dict_state
#include "pycore_dict_state.h" // struct _Py_dict_state
#include "pycore_exceptions.h" // struct _Py_exc_state
#include "pycore_floatobject.h" // struct _Py_float_state
#include "pycore_genobject.h" // struct _Py_async_gen_state
Expand Down Expand Up @@ -171,8 +171,6 @@ struct _is {
// Initialized to _PyEval_EvalFrameDefault().
_PyFrameEvalFunction eval_frame;

PyDict_WatchCallback dict_watchers[DICT_MAX_WATCHERS];

Py_ssize_t co_extra_user_count;
freefunc co_extra_freefuncs[MAX_CO_EXTRA_USERS];

Expand Down
4 changes: 4 additions & 0 deletions Include/internal/pycore_runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ extern "C" {
#endif

#include "pycore_atomic.h" /* _Py_atomic_address */
#include "pycore_dict_state.h" // struct _Py_dict_runtime_state
#include "pycore_dtoa.h" // struct _dtoa_runtime_state
#include "pycore_floatobject.h" // struct _Py_float_runtime_state
#include "pycore_function.h" // struct _func_runtime_state
#include "pycore_gil.h" // struct _gil_runtime_state
#include "pycore_global_objects.h" // struct _Py_global_objects
#include "pycore_import.h" // struct _import_runtime_state
Expand Down Expand Up @@ -151,6 +153,8 @@ typedef struct pyruntimestate {

struct _Py_float_runtime_state float_state;
struct _Py_unicode_runtime_state unicode_state;
struct _Py_dict_runtime_state dict_state;
struct _py_func_runtime_state func_state;

struct {
/* Used to set PyTypeObject.tp_version_tag */
Expand Down
6 changes: 6 additions & 0 deletions Include/internal/pycore_runtime_init.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ extern "C" {
.float_format = _py_float_format_unknown, \
.double_format = _py_float_format_unknown, \
}, \
.dict_state = { \
.next_keys_version = 2, \
}, \
.func_state = { \
.next_version = 1, \
}, \
.types = { \
.next_version_tag = 1, \
}, \
Expand Down
8 changes: 0 additions & 8 deletions Lib/test/test_audit.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,19 +197,11 @@ def test_threading(self):
actual = [(ev[0], ev[2]) for ev in events]
expected = [
("_thread.start_new_thread", "(<test_func>, (), None)"),
("cpython.PyThreadState_New", "(2,)"),
("test.test_func", "()"),
("cpython.PyThreadState_Clear", "(2,)"),
]

self.assertEqual(actual, expected)

def test_threading_abort(self):
# Ensures that aborting PyThreadState_New raises the correct exception
returncode, events, stderr = self.run_python("test_threading_abort")
if returncode:
self.fail(stderr)


def test_wmi_exec_query(self):
import_helper.import_module("_wmi")
Expand Down
Loading

0 comments on commit 7ecea78

Please sign in to comment.