-
-
Notifications
You must be signed in to change notification settings - Fork 32.1k
bpo-43441: fix [Subinterpreters]: global variable next_version_tag cause method cache bug #24822
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
bpo-43441: fix [Subinterpreters]: global variable next_version_tag cause method cache bug #24822
Conversation
@@ -285,9 +285,9 @@ PyType_ClearCache(void) | |||
void | |||
_PyType_Fini(PyInterpreterState *interp) | |||
{ | |||
_PyType_ClearCache(&interp->type_cache); |
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.
This change leaks memory: type_cache_clear() clears objects and should be done in subinterpreters.
I suggest to pass interp to _PyType_ClearCache() and check _Py_IsMainInterpreter(interp)
in this function to decide if next_version_tag must be modified or not.
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.
Thank you for your review, it is very reasonable. I have made the changes as you suggested.
A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated. Once you have made the requested changes, please leave a comment on this pull request containing the phrase And if you don't make the requested changes, you will be poked with soft cushions! |
I have made the requested changes; please review again |
Thanks for making the requested changes! @vstinner: please review the changes made to this pull request. |
@@ -0,0 +1 @@ | |||
under building Python with --with-experimental-isolated-subinterpreters, fix method cache mess cause by global variable next_version_tag and sub interpreter destory clear type method cache. |
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 remove the NEWS entry. I would prefer to keep --with-experimental-isolated-subinterpreters feature secret on purpose. It's still experimental (and broken).
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.
Okay, thanks for the hint.
@vstinner Thank you for your code review, I have removed the news. But I don't know how to make |
Objects/typeobject.c
Outdated
@@ -252,7 +252,7 @@ _PyType_InitCache(PyInterpreterState *interp) | |||
|
|||
|
|||
static unsigned int | |||
_PyType_ClearCache(struct type_cache *cache) | |||
_PyType_ClearCache(PyInterpreterState *interp, struct type_cache *cache) |
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.
Hum, the cache parameter sounds redundant. Please remove it and get the cache with:
struct type_cache *cache = &interp->type_cache;
So you can remove struct type_cache *cache = get_type_cache();
in PyType_ClearCache().
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.
Thanks vstinner, good suggestion.
I have made the requested changes; please review again |
Thanks for making the requested changes! @vstinner: please review the changes made to this pull request. |
@@ -267,7 +268,10 @@ _PyType_ClearCache(struct type_cache *cache) | |||
#endif | |||
|
|||
unsigned int cur_version_tag = next_version_tag - 1; | |||
next_version_tag = 0; | |||
if (_Py_IsMainInterpreter(interp)) { | |||
next_version_tag = 0; |
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.
It would be safer to have a per-interpreter next_version_tag. The problem is that there are still many static types which are shared between interpreters :-/ You may add a comment explaining that:
// bpo-42745: next_version_tag remains shared by all interpreters because of static types
Or put the comment on the variable definition:
// Used to set PyTypeObject.tp_version_tag
static unsigned int next_version_tag = 0;
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.
Thanks, ok i added
…ause method cache bug
I have made the requested changes; please review again |
Thanks for making the requested changes! @vstinner: please review the changes made to this pull request. |
I pushed my last requested change and I merged your PR, thanks for the fix. |
under building Python with --with-experimental-isolated-subinterpreters
when sub interpreter finalize.
_PyType_ClearCache
set next_version_tag = 0.Type shared between interpreters.
another interpreter assign_version_tag "1" for a type, the type is first assign.
the dealloc interpreter had assign_version_tag "1" for another type.
now, two different type has same version tag. it cause method cache wrong.
https://bugs.python.org/issue43441