8000 backport a9a74da 3.13 by JelleZijlstra · Pull Request #119642 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

backport a9a74da 3.13 #119642

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 160 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
160 commits
Select commit Hold shift + click to select a range
c844b14
Post 3.13.0b1
Yhg1s May 8, 2024
58d9a9b
[3.13] Run CI on the 3.13 branch (GH-118779) (#118781)
miss-islington May 8, 2024
02d49af
[3.13] Docs: fix typos in documentation (GH-118752) (#118787)
miss-islington May 8, 2024
c6680cd
[3.13] gh-118772: Allow TypeVars without a default to follow those wi…
miss-islington May 8, 2024
c33bba6
[3.13] docs: module page titles should not start with a link to thems…
miss-islington May 8, 2024
8f31af6
[3.13] Format None, True, False and NotImplemented as literals (GH-11…
miss-islington May 8, 2024
7b9ca26
[3.13] gh-117657: Fix data races when writing / reading `ob_gc_bits` …
miss-islington May 8, 2024
09896fc
[3.13] [tests]: Mark ``test_statistics.test_kde_random`` with a ``req…
miss-islington May 9, 2024
632682c
[3.13] gh-118033: Fix `__weakref__` not set for generic dataclasses (…
miss-islington May 9, 2024
d86b494
gh-118486: Update docs for CVE-2024-4030 reference (GH-118737)
zooba May 9, 2024
c4b853f
[3.13] gh-103956: Fix `trace` output in case of missing source line (…
miss-islington May 9, 2024
a98e44a
gh-118802: Fix ACL use in test for non-English Windows (GH-118831)
miss-islington May 9, 2024
738877a
[3.13] gh-118817: Fix `asyncio REPL` on Windows (GH-118819) (#118847)
miss-islington May 9, 2024
62a559a
[3.13] gh-117657: Acquire a critical section around `SemLock.__{enter…
miss-islington May 9, 2024
9d646d0
gh-118773: Use language-invariant SDDL string instead of aliases for …
miss-islington May 9, 2024
098eec9
[3.13] gh-118849: Fix "code will never be executed" warning in `dicto…
miss-islington May 9, 2024
846cfb9
[3.13] gh-118561: Fix crash involving list.extend in free-threaded bu…
miss-islington May 9, 2024
0a23970
[3.13] gh-116984: Make mimalloc header includes relative to the curre…
miss-islington May 9, 2024
d4c6948
[3.13] gh-118846: Fix PGO tests in free-threaded build (GH-118862) (#…
miss-islington May 9, 2024
982c73a
[3.13] gh-117657: Replace TSAN suppresions with more specific rules (…
miss-islington May 9, 2024
00ec116
[3.13] gh-118851: Default ctx arguments to AST constructors to Load()…
miss-islington May 9, 2024
b62cb52
[3.13] Revert "gh-115432: Add critical section variant that handles a…
miss-islington May 9, 2024
d524802
Fix some missing null checks. (GH-118721)
miss-islington May 10, 2024
760b3f0
gh-118689: Doc: fix ePub build (GH-118690)
miss-islington May 10, 2024
7dc9875
gh-118209: Add Windows structured exception handling to mmap module (…
miss-islington May 10, 2024
93fce2d
[3.13] Rename `notimplemented_methods` into `nodefault_methods` (GH-1…
miss-islington May 10, 2024
bb5bf24
[3.13] gh-118789: Restore hidden `_PyWeakref_ClearRef` (GH-118797) (G…
miss-islington May 10, 2024
4480dd8
[3.13] gh-117657: Fix data races reported by TSAN on `interp->threads…
miss-islington May 10, 2024
0874a40
[3.13] Correct the argument names for `secrets.choice` and `secrets.r…
miss-islington May 10, 2024
0becae3
[3.13] gh-117657: Fix QSBR race condition (GH-118843) (#118905)
miss-islington May 10, 2024
6df4913
[3.13] gh-118895: Call PyType_Ready() on typing.NoDefault (GH-118897)…
miss-islington May 10, 2024
b3074f0
[3.13] Rename typing._collect_parameters (GH-118900) (#118917)
miss-islington May 10, 2024
cceb758
[3.13] gh-118846: Fix free-threading test failures when run sequentia…
miss-islington May 10, 2024
7dc9e92
[3.13] gh-117657: Log TSAN warnings to separate files and archive the…
miss-islington May 10, 2024
93ef7aa
[3.13] gh-118921: Add `copy()` method for `FrameLocalsProxy` (GH-1189…
miss-islington May 10, 2024
d309474
[3.13] gh-117655: Prevent `test_strptime` from raising a DeprecationW…
miss-islington May 11, 2024
6e855b3
[3.13] gh-118899: Add tests for `NotImplemented` attribute access (GH…
miss-islington May 12, 2024
9d2c10b
[3.13] GH-118844: Fix build failures when combining --disable-gil wit…
miss-islington May 13, 2024
a8ea966
[3.13] gh-87106: Fix inspect.signature.bind() handling of positional-…
miss-islington May 13, 2024
9418832
[3.13] Improve the `rmtree` doc for `dir_fd` param addition in 3.11 (…
miss-islington May 13, 2024
44995aa
gh-118876: Ensure PC/layout sets ns.temp before using it (GH-118880)
miss-islington May 13, 2024
09d4c07
[3.13] gh-58933: Make pdb return to caller frame correctly when f_tra…
miss-islington May 13, 2024
d1aac22
[3.13] gh-119010: Adds docs about `__type_params__` to `functools.upd…
miss-islington May 13, 2024
c7628b0
[3.13] gh-118998: Handle errors correctly in `tmtotuple` in `timemodu…
miss-islington May 13, 2024
29a2f9c
[3.13] GH-118836: Fix JIT build error when SHT_NOTE section is presen…
miss-islington May 13, 2024
8720006
[3.13] gh-67693: Fix urlunparse() and urlunsplit() for URIs with path…
miss-islington May 14, 2024
54839f0
[3.13] Add yet few cases for urlparse/urlunparse roundtrip tests (GH-…
miss-islington May 14, 2024
041cc2a
[3.13] typing tests: remove some unnecessary uses of `exec()` (GH-119…
miss-islington May 14, 2024
87f683e
[3.13] Itertools docs: fix parameter names and indentation in Python …
miss-islington May 14, 2024
8439d09
[3.13] Misc improvements to the itertools docs (gh-119040) (#119045)
miss-islington May 14, 2024
dd8a61f
[3.13] 3.13 What's New: Add PEP 702 (GH-118922) (#119062)
miss-islington May 15, 2024
e1dfa97
gh-118486: Simplify test_win32_mkdir_700 to check the exact ACL (GH-1…
miss-islington May 15, 2024
f85d59c
[3.13] Remove references to private symbols from zipimport module doc…
miss-islington May 15, 2024
4f81915
[3.13] gh-118760: Fix errors in calling Tkinter bindings on Windows (…
miss-islington May 15, 2024
7c224dd
[3.13] gh-119009: Add gettext target (GH-119006) (#119074)
miss-islington May 15, 2024
bca7fb0
[3.13] Use literal syntax in origin property (GH-119029) (#119083)
miss-islington May 16, 2024
1dc7fcd
[3.13] gh-119064: Use os_helper.FakePath instead of pathlib.Path in t…
miss-islington May 16, 2024
8a4730e
[3.13] Add Tkinter tests for different events (GH-118778) (GH-119091)
miss-islington May 16, 2024
c69fe80
[3.13] gh-108267: Fix object.__setattr__ regression in dataclasses do…
miss-islington May 16, 2024
45fbca9
[3.13] Explain how to install LLVM on Fedora (GH-119100)
miss-islington May 16, 2024
acffe20
[3.13] GH-118943: Fix a race condition when generating jit_stencils.h…
miss-islington May 16, 2024
ada4ad0
[3.13] Fix typos in documentation (GH-119092) (#119116)
miss-islington May 17, 2024
ced71d3
[3.13] gh-119049: Fix incorrect display of warning which is construct…
miss-islington May 17, 2024
374655f
[3.13] Minor improvements to the docs for itertools.tee() (gh-119135)…
miss-islington May 18, 2024
1bb3a9d
[3.13] gh-119078: Clarify venv tutorial (GH-119129) (GH-119142)
miss-islington May 18, 2024
9c2de86
[3.13] gh-119132: Log sys._is_gil_enabled() in test.pythoninfo (GH-11…
miss-islington May 18, 2024
641e59d
[3.13] docs: make mimalloc license text literal (GH-119046) (#119149)
miss-islington May 18, 2024
ec88e9f
[3.13] gh-119132: Update sys.version to identify free-threaded or not…
miss-islington May 18, 2024
9129614
[3.13] gh-119050: Add type hints to libregrtest/results.py (GH-119144…
miss-islington May 18, 2024
7407267
[3.13] GH-118447: Fix handling of unreadable symlinks in `os.path.rea…
miss-islington May 18, 2024
bc5e47c
[3.13] marshal docs: Remove reference to "Sun" (GH-119161) (#119167)
miss-islington May 19, 2024
fdc50ba
[3.13] GH-118447: Fix FreeBSD test failures. (GH-119170) (#119181)
miss-islington May 19, 2024
27b61c1
[3.13] GH-119113: Raise `TypeError` from `pathlib.PurePath.with_suffi…
miss-islington May 19, 2024
3b90807
[3.13] IDLE: fix url in config.py comment (GH-119198) (#119199)
miss-islington May 20, 2024
3a8ab99
[3.13] gh-119121: Fix and test `async.staggered.staggered_race` (GH-1…
miss-islington May 20, 2024
cbf064b
[3.13] typing docs: Fix formatting issue (GH-119210) (#119212)
miss-islington May 20, 2024
a52ed7e
[3.13] gh-119185: Fix typo in `_pyrepl.pager`: `tempfilepager` should…
miss-islington May 20, 2024
8f3fc01
[3.13] [docs] TypeVarTuple default is keyword-only (GH-119215) (#119224)
miss-islington May 20, 2024
e370b64
[3.13] gh-115119: Fall back to bundled libmpdec if system libmpdec is…
miss-islington May 20, 2024
a6b873f
[3.13] GH-119146: Don't run JIT CI on unrelated changes (GH-119226)
miss-islington May 20, 2024
< 8000 code class="float-right">fda3291
[3.13] DOCS: Suggest always calling exec with a globals argument and …
miss-islington May 20, 2024
d8c562a
[3.13] gh-112844: Update CPE references for external dependencies (GH…
miss-islington May 20, 2024
054f1af
[3.13] gh-92081: Fix for email.generator.Generator with whitespace be…
miss-islington May 20, 2024
906f6cb
[3.13] Use correct markup in unittest.mock.reset_mock documentation (…
miss-islington May 20, 2024
b4462aa
[3.13] gh-118760: Restore the default value of tkinter.wantobjects to…
miss-islington May 20, 2024
572b0b0
[3.13] gh-119189: Add more tests for mixed Fraction arithmetic (GH-11…
miss-islington May 20, 2024
071d996
[3.13] gh-119253: use ImportError in _ios_support (GH-119254) (#119265)
miss-islington May 20, 2024
42a8d11
[3.13] gh-119050: Add XML support to libregrtest refleak checker (GH-…
miss-islington May 20, 2024
d8fbe5b
[3.13] gh-108267 Fix another dataclasses docs typo (GH-119277) (#119279)
miss-islington May 20, 2024
24b0e8d
[3.13] gh-118912: Remove description of issue fixed in 3.5 from autos…
miss-islington May 20, 2024
f7303cd
[3.13] gh-119174: Fix high DPI causes turtledemo(turtle-graphics exam…
miss-islington May 21, 2024
db64dae
[3.13] gh-74929: PEP 667 general docs update (gh-119291)
miss-islington May 21, 2024
49ad4d0
[3.13] Use `fail-fast: false` in `mypy.yml` (GH-119297) (#119304)
miss-islington May 21, 2024
f028451
[3.13] gh-119102: Fix REPL for dumb terminal (GH-119269) (#119308)
miss-islington May 21, 2024
1929b7e
[3.13] Docs: Ensure no warnings are found in the NEWS file before a g…
hugovk May 21, 2024
dcb8030
[3.13] gh-119053: Implement the fast path for list.__getitem__ (gh-11…
miss-islington May 21, 2024
d93c4f9
[3.13] GH-119292: Add job to JIT CI to build and test with --disable-…
miss-islington May 21, 2024
11ca1d9
[3.13] GH-110383: Improve Tutorial for Input Ouput (GH-119230) (GH-11…
miss-islington May 21, 2024
256b791
[3.13] gh-110383: Document `socket.makefile()` accepts combined modes…
miss-islington May 21, 2024
8860f83
[3.13] gh-119035: Add Ctrl+← and Ctrl+→ word-skipping keybindings to …
miss-islington May 21, 2024
fef202f
[3.13] Fix typos in documentation (GH-119295) (#119337)
miss-islington May 21, 2024
0582016
[3.13] Docs: Add central references to free-threading-related options…
miss-islington May 21, 2024
f371565
[3.13] gh-119102: Fix REPL for dumb terminal (GH-119332) (#119359)
miss-islington May 22, 2024
f15fbe9
gh-118507 : Refactor `nt._path_is*` to improve applicability for othe…
miss-islington May 22, 2024
e992217
[3.13] gh-118877: Fix AssertionError crash in pyrepl (GH-118936) (#11…
miss-islington May 22, 2024
455b386
[3.13] gh-110383: Align dict.get(), .fromkeys(), and .setdefault() do…
miss-islington May 22, 2024
b5b0e32
[3.13] DOCS: fix error in exec namespace note (gh-119380)
miss-islington May 22, 2024
f757996
[3.13] Clarify that dklen is expected in bytes for the hashlib functi…
miss-islington May 22, 2024
ec484b6
[3.13] gh-119189: Add yet more tests for mixed Fraction arithmetic (G…
miss-islington May 22, 2024
0e61989
[3.13] Fix typos in NEWS entries for 3.13 (GH-119374) (GH-119385)
miss-islington May 22, 2024
414346e
[3.13] Fix version number in use_load_tests deprecation reference (GH…
miss-islington May 22, 2024
6892b40
[3.13] gh-118643: Fix AttributeError in the email module (GH-119099) …
miss-islington May 22, 2024
7214598
[3.13] gh-119306: Break up _pyrepl tests (GH-119307) (#119362)
lysnikolaou May 22, 2024
ac91636
[3.13] gh-111201: Remove readline dependency from the PyREPL (GH-1192…
lysnikolaou May 22, 2024
aefe2e6
[3.13] gh-111201: Add append to screen method to avoid recalculation …
miss-islington May 22, 2024
eafd633
[3.13] gh-119205: Fix autocompletion bug in new repl (GH-119229) (#11…
miss-islington May 22, 2024
a463cd8
[3.13] gh-118893: Evaluate all statements in the new REPL separately …
miss-islington May 22, 2024
bfd9c3e
[3.13] gh-119213: Be More Careful About _PyArg_Parser.kwtuple Across …
miss-islington May 22, 2024
cd39da7
[3.13] Improve `pyrepl` type-annotation coverage (GH-119081) (#119415)
miss-islington May 22, 2024
0841606
[3.13] gh-119247: Add macros to use PySequence_Fast safely in free-th…
miss-islington May 22, 2024
0bd7c87
[3.13] gh-112066: Fix versionadded in PyDict_SetDefaultRef docs (GH-1…
miss-islington May 22, 2024
3e30a38
gh-117505: Run ensurepip in isolated env in Windows installer (GH-118…
miss-islington May 22, 2024
e6e4efc
[3.13] gh-119357: Increase test coverage for keymap in _pyrepl (GH-11…
lysnikolaou May 22, 2024
6bc7fc0
[3.13] gh-113978: Ignore warnings on text completion inside REPL (GH-…
miss-islington May 22, 2024
81440c5
[3.13] Enable some stricter mypy settings on `Lib/_pyrepl` (GH-119077…
miss-islington May 22, 2024
9435124
[3.13] gh-111201: auto-indentation in _pyrepl (GH-119348) (#119427)
lysnikolaou May 22, 2024
a6ed742
[3.13] gh-70795: Rework RLock documentation (GH-103853) (#119436)
miss-islington May 22, 2024
cd35e9d
[3.13] gh-117657: Fix missing atomic in dict_resize (GH-119312) (#119…
miss-islington May 22, 2024
dbff1f1
[3.13] gh-119434: Fix culmitive errors in wrapping as lines proceed (…
miss-islington May 23, 2024
9fa1b4f
[3.13] gh-118911: Trailing whitespace in a block shouldn't prevent th…
lysnikolaou May 23, 2024
58dbb4a
[3.13] gh-111201: Speed up paste mode in the REPL (#119341) (GH-11943…
miss-islington May 23, 2024
89e2689
[3.13] gh-90562: Mention slots pitfall in dataclass docs (GH-107391) …
miss-islington May 23, 2024
dbe4f8a
[3.13] Fix typos in what's new documentation (GH-119448) (#119449)
miss-islington May 23, 2024
251ef2e
[3.13] GH-117195: Avoid assertion error in `object.__sizeof__` (GH-11…
miss-islington May 23, 2024
8fd8cc5
[3.13] gh-119469: Fix _pyrepl reference leaks (GH-119470) (#119471)
miss-islington May 23, 2024
d98d6b1
[3.13] gh-118727: Don't drop the GIL in `drop_gil()` unless the curre…
miss-islington May 23, 2024
c750061
[3.13] gh-119461: Fix ThreadedVSOCKSocketStreamTest (#119465) (#119479)
vstinner May 23, 2024
e27e369
[3.13] GH-113464: Run the JIT interpreter before any other JIT CI (GH…
miss-islington May 24, 2024
c864efb
[3.13] gh-118692: Avoid creating unnecessary StopIteration instances …
miss-islington May 24, 2024
0bab0b3
[3.13] gh-69214: Fix fcntl.ioctl() request type (GH-119498) (#119504)
miss-islington May 24, 2024
217d57f
[3.13] GH-119496: accept UTF-8 BOM in .pth files (GH-119508)
miss-islington May 24, 2024
cc38ee1
gh-118263: Add additional arguments to path_t (Argument Clinic type) …
miss-islington May 24, 2024
392a3d8
[3.13] Regen ``Doc/requirements-oldest-sphinx.txt`` (GH-119520) (#119…
miss-islington May 24, 2024
5544651
[3.13] Misc improvement to the docs for itertools (gh-119529) (#119531)
rhettinger May 24, 2024
f49749c
[3.13] gh-111999: Fix the signature of str.format_map() (GH-119540) (…
miss-islington May 25, 2024
317cc3b
[3.13] FAQ: Add reference to Python version numbering scheme (GH-1192…
miss-islington May 25, 2024
2404cd9
[3.13] gh-99180: Make `StackSummary.should_show_carets` private (GH-1…
miss-islington May 25, 2024
3f0198d
[3.13] docs: fix a few typos identified by codespell (GH-119516) (#11…
miss-islington May 26, 2024
825a5ae
[3.13] gh-111997: Fix argument count for LINE event and clarify type …
miss-islington May 26, 2024
46d7712
[3.13] Fix typos in HISTORY documentation (GH-119453) (#119597)
miss-islington May 27, 2024
f1302c1
[3.13] gh-119467: Fix Py_buffer.format type and correct documentation…
miss-islington May 27, 2024
ba71835
[3.13] Docs: Only install sphinx-autobuild for `make htmllive` (GH-11…
miss-islington May 27, 2024
9edf010
[3.13] gh-119580: Improve version added section for convenience varia…
miss-islington May 27, 2024
8117cb5
[3.13] Misc cleanups and wording improvements for the itertools docs …
miss-islington May 27, 2024
0a4a318
[3.13] Docs: Move inline JavaScript to own file to reduce duplication…
hugovk May 27, 2024
bd9983c
[3.13] gh-119560: Drop an Invalid Assert in PyState_FindModule() (gh-…
miss-islington May 27, 2024
660125f
[3.13] gh-119584: Fix test_import Failed Assertion (gh-119623) (gh-11…
miss-islington May 27, 2024
d58ebf0
[3.13] gh-117398: Add multiphase support to _datetime (gh-119373) (gh…
miss-islington May 27, 2024
7322ff1
[3.13] gh-119317: findall instead of traverse for docutils nodes (GH-…
miss-islington May 27, 2024
9216a53
[3.13] gh-117398: Revert gh-119636, Add multiphase support to _dateti…
ericsnowcurrently May 28, 2024
File filter

Filter by extension

8000
Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
[3.13] gh-118727: Don't drop the GIL in drop_gil() unless the curre…
…nt thread holds it (GH-118745) (#119474)

`drop_gil()` assumes that its caller is attached, which means that the current
thread holds the GIL if and only if the GIL is enabled, and the enabled-state
of the GIL won't change. This isn't true, though, because `detach_thread()`
calls `_PyEval_ReleaseLock()` after detaching and
`_PyThreadState_DeleteCurrent()` calls it after removing the current thread
from consideration for stop-the-world requests (effectively detaching it).

Fix this by remembering whether or not a thread acquired the GIL when it last
attached, in `PyThreadState._status.holds_gil`, and check this in `drop_gil()`
instead of `gil->enabled`.

This fixes a crash in `test_multiprocessing_pool_circular_import()`, so I've
reenabled it.
(cherry picked from commit be1dfcc)

Co-authored-by: Brett Simmers <swtaarrs@users.noreply.github.com>
  • Loading branch information
miss-islington and swtaarrs authored May 23, 2024
commit d98d6b1776996484e05ec6b755a6770977a5000a
4 changes: 3 additions & 1 deletion Include/cpython/pystate.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,14 +83,16 @@ struct _ts {
unsigned int bound_gilstate:1;
/* Currently in use (maybe holds the GIL). */
unsigned int active:1;
/* Currently holds the GIL. */
unsigned int holds_gil:1;

/* various stages of finalization */
unsigned int finalizing:1;
unsigned int cleared:1;
unsigned int finalized:1;

/* padding to align to 4 bytes */
unsigned int :24;
unsigned int :23;
} _status;
#ifdef Py_BUILD_CORE
# define _PyThreadState_WHENCE_NOTSET -1
Expand Down
7 changes: 3 additions & 4 deletions Include/internal/pycore_ceval.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,10 @@ extern int _PyEval_ThreadsInitialized(void);
extern void _PyEval_InitGIL(PyThreadState *tstate, int own_gil);
extern void _PyEval_FiniGIL(PyInterpreterState *interp);

// Acquire the GIL and return 1. In free-threaded builds, this function may
// return 0 to indicate that the GIL was disabled and therefore not acquired.
extern int _PyEval_AcquireLock(PyThreadState *tstate);
extern void _PyEval_AcquireLock(PyThreadState *tstate);

extern void _PyEval_ReleaseLock(PyInterpreterState *, PyThreadState *);
extern void _PyEval_ReleaseLock(PyInterpreterState *, PyThreadState *,
int final_release);

#ifdef Py_GIL_DISABLED
// Returns 0 or 1 if the GIL for the given thread's interpreter is disabled or
Expand Down
5 changes: 1 addition & 4 deletions Lib/test/test_importlib/test_threaded_import.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from test.support import verbose
from test.support.import_helper import forget, mock_register_at_fork
from test.support.os_helper import (TESTFN, unlink, rmtree)
from test.support import script_helper, threading_helper, requires_gil_enabled
from test.support import script_helper, threading_helper

threading_helper.requires_working_threading(module=True)

Expand Down Expand Up @@ -248,9 +248,6 @@ def test_concurrent_futures_circular_import(self):
'partial', 'cfimport.py')
script_helper.assert_python_ok(fn)

# gh-118727 and gh-118729: pool_in_threads.py may crash in free-threaded
# builds, which can hang the Tsan test so temporarily skip it for now.
@requires_gil_enabled("gh-118727: test may crash in free-threaded builds")
def test_multiprocessing_pool_circular_import(self):
# Regression test for bpo-41567
fn = os.path.join(os.path.dirname(__file__),
Expand Down
96 changes: 57 additions & 39 deletions Python/ceval_gil.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,59 +205,63 @@ static void recreate_gil(struct _gil_runtime_state *gil)
}
#endif

static void
drop_gil_impl(struct _gil_runtime_state *gil)
static inline void
drop_gil_impl(PyThreadState *tstate, struct _gil_runtime_state *gil)
{
MUTEX_LOCK(gil->mutex);
_Py_ANNOTATE_RWLOCK_RELEASED(&gil->locked, /*is_write=*/1);
_Py_atomic_store_int_relaxed(&gil->locked, 0);
if (tstate != NULL) {
tstate->_status.holds_gil = 0;
}
COND_SIGNAL(gil->cond);
MUTEX_UNLOCK(gil->mutex);
}

static void
drop_gil(PyInterpreterState *interp, PyThreadState *tstate)
drop_gil(PyInterpreterState *interp, PyThreadState *tstate, int final_release)
{
struct _ceval_state *ceval = &interp->ceval;
/* If tstate is NULL, the caller is indicating that we're releasing
/* If final_release is true, the caller is indicating that we're releasing
the GIL for the last time in this thread. This is particularly
relevant when the current thread state is finalizing or its
interpreter is finalizing (either may be in an inconsistent
state). In that case the current thread will definitely
never try to acquire the GIL again. */
// XXX It may be more correct to check tstate->_status.finalizing.
// XXX assert(tstate == NULL || !tstate->_status.cleared);
// XXX assert(final_release || !tstate->_status.cleared);

assert(final_release || tstate != NULL);
struct _gil_runtime_state *gil = ceval->gil;
#ifdef Py_GIL_DISABLED
if (!_Py_atomic_load_int_relaxed(&gil->enabled)) {
// Check if we have the GIL before dropping it. tstate will be NULL if
// take_gil() detected that this thread has been destroyed, in which case
// we know we have the GIL.
if (tstate != NULL && !tstate->_status.holds_gil) {
return;
}
#endif
if (!_Py_atomic_load_int_relaxed(&gil->locked)) {
Py_FatalError("drop_gil: GIL is not locked");
}

/* tstate is allowed to be NULL (early interpreter init) */
if (tstate != NULL) {
if (!final_release) {
/* Sub-interpreter support: threads might have been switched
under our feet using PyThreadState_Swap(). Fix the GIL last
holder variable so that our heuristics work. */
_Py_atomic_store_ptr_relaxed(&gil->last_holder, tstate);
}

drop_gil_impl(gil);
drop_gil_impl(tstate, gil);

#ifdef FORCE_SWITCHING
/* We check tstate first in case we might be releasing the GIL for
the last time in this thread. In that case there's a possible
race with tstate->interp getting deleted after gil->mutex is
unlocked and before the following code runs, leading to a crash.
We can use (tstate == NULL) to indicate the thread is done with
the GIL, and that's the only time we might delete the
interpreter, so checking tstate first prevents the crash.
See https://github.com/python/cpython/issues/104341. */
if (tstate != NULL &&
/* We might be releasing the GIL for the last time in this thread. In that
case there's a possible race with tstate->interp getting deleted after
gil->mutex is unlocked and before the following code runs, leading to a
crash. We can use final_release to indicate the thread is done with the
GIL, and that's the only time we might delete the interpreter. See
https://github.com/python/cpython/issues/104341. */
if (!final_release &&
_Py_eval_breaker_bit_is_set(tstate, _PY_GIL_DROP_REQUEST_BIT)) {
MUTEX_LOCK(gil->switch_mutex);
/* Not switched yet => wait */
Expand All @@ -284,7 +288,7 @@ drop_gil(PyInterpreterState *interp, PyThreadState *tstate)
tstate must be non-NULL.

Returns 1 if the GIL was acquired, or 0 if not. */
static int
static void
take_gil(PyThreadState *tstate)
{
int err = errno;
Expand All @@ -309,7 +313,7 @@ take_gil(PyThreadState *tstate)
struct _gil_runtime_state *gil = interp->ceval.gil;
#ifdef Py_GIL_DISABLED
if (!_Py_atomic_load_int_relaxed(&gil->enabled)) {
return 0;
return;
}
#endif

Expand Down Expand Up @@ -358,10 +362,10 @@ take_gil(PyThreadState *tstate)
if (!_Py_atomic_load_int_relaxed(&gil->enabled)) {
// Another thread disabled the GIL between our check above and
// now. Don't take the GIL, signal any other waiting threads, and
// return 0.
// return.
COND_SIGNAL(gil->cond);
MUTEX_UNLOCK(gil->mutex);
return 0;
return;
}
#endif

Expand Down Expand Up @@ -393,20 +397,21 @@ take_gil(PyThreadState *tstate)
in take_gil() while the main thread called
wait_for_thread_shutdown() from Py_Finalize(). */
MUTEX_UNLOCK(gil->mutex);
/* Passing NULL to drop_gil() indicates that this thread is about to
terminate and will never hold the GIL again. */
drop_gil(interp, NULL);
/* tstate could be a dangling pointer, so don't pass it to
drop_gil(). */
drop_gil(interp, NULL, 1);
PyThread_exit_thread();
}
assert(_PyThreadState_CheckConsistency(tstate));

tstate->_status.holds_gil = 1;
_Py_unset_eval_breaker_bit(tstate, _PY_GIL_DROP_REQUEST_BIT);
update_eval_breaker_for_thread(interp, tstate);

MUTEX_UNLOCK(gil->mutex);

errno = err;
return 1;
return;
}

void _PyEval_SetSwitchInterval(unsigned long microseconds)
Expand Down Expand Up @@ -451,10 +456,17 @@ PyEval_ThreadsInitialized(void)
static inline int
current_thread_holds_gil(struct _gil_runtime_state *gil, PyThreadState *tstate)
{
if (((PyThreadState*)_Py_atomic_load_ptr_relaxed(&gil->last_holder)) != tstate) {
return 0;
}
return _Py_atomic_load_int_relaxed(&gil->locked);
int holds_gil = tstate->_status.holds_gil;

// holds_gil is the source of truth; check that last_holder and gil->locked
// are consistent with it.
int locked = _Py_atomic_load_int_relaxed(&gil->locked);
int is_last_holder =
((PyThreadState*)_Py_atomic_load_ptr_relaxed(&gil->last_holder)) == tstate;
assert(!holds_gil || locked);
assert(!holds_gil || is_last_holder);

return holds_gil;
}
#endif

Expand Down Expand Up @@ -563,23 +575,24 @@ PyEval_ReleaseLock(void)
/* This function must succeed when the current thread state is NULL.
We therefore avoid PyThreadState_Get() which dumps a fatal error
in debug mode. */
drop_gil(tstate->interp, tstate);
drop_gil(tstate->interp, tstate, 0);
}

int
void
_PyEval_AcquireLock(PyThreadState *tstate)
{
_Py_EnsureTstateNotNULL(tstate);
return take_gil(tstate);
take_gil(tstate);
}

void
_PyEval_ReleaseLock(PyInterpreterState *interp, PyThreadState *tstate)
_PyEval_ReleaseLock(PyInterpreterState *interp,
PyThreadState *tstate,
int final_release)
{
/* If tstate is NULL then we do not expect the current thread
to acquire the GIL ever again. */
assert(tstate == NULL || tstate->interp == interp);
drop_gil(interp, tstate);
assert(tstate != NULL);
assert(tstate->interp == interp);
drop_gil(interp, tstate, final_release);
}

void
Expand Down Expand Up @@ -1136,7 +1149,12 @@ _PyEval_DisableGIL(PyThreadState *tstate)
//
// Drop the GIL, which will wake up any threads waiting in take_gil()
// and let them resume execution without the GIL.
drop_gil_impl(gil);
drop_gil_impl(tstate, gil);

// If another thread asked us to drop the GIL, they should be
// free-threading by now. Remove any such request so we have a clean
// slate if/when the GIL is enabled again.
_Py_unset_eval_breaker_bit(tstate, _PY_GIL_DROP_REQUEST_BIT);
return 1;
}
return 0;
Expand Down
11 changes: 4 additions & 7 deletions Python/pystate.c
Original file line number Diff line number Diff line change
Expand Up @@ -1843,7 +1843,7 @@ _PyThreadState_DeleteCurrent(PyThreadState *tstate)
#endif
current_fast_clear(tstate->interp->runtime);
tstate_delete_common(tstate);
_PyEval_ReleaseLock(tstate->interp, NULL);
_PyEval_ReleaseLock(tstate->interp, tstate, 1);
free_threadstate((_PyThreadStateImpl *)tstate);
}

Expand Down Expand Up @@ -2068,7 +2068,7 @@ _PyThreadState_Attach(PyThreadState *tstate)


while (1) {
int acquired_gil = _PyEval_AcquireLock(tstate);
_PyEval_AcquireLock(tstate);

// XXX assert(tstate_is_alive(tstate));
current_fast_set(&_PyRuntime, tstate);
Expand All @@ -2079,20 +2079,17 @@ _PyThreadState_Attach(PyThreadState *tstate)
}

#ifdef Py_GIL_DISABLED
if (_PyEval_IsGILEnabled(tstate) != acquired_gil) {
if (_PyEval_IsGILEnabled(tstate) && !tstate->_status.holds_gil) {
// The GIL was enabled between our call to _PyEval_AcquireLock()
// and when we attached (the GIL can't go from enabled to disabled
// here because only a thread holding the GIL can disable
// it). Detach and try again.
assert(!acquired_gil);
tstate_set_detached(tstate, _Py_THREAD_DETACHED);
tstate_deactivate(tstate);
current_fast_clear(&_PyRuntime);
continue;
}
_Py_qsbr_attach(((_PyThreadStateImpl *)tstate)->qsbr);
#else
(void)acquired_gil;
#endif
break;
}
Expand Down Expand Up @@ -2123,7 +2120,7 @@ detach_thread(PyThreadState *tstate, int detached_state)
tstate_deactivate(tstate);
tstate_set_detached(tstate, detached_state);
current_fast_clear(&_PyRuntime);
_PyEval_ReleaseLock(tstate->interp, tstate);
_PyEval_ReleaseLock(tstate->interp, tstate, 0);
}

void
Expand Down
Loading
0