GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — gh-146452: Improve locking granularity in pickle's batch_dict_exact by scopreon · Pull Request #150025 · python/cpython

Conversation

@scopreon

@scopreon scopreon commented May 18, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

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.

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

  • Issue: Segfault in _pickle.c:batch_dict_exact when pickling dict with concurrent mutation (free-threading) #146452

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@bedevere-app

bedevere-app Bot commented May 18, 2026

Copy link
Copy Markdown

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.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@python-cla-bot

python-cla-bot Bot commented May 18, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

All commit authors signed the Contributor License Agreement.

CLA signed

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-app bedevere-app Bot added the awaiting review label May 18, 2026
@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 bedevere-app Bot mentioned this pull request May 18, 2026
Segfault in _pickle.c:batch_dict_exact when pickling dict with concurrent mutation (free-threading) #146452
Closed
@scopreon
scopreon force-pushed the gh-149816-89 branch from 08500b2 to 8f6a3e3 Compare May 18, 2026 22:18
@bedevere-app

bedevere-app Bot commented May 18, 2026

Copy link
Copy Markdown

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.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@scopreon
Improve locking granularity in pickle's batch_dict_exact (free-thread…
ac03980
…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.
@scopreon
scopreon force-pushed the gh-149816-89 branch from 8f6a3e3 to ac03980 Compare May 18, 2026 22:31
JelleZijlstra
JelleZijlstra approved these changes May 18, 2026
View reviewed changes
@bedevere-app bedevere-app Bot added awaiting merge and removed awaiting review labels May 18, 2026
JelleZijlstra
JelleZijlstra reviewed May 18, 2026
View reviewed changes
Comment thread Modules/_pickle.c
assert(self->proto > 0);

dict_size = PyDict_GET_SIZE(obj);
assert(dict_size);

@JelleZijlstra JelleZijlstra May 18, 2026

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

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.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

scopreon reacted with heart emoji
All reactions
  • ❤️ 1 reaction
JelleZijlstra
JelleZijlstra approved these changes May 18, 2026
View reviewed changes
@JelleZijlstra JelleZijlstra added needs backport to 3.14 bugs and security fixes needs backport to 3.15 bugs and security fixes labels May 18, 2026
@JelleZijlstra
JelleZijlstra merged commit 57a0e57 into python:main May 18, 2026
63 checks passed

Uh oh!

There was an error while loading. Please reload this page.

@miss-islington-app

miss-islington-app Bot commented May 18, 2026

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.
🐍🍒⛏🤖

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-app bedevere-app Bot removed the awaiting merge label May 18, 2026
@miss-islington-app

miss-islington-app Bot commented May 18, 2026

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
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@miss-islington-app miss-islington-app Bot assigned JelleZijlstra May 18, 2026
@bedevere-app

bedevere-app Bot commented May 18, 2026

Copy link
Copy Markdown

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

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-app bedevere-app Bot removed the needs backport to 3.15 bugs and security fixes label May 18, 2026
JelleZijlstra pushed a commit that referenced this pull request May 18, 2026
@miss-islington @scopreon
[3.15] gh-146452: Improve locking granularity in pickle's batch_dict_…
66ade28
…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 <[email protected]>
@scopreon scopreon mentioned this pull request May 19, 2026
[3.14] gh-146452: Improve locking granularity in pickle's batch_dict_… #150062
Merged
@bedevere-app

bedevere-app Bot commented May 19, 2026

Copy link
Copy Markdown

GH-150062 is a backport of this pull request to the 3.14 branch.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-app bedevere-app Bot removed the needs backport to 3.14 bugs and security fixes label May 19, 2026
JelleZijlstra pushed a commit that referenced this pull request May 19, 2026
@scopreon
[3.14] gh-146452: Improve locking granularity in pickle's batch_dict_… (
1243cd6
#150062)

[3.14] 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)
@vstinner

vstinner commented May 22, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

I propose to revert these changes, since they cause Out of Memory on the main branch when running test_free_threading.test_pickle. Because of that, the GitHub Action CI jobs fail with exit code 143 (issue gh-150114).

I don't think that this change is correct: sometimes (race condition), test_pickle_dumps_with_concurrent_dict_mutation() of test_free_threading.test_pickle enters an unlimited loop and exhaust the system memory. See the issue gh-150257.

The following code was added to _pickle to fix the crash gh-146452:

/* gh-146452: Wrap the dict iteration in a critical section to prevent
   concurrent mutation from invalidating PyDict_Next() iteration state. */
static int
batch_dict_exact(PickleState *state, PicklerObject *self, PyObject *obj)
{
    int ret;
    Py_BEGIN_CRITICAL_SECTION(obj);
    ret = batch_dict_exact_impl(state, self, obj);
    Py_END_CRITICAL_SECTION();
    return ret;
}

This PR replaces this function with "fine-grained sections".

Problem: Py_BEGIN_CRITICAL_SECTION(obj); and Py_END_CRITICAL_SECTION(); is put around a single PyDict_Next() call, whereas the PyDict_Next() documentation recommends putting the whole loop in the critical section.

By the way, the 3.15 backport of this PR is different since there was not batch_dict_exact_impl() function. Maybe a 3.15 backport of the previous fix was missed?

ngoldbaum reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@vstinner vstinner mentioned this pull request May 22, 2026
GitHub free threading CI failing with SIGTERM #150114
Closed
@vstinner

vstinner commented May 22, 2026

Copy link
Copy Markdown
Member

I prepared 3 reverts:

  • main: Revert "gh-146452: Improve locking granularity in pickle's batch_dict_exact and fix race condition (#150025)" #150261
  • 3.15: [3.15] Revert "[3.15] gh-146452: Improve locking granularity in pickle's batch_dict_exact and fix race condition (GH-150025) (#150039)" #150262
  • 3.14: [3.14] Revert "[3.14] gh-146452: Improve locking granularity in pickle's batch_dict_… (#150062)" #150263

Once the 3.15 revert will be merged, the commit e62a611 should be backported to the 3.15 branch.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@vstinner vstinner mentioned this pull request May 22, 2026
test_free_threading.test_pickle takes more than 4 minutes and consumes up to 22 GiB of memory #150257
Closed
vstinner added a commit that referenced this pull request May 22, 2026
@vstinner
Revert "gh-146452: Improve locking granularity in pickle's batch_dict…
b770b23
…_exact and fix race condition (#150025)" (#150261)

This reverts commit 57a0e57.
kumaraditya303 pushed a commit that referenced this pull request May 23, 2026
@vstinner
[3.15] Revert "[3.15] gh-146452: Improve locking granularity in pickl…
795dd3b
…e's batch_dict_exact and fix race condition (GH-150025) (#150039)" (#150262)

Revert "[3.15] gh-146452: Improve locking granularity in pickle's batch_dict_exact and fix race condition (GH-150025) (#150039)"

This reverts commit 66ade28.
@scopreon

scopreon commented May 23, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for spotting this regression @vstinner , and for the explanation. Sorry for overlooking that.

vstinner reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@JelleZijlstra JelleZijlstra JelleZijlstra approved these changes

Uh oh!

There was an error while loading. Please reload this page.

Assignees

@JelleZijlstra JelleZijlstra

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

3 participants

@scopreon @vstinner @JelleZijlstra
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.