Skip to content

gh-146452: Improve locking granularity in pickle's batch_dict_exact#150025

Merged
JelleZijlstra merged 1 commit into
python:mainfrom
scopreon:gh-149816-89
May 18, 2026
Merged

gh-146452: Improve locking granularity in pickle's batch_dict_exact#150025
JelleZijlstra merged 1 commit into
python:mainfrom
scopreon:gh-149816-89

Conversation

@scopreon
Copy link
Copy Markdown
Contributor

@scopreon scopreon commented May 18, 2026

Improve critical section locking in batch_dict_exact. This originally held a lock for the entirey of batch_dict_exact_impl, which is not necessary. We can instead have localised locks for sections which require it. It wrapped possibly expensive calls to save() etc

Remove batch_dict_exact_impl which existed to allow the wrapping with critical sections. Called by batch_dict_exact.

Additionally handle the case where PyDict_Next returns 0 in the size 1 special case (modified during pickling).

Note: this spun out of looking into #149816 89, it was fixed in #146452 but I'm not sure exactly what issue this belongs to.

Test was added in https://github.com/python/cpython/pull/146470/changes

@bedevere-app
Copy link
Copy Markdown

bedevere-app Bot commented May 18, 2026

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

@python-cla-bot
Copy link
Copy Markdown

python-cla-bot Bot commented May 18, 2026

All commit authors signed the Contributor License Agreement.

CLA signed

@scopreon scopreon changed the title Improve locking granularity in pickle's batch_dict_exact gh-146452: Improve locking granularity in pickle's batch_dict_exact May 18, 2026
@bedevere-app
Copy link
Copy Markdown

bedevere-app Bot commented May 18, 2026

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

…ing)

Replace the coarse critical section wrapping the entire function with
fine-grained sections covering only PyDict_Next + Py_INCREF.
Also handle PyDict_Next returning 0 in the single-item fast path.
Comment thread Modules/_pickle.c
assert(self->proto > 0);

dict_size = PyDict_GET_SIZE(obj);
assert(dict_size);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We discussed this in person. This assertion could fail if the dictionary gets mutated by another thread between the size check in the caller and this check. The code should work correctly in this case (it will just emit a SETITEMS that sets 0 items), so removing the assertion is the right change.

@JelleZijlstra JelleZijlstra added needs backport to 3.14 bugs and security fixes needs backport to 3.15 pre-release feature fixes, bugs and security fixes labels May 18, 2026
@JelleZijlstra JelleZijlstra merged commit 57a0e57 into python:main May 18, 2026
63 checks passed
@miss-islington-app
Copy link
Copy Markdown

Thanks @scopreon for the PR, and @JelleZijlstra for merging it 🌮🎉.. I'm working now to backport this PR to: 3.14, 3.15.
🐍🍒⛏🤖

@miss-islington-app
Copy link
Copy Markdown

Sorry, @scopreon and @JelleZijlstra, I could not cleanly backport this to 3.14 due to a conflict.
Please backport using cherry_picker on command line.

cherry_picker 57a0e570d36f41b953a91bbaf4262a5d05d0391b 3.14

@bedevere-app
Copy link
Copy Markdown

bedevere-app Bot commented May 18, 2026

GH-150039 is a backport of this pull request to the 3.15 branch.

@bedevere-app bedevere-app Bot removed the needs backport to 3.15 pre-release feature fixes, bugs and security fixes label May 18, 2026
JelleZijlstra pushed a commit that referenced this pull request May 18, 2026
…exact and fix race condition (GH-150025) (#150039)

gh-146452: Improve locking granularity in pickle's batch_dict_exact and fix race condition (GH-150025)

Remove assertion that could fail in rare race condition.

Replace the coarse critical section wrapping the entire function with
fine-grained sections covering only PyDict_Next + Py_INCREF.
Also handle PyDict_Next returning 0 in the single-item fast path.
(cherry picked from commit 57a0e57)

Co-authored-by: Saul Cooperman <58375603+scopreon@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs backport to 3.14 bugs and security fixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants