Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitbfd316e

Browse files
committed
Add _PyThreadState_UncheckedGet()
Issue#26154: Add a new private _PyThreadState_UncheckedGet() function whichgets the current thread state, but don't call Py_FatalError() if it is NULL.Python 3.5.1 removed the _PyThreadState_Current symbol from the Python C API tono more expose complex and private atomic types. Atomic types depends on thecompiler or can even depend on compiler options. The new function_PyThreadState_UncheckedGet() allows to get the variable value without havingto care of the exact implementation of atomic types.Changes:* Replace direct usage of the _PyThreadState_Current variable with a call to _PyThreadState_UncheckedGet().* In pystate.c, replace direct usage of the _PyThreadState_Current variable with the PyThreadState_GET() macro for readability.* Document also PyThreadState_Get() in pystate.h
1 parentaebb6d3 commitbfd316e

File tree

7 files changed

+42
-26
lines changed

7 files changed

+42
-26
lines changed

‎Include/pystate.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,17 @@ PyAPI_FUNC(void) PyThreadState_DeleteCurrent(void);
168168
PyAPI_FUNC(void)_PyGILState_Reinit(void);
169169
#endif
170170

171+
/* Return the current thread state. The global interpreter lock must be held.
172+
* When the current thread state is NULL, this issues a fatal error (so that
173+
* the caller needn't check for NULL). */
171174
PyAPI_FUNC(PyThreadState*)PyThreadState_Get(void);
175+
176+
#ifdefWITH_THREAD
177+
/* Similar to PyThreadState_Get(), but don't issue a fatal error
178+
* if it is NULL. */
179+
PyAPI_FUNC(PyThreadState*)_PyThreadState_UncheckedGet(void);
180+
#endif
181+
172182
PyAPI_FUNC(PyThreadState*)PyThreadState_Swap(PyThreadState*);
173183
PyAPI_FUNC(PyObject*)PyThreadState_GetDict(void);
174184
PyAPI_FUNC(int)PyThreadState_SetAsyncExc(long,PyObject*);

‎Misc/NEWS

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@ Release date: tba
1010
Core and Builtins
1111
-----------------
1212

13+
- Issue #26154: Add a new private _PyThreadState_UncheckedGet() function to get
14+
the current Python thread state, but don't issue a fatal error if it is NULL.
15+
This new function must be used instead of accessing directly the
16+
_PyThreadState_Current variable. The variable is no more exposed since
17+
Python 3.5.1 to hide the exact implementation of atomic C types, to avoid
18+
compiler issues.
19+
1320
- Issue #25731: Fix set and deleting __new__ on a class.
1421

1522
- Issue #22995: [UPDATE] Comment out the one of the pickleability tests in

‎Modules/faulthandler.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,7 @@ faulthandler_thread(void *unused)
490490
assert(st==PY_LOCK_FAILURE);
491491

492492
/* get the thread holding the GIL, NULL if no thread hold the GIL */
493-
current=(PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current);
493+
current=_PyThreadState_UncheckedGet();
494494

495495
_Py_write_noraise(thread.fd,thread.header, (int)thread.header_len);
496496

‎Objects/dictobject.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,8 +1064,7 @@ PyDict_GetItem(PyObject *op, PyObject *key)
10641064
Let's just hope that no exception occurs then... This must be
10651065
_PyThreadState_Current and not PyThreadState_GET() because in debug
10661066
mode, the latter complains if tstate is NULL. */
1067-
tstate= (PyThreadState*)_Py_atomic_load_relaxed(
1068-
&_PyThreadState_Current);
1067+
tstate=_PyThreadState_UncheckedGet();
10691068
if (tstate!=NULL&&tstate->curexc_type!=NULL) {
10701069
/* preserve the existing exception */
10711070
PyObject*err_type,*err_value,*err_tb;
@@ -1102,8 +1101,7 @@ _PyDict_GetItem_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash)
11021101
Let's just hope that no exception occurs then... This must be
11031102
_PyThreadState_Current and not PyThreadState_GET() because in debug
11041103
mode, the latter complains if tstate is NULL. */
1105-
tstate= (PyThreadState*)_Py_atomic_load_relaxed(
1106-
&_PyThreadState_Current);
1104+
tstate=_PyThreadState_UncheckedGet();
11071105
if (tstate!=NULL&&tstate->curexc_type!=NULL) {
11081106
/* preserve the existing exception */
11091107
PyObject*err_type,*err_value,*err_tb;

‎Python/errors.c

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -152,13 +152,7 @@ PyErr_SetString(PyObject *exception, const char *string)
152152
PyObject*
153153
PyErr_Occurred(void)
154154
{
155-
/* If there is no thread state, PyThreadState_GET calls
156-
Py_FatalError, which calls PyErr_Occurred. To avoid the
157-
resulting infinite loop, we inline PyThreadState_GET here and
158-
treat no thread as no error. */
159-
PyThreadState*tstate=
160-
((PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current));
161-
155+
PyThreadState*tstate=_PyThreadState_UncheckedGet();
162156
returntstate==NULL ?NULL :tstate->curexc_type;
163157
}
164158

‎Python/pystate.c

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@
33

44
#include"Python.h"
55

6+
#ifndefPy_BUILD_CORE
7+
/* ensure that PyThreadState_GET() is a macro, not an alias to
8+
* PyThreadState_Get() */
9+
# error "pystate.c must be compiled with Py_BUILD_CORE defined"
10+
#endif
11+
612
/* --------------------------------------------------------------------------
713
CAUTION
814
@@ -423,7 +429,7 @@ tstate_delete_common(PyThreadState *tstate)
423429
void
424430
PyThreadState_Delete(PyThreadState*tstate)
425431
{
426-
if (tstate==(PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current))
432+
if (tstate==PyThreadState_GET())
427433
Py_FatalError("PyThreadState_Delete: tstate is still current");
428434
#ifdefWITH_THREAD
429435
if (autoInterpreterState&&PyThread_get_key_value(autoTLSkey)==tstate)
@@ -437,8 +443,7 @@ PyThreadState_Delete(PyThreadState *tstate)
437443
void
438444
PyThreadState_DeleteCurrent()
439445
{
440-
PyThreadState*tstate= (PyThreadState*)_Py_atomic_load_relaxed(
441-
&_PyThreadState_Current);
446+
PyThreadState*tstate=PyThreadState_GET();
442447
if (tstate==NULL)
443448
Py_FatalError(
444449
"PyThreadState_DeleteCurrent: no current tstate");
@@ -488,11 +493,17 @@ _PyThreadState_DeleteExcept(PyThreadState *tstate)
488493
}
489494

490495

496+
PyThreadState*
497+
_PyThreadState_UncheckedGet(void)
498+
{
499+
returnPyThreadState_GET();
500+
}
501+
502+
491503
PyThreadState*
492504
PyThreadState_Get(void)
493505
{
494-
PyThreadState*tstate= (PyThreadState*)_Py_atomic_load_relaxed(
495-
&_PyThreadState_Current);
506+
PyThreadState*tstate=PyThreadState_GET();
496507
if (tstate==NULL)
497508
Py_FatalError("PyThreadState_Get: no current thread");
498509

@@ -503,8 +514,7 @@ PyThreadState_Get(void)
503514
PyThreadState*
504515
PyThreadState_Swap(PyThreadState*newts)
505516
{
506-
PyThreadState*oldts= (PyThreadState*)_Py_atomic_load_relaxed(
507-
&_PyThreadState_Current);
517+
PyThreadState*oldts=PyThreadState_GET();
508518

509519
_Py_atomic_store_relaxed(&_PyThreadState_Current,newts);
510520
/* It should not be possible for more than one thread state
@@ -535,8 +545,7 @@ PyThreadState_Swap(PyThreadState *newts)
535545
PyObject*
536546
PyThreadState_GetDict(void)
537547
{
538-
PyThreadState*tstate= (PyThreadState*)_Py_atomic_load_relaxed(
539-
&_PyThreadState_Current);
548+
PyThreadState*tstate=PyThreadState_GET();
540549
if (tstate==NULL)
541550
returnNULL;
542551

@@ -682,7 +691,7 @@ PyThreadState_IsCurrent(PyThreadState *tstate)
682691
{
683692
/* Must be the tstate for this thread */
684693
assert(PyGILState_GetThisThreadState()==tstate);
685-
returntstate==(PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current);
694+
returntstate==PyThreadState_GET();
686695
}
687696

688697
/* Internal initialization/finalization functions called by
@@ -774,9 +783,7 @@ PyGILState_GetThisThreadState(void)
774783
int
775784
PyGILState_Check(void)
776785
{
777-
/* can't use PyThreadState_Get() since it will assert that it has the GIL */
778-
PyThreadState*tstate= (PyThreadState*)_Py_atomic_load_relaxed(
779-
&_PyThreadState_Current);
786+
PyThreadState*tstate=PyThreadState_GET();
780787
returntstate&& (tstate==PyGILState_GetThisThreadState());
781788
}
782789

‎Python/sysmodule.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1397,7 +1397,7 @@ PySys_AddXOption(const wchar_t *s)
13971397
Py_XDECREF(name);
13981398
Py_XDECREF(value);
13991399
/* No return value, therefore clear error state if possible */
1400-
if (_Py_atomic_load_relaxed(&_PyThreadState_Current))
1400+
if (_PyThreadState_UncheckedGet())
14011401
PyErr_Clear();
14021402
}
14031403

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp