summaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/Python/context.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/tools/python3/Python/context.c')
-rw-r--r--contrib/tools/python3/Python/context.c113
1 files changed, 49 insertions, 64 deletions
diff --git a/contrib/tools/python3/Python/context.c b/contrib/tools/python3/Python/context.c
index 7bccfad11a4..1b2797b8af5 100644
--- a/contrib/tools/python3/Python/context.c
+++ b/contrib/tools/python3/Python/context.c
@@ -7,7 +7,7 @@
#include "pycore_object.h"
#include "pycore_pyerrors.h"
#include "pycore_pystate.h" // _PyThreadState_GET()
-#include "structmember.h" // PyMemberDef
+
#include "clinic/context.c.h"
@@ -64,12 +64,12 @@ static int
contextvar_del(PyContextVar *var);
-#if PyContext_MAXFREELIST > 0
-static struct _Py_context_state *
-get_context_state(void)
+#ifdef WITH_FREELISTS
+static struct _Py_context_freelist *
+get_context_freelist(void)
{
- PyInterpreterState *interp = _PyInterpreterState_GET();
- return &interp->context;
+ struct _Py_object_freelists *freelists = _Py_object_freelists_GET();
+ return &freelists->contexts;
}
#endif
@@ -203,6 +203,7 @@ PyContextVar_Get(PyObject *ovar, PyObject *def, PyObject **val)
goto not_found;
}
+#ifndef Py_GIL_DISABLED
if (var->var_cached != NULL &&
var->var_cached_tsid == ts->id &&
var->var_cached_tsver == ts->context_ver)
@@ -210,6 +211,7 @@ PyContextVar_Get(PyObject *ovar, PyObject *def, PyObject **val)
*val = var->var_cached;
goto found;
}
+#endif
assert(PyContext_CheckExact(ts->context));
PyHamtObject *vars = ((PyContext *)ts->context)->ctx_vars;
@@ -221,9 +223,11 @@ PyContextVar_Get(PyObject *ovar, PyObject *def, PyObject **val)
}
if (res == 1) {
assert(found != NULL);
+#ifndef Py_GIL_DISABLED
var->var_cached = found; /* borrow */
var->var_cached_tsid = ts->id;
var->var_cached_tsver = ts->context_ver;
+#endif
*val = found;
goto found;
@@ -260,12 +264,6 @@ PyContextVar_Set(PyObject *ovar, PyObject *val)
ENSURE_ContextVar(ovar, NULL)
PyContextVar *var = (PyContextVar *)ovar;
- if (!PyContextVar_CheckExact(var)) {
- PyErr_SetString(
- PyExc_TypeError, "an instance of ContextVar was expected");
- return NULL;
- }
-
PyContext *ctx = context_get();
if (ctx == NULL) {
return NULL;
@@ -340,16 +338,12 @@ static inline PyContext *
_context_alloc(void)
{
PyContext *ctx;
-#if PyContext_MAXFREELIST > 0
- struct _Py_context_state *state = get_context_state();
-#ifdef Py_DEBUG
- // _context_alloc() must not be called after _PyContext_Fini()
- assert(state->numfree != -1);
-#endif
- if (state->numfree) {
- state->numfree--;
- ctx = state->freelist;
- state->freelist = (PyContext *)ctx->ctx_weakreflist;
+#ifdef WITH_FREELISTS
+ struct _Py_context_freelist *context_freelist = get_context_freelist();
+ if (context_freelist->numfree > 0) {
+ context_freelist->numfree--;
+ ctx = context_freelist->items;
+ context_freelist->items = (PyContext *)ctx->ctx_weakreflist;
OBJECT_STAT_INC(from_freelist);
ctx->ctx_weakreflist = NULL;
_Py_NewReference((PyObject *)ctx);
@@ -471,16 +465,12 @@ context_tp_dealloc(PyContext *self)
}
(void)context_tp_clear(self);
-#if PyContext_MAXFREELIST > 0
- struct _Py_context_state *state = get_context_state();
-#ifdef Py_DEBUG
- // _context_alloc() must not be called after _PyContext_Fini()
- assert(state->numfree != -1);
-#endif
- if (state->numfree < PyContext_MAXFREELIST) {
- state->numfree++;
- self->ctx_weakreflist = (PyObject *)state->freelist;
- state->freelist = self;
+#ifdef WITH_FREELISTS
+ struct _Py_context_freelist *context_freelist = get_context_freelist();
+ if (context_freelist->numfree >= 0 && context_freelist->numfree < PyContext_MAXFREELIST) {
+ context_freelist->numfree++;
+ self->ctx_weakreflist = (PyObject *)context_freelist->items;
+ context_freelist->items = self;
OBJECT_STAT_INC(to_freelist);
}
else
@@ -731,8 +721,10 @@ PyTypeObject PyContext_Type = {
static int
contextvar_set(PyContextVar *var, PyObject *val)
{
+#ifndef Py_GIL_DISABLED
var->var_cached = NULL;
PyThreadState *ts = _PyThreadState_GET();
+#endif
PyContext *ctx = context_get();
if (ctx == NULL) {
@@ -747,16 +739,20 @@ contextvar_set(PyContextVar *var, PyObject *val)
Py_SETREF(ctx->ctx_vars, new_vars);
+#ifndef Py_GIL_DISABLED
var->var_cached = val; /* borrow */
var->var_cached_tsid = ts->id;
var->var_cached_tsver = ts->context_ver;
+#endif
return 0;
}
static int
contextvar_del(PyContextVar *var)
{
+#ifndef Py_GIL_DISABLED
var->var_cached = NULL;
+#endif
PyContext *ctx = context_get();
if (ctx == NULL) {
@@ -821,19 +817,20 @@ contextvar_new(PyObject *name, PyObject *def)
return NULL;
}
- var->var_hash = contextvar_generate_hash(var, name);
- if (var->var_hash == -1) {
- Py_DECREF(var);
- return NULL;
- }
-
var->var_name = Py_NewRef(name);
-
var->var_default = Py_XNewRef(def);
+#ifndef Py_GIL_DISABLED
var->var_cached = NULL;
var->var_cached_tsid = 0;
var->var_cached_tsver = 0;
+#endif
+
+ var->var_hash = contextvar_generate_hash(var, name);
+ if (var->var_hash == -1) {
+ Py_DECREF(var);
+ return NULL;
+ }
if (_PyObject_GC_MAY_BE_TRACKED(name) ||
(def != NULL && _PyObject_GC_MAY_BE_TRACKED(def)))
@@ -871,9 +868,11 @@ contextvar_tp_clear(PyContextVar *self)
{
Py_CLEAR(self->var_name);
Py_CLEAR(self->var_default);
+#ifndef Py_GIL_DISABLED
self->var_cached = NULL;
self->var_cached_tsid = 0;
self->var_cached_tsver = 0;
+#endif
return 0;
}
@@ -974,12 +973,6 @@ static PyObject *
_contextvars_ContextVar_get_impl(PyContextVar *self, PyObject *default_value)
/*[clinic end generated code: output=0746bd0aa2ced7bf input=30aa2ab9e433e401]*/
{
- if (!PyContextVar_CheckExact(self)) {
- PyErr_SetString(
- PyExc_TypeError, "an instance of ContextVar was expected");
- return NULL;
- }
-
PyObject *val;
if (PyContextVar_Get((PyObject *)self, default_value, &val) < 0) {
return NULL;
@@ -1043,7 +1036,7 @@ _contextvars_ContextVar_reset(PyContextVar *self, PyObject *token)
static PyMemberDef PyContextVar_members[] = {
- {"name", T_OBJECT, offsetof(PyContextVar, var_name), READONLY},
+ {"name", _Py_T_OBJECT, offsetof(PyContextVar, var_name), Py_READONLY},
{NULL}
};
@@ -1268,7 +1261,7 @@ PyTypeObject _PyContextTokenMissing_Type = {
static PyObject *
get_token_missing(void)
{
- return Py_NewRef(&_Py_SINGLETON(context_token_missing));
+ return (PyObject *)&_Py_SINGLETON(context_token_missing);
}
@@ -1276,27 +1269,19 @@ get_token_missing(void)
void
-_PyContext_ClearFreeList(PyInterpreterState *interp)
+_PyContext_ClearFreeList(struct _Py_object_freelists *freelists, int is_finalization)
{
-#if PyContext_MAXFREELIST > 0
- struct _Py_context_state *state = &interp->context;
- for (; state->numfree; state->numfree--) {
- PyContext *ctx = state->freelist;
- state->freelist = (PyContext *)ctx->ctx_weakreflist;
+#ifdef WITH_FREELISTS
+ struct _Py_context_freelist *state = &freelists->contexts;
+ for (; state->numfree > 0; state->numfree--) {
+ PyContext *ctx = state->items;
+ state->items = (PyContext *)ctx->ctx_weakreflist;
ctx->ctx_weakreflist = NULL;
PyObject_GC_Del(ctx);
}
-#endif
-}
-
-
-void
-_PyContext_Fini(PyInterpreterState *interp)
-{
- _PyContext_ClearFreeList(interp);
-#if defined(Py_DEBUG) && PyContext_MAXFREELIST > 0
- struct _Py_context_state *state = &interp->context;
- state->numfree = -1;
+ if (is_finalization) {
+ state->numfree = -1;
+ }
#endif
}