-
-
Notifications
You must be signed in to change notification settings - Fork 32.1k
Crash when calling textiowrapper_iternext
and writing to a text file simultaneously in ft build
#134908
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
Comments
…tion ``textiowrapper_iternext`` calls ``_textiowrapper_writeflush`` but does not take the critical section, making it racy in free-threaded builds.
I'm pretty sure we don't support concurrent calls to |
That is a very interesting discussion, thanks for linking!
I totally agree that in general iterators should not be assumed to be thread-safe, in the broader sense. However they should not crash, which is happening here. In the description I reported an assertion failure, but the repro script will crash with assertions disabled too, just in more "interesting" ways. |
You can get similar crashes from pure-Python by concurrently calling an object's |
I'm sure there are places where fixing crashes without substantially hurting performance might be difficult or impossible, but I don't think this is one of them. It should have no impact on GIL performance and minimal in free-threading. The third bullet point in #124397 is:
I think this fix is exactly that...or at least, that was exactly what I intended when I wrote it. Of course, I may well have missed something! |
I'll let others weigh in here, but my personal stance is that concurrent iteration without synchronization by the caller is not a real use-case. The example you sent would suffer from so much lock contention that it would be no better than calling it in a single thread :( I think that last point is in regards to making the iterator thread-safe when others are calling separate methods on it, not necessarily concurrent calls to |
From looking at the repro code, this looks like something we should fix. |
Ok, thanks Sam. For clarity: when should we fix these cases? |
This looks like concurrent operations on a NamedTemporaryFile. I think I/O should generally be internally synchronized. That's mostly true for Python already, it's usually true at the OS level, as well as in other language runtimes. I get that there is a crash in iteration, but it doesn't look like there's an iterator shared between threads. |
The |
Thanks. That still feels pretty different from list and dict iterators. For one thing, it'd be difficult to make list and dict iterators thread-safe without slowing down the common case substantially. I don't think that's the case here. The iteration interface just provides access to readline, which is already synchronized. I think there's a difference between objects like NamedTemporaryFile that provide an iteration interface and objects like list_iterator, which are usually temporary objects that you don't think about and rarely store to variables. |
Ok, that makes sense to me. |
…-134910) The `textiowrapper_iternext` function called `_textiowrapper_writeflush`, but did not use a critical section, making it racy in free-threaded builds.
…on (pythongh-134910) The `textiowrapper_iternext` function called `_textiowrapper_writeflush`, but did not use a critical section, making it racy in free-threaded builds. (cherry picked from commit 44fb7c3) Co-authored-by: Duane Griffin <duaneg@dghda.com>
…l section (pythongh-134910) The `textiowrapper_iternext` function called `_textiowrapper_writeflush`, but did not use a critical section, making it racy in free-threaded builds. (cherry picked from commit 44fb7c3) Co-authored-by: Duane Griffin <duaneg@dghda.com>
…l section (pythongh-134910) The `textiowrapper_iternext` function called `_textiowrapper_writeflush`, but did not use a critical section, making it racy in free-threaded builds. (cherry picked from commit 44fb7c3) Co-authored-by: Duane Griffin <duaneg@dghda.com>
Uh oh!
There was an error while loading. Please reload this page.
Running this script under free-threading build:
...results in a crash:
The
textiowrapper_iternext
method is not protected by a critical section and calls_textiowrapper_readline
, which calls_textiowrapper_writeflush
, which relies on the GIL or critical section to synchronise access to its internal data. In a free-threading build this means iterating over lines in a text file is not thread-safe and can crash if it races with writes or other operations.It looks like all other entry points that could call
_textiowrapper_writeflush
are protected by the critical section, so the easiest fix is probably to just likewise protecttextiowrapper_iternext
.CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux
Output from running 'python -VV' on the command line:
No response
Linked PRs
textiowrapper_iternext
with critical section #134910textiowrapper_iternext
with critical section (gh-134910) #135039textiowrapper_iternext
with critical section (gh-134910) #135040The text was updated successfully, but these errors were encountered: