Skip to content

Builtin zip method is not safe under free-threading #123271

@eendebakpt

Description

@eendebakpt

Bug report

Bug description:

A common optimization technique (used in zip_next) for methods generating tuples is to keep an internal reference to the returned tuple and when the method is called again check whether the internal tuple has reference count 1. If the refcount is one, the tuple can be re-used. Under the free-threading build this is not safe: after the check on the reference count another thread can perform the same check and also re-use the tuple. This can lead to a double decref on the items of the tuple replaced and a double incref (memory leak) on the items of the tuple being set.

Some options to address this:

  • Stop the internal tracking of the tuple. This affects performance of zip when the tuple can be re-used
  • Lock the entire zip object during a call to zip_next. This is expensive, also for the single-threaded case.
  • Use an atomic "check refcount equals one and conditionally increment" method. This could be less expensive than locking the entire object, but maybe this method is not available or almost as expensive as locking the object.

A minimal example reproducing the issue is added as a test in #123272. It shows the issue when executed with a free-threading debug build.

CPython versions tested on:

CPython main branch

Operating systems tested on:

Windows

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions