-
-
Notifications
You must be signed in to change notification settings - Fork 31.9k
bpo-34410: itertools.tee not thread-safe; can segfault #9254
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
Conversation
Related PR with locking approach : #9075 Thanks |
In addition, users should ensure that the critical section is thread-safe on their own python code. The patch make tee to traverse each element returned by PyIter_Next. But if the elements returned in
Here
|
Serhiy, would you please take a look at this? |
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.
Please add a NEWS entry.
This approach can fix a crash, but it can lead to emitting items out of order (e.g. 1, 2, 4, 3, ...). This should be explicitly documented in the documentation of tee()
.
Also an exception can be raised even if there are cached values. For example, the original iterator emits 1, 2, and then raise an error. In thread A you get 1, then in thread B you get 1 and 2, then in thread A you get an error instead of 2.
Modules/itertoolsmodule.c
Outdated
|
||
if (value != NULL) { | ||
teedataobject *temp = tdo; | ||
while (temp->numread + 1 > LINKCELLS) { |
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.
while (temp->numread + 1 > LINKCELLS) { | |
while (temp->numread >= LINKCELLS) { |
Modules/itertoolsmodule.c
Outdated
} | ||
temp->values[temp->numread] = value; | ||
temp->numread++; | ||
}else if (i == tdo->numread) { |
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.
}else if (i == tdo->numread) { | |
} | |
else if (i == tdo->numread || PyErr_Occurred()) { |
Closing in favor of PR 15567 |
This is a resolution without lock. I think it's not right in the demo
3.py
, because it will use the original iterable inimap_unordered -> _guarded_task_generation
.imap_unordered_demo.py
https://bugs.python.org/issue34410