Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork33.7k
Closed
Description
Running this script under free-threading build:
importosimporttempfileimportthreadingN=2COUNT=100defwriter(file,barrier):barrier.wait()for_inrange(COUNT):f.write("x")defreader(file,stopping):whilenotstopping.is_set():forlineinfile:assertline==""stopping=threading.Event()withtempfile.NamedTemporaryFile("w+")asf:reader=threading.Thread(target=reader,args=(f,stopping))reader.start()barrier=threading.Barrier(N)writers= [threading.Thread(target=writer,args=(f,barrier))for_inrange(N)]fortinwriters:t.start()fortinwriters:t.join()stopping.set()reader.join()f.flush()assert(os.stat(f.name).st_size==COUNT*N)
...results in a crash:
python: ./Modules/_io/textio.c:1751: _io_TextIOWrapper_write_impl: Assertion `self->pending_bytes_count == 0' failed.Aborted (core dumped)Thetextiowrapper_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