-
-
Notifications
You must be signed in to change notification settings - Fork 32.1k
bpo-31356: Fix multiple errors in gc.ensure_disabled() #5462
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
cc @lisroach |
@ned-deily If there's time, when this one is reviewed by @lisroach and @serhiy-storchaka it would be great if it gets merged into beta-1. Currently, running |
Modules/gcmodule.c
Outdated
|
||
if (ret == NULL) { | ||
return NULL; | ||
} |
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.
Don't you have to DECREF somewhere? Try: ./python -m test -R 3:3 test_gc
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.
Good catch; fixed.
cc @pablogsal |
I don't understand the "test_ensure_disabled_thread" test: why is |
Why are we using |
@@ -1530,8 +1535,13 @@ ensure_disabled__enter__method(ensure_disabled_object *self, PyObject *args) | |||
PyGILState_STATE gstate = PyGILState_Ensure(); | |||
++_PyRuntime.gc.disabled_threads; | |||
self->previous_gc_state = _PyRuntime.gc.enabled; | |||
gc_disable_impl(NULL); | |||
|
|||
PyObject *ret = gc_disable_impl(NULL); | |||
PyGILState_Release(gstate); |
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.
@serhiy-storchaka Do you understand this PyGILState_Release
call? Isn't it unsafe to execute Python/CAPI code after it?
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.
here and below, the
PyGILState_Release(gstate);
if (ret == NULL) {
return NULL;
}
Py_DECREF(ret);
blocks should be replaced with
Py_XDECREF(ret);
PyGILState_Release(gstate);
if (ret == NULL) {
return NULL;
}
The GIL must be held for the decref.
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.
But this is a Python API! So we release the gil inside with ensure_disabled()
. Why?
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.
I didn't review the initial changes and know nothing about the correctness of other code. I'll check it carefully after beta1.
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.
IMO this is just plain wrong.
thread = threading.Thread(target=disabling_thread) | ||
thread.start() | ||
inside_status_after_thread = gc.isenabled() | ||
with self.assertWarnsRegex(RuntimeWarning, "enabled while another"): |
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.
What line emits a warning? It would be better to surround with assertWarnsRegex() only that line. Or it can be emitted by arbitrary line in the block?
Note that warnings emitted in other thread are not caught here.
@@ -1068,8 +1068,13 @@ gc_enable_impl(PyObject *module) | |||
/*[clinic end generated code: output=45a427e9dce9155c input=81ac4940ca579707]*/ | |||
{ | |||
if(_PyRuntime.gc.disabled_threads){ |
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 fix the style of this line too.
} | ||
PyGILState_Release(gstate); | ||
if (ret == NULL) { | ||
return NULL; |
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.
Maybe it would be better to chain exceptions, but this is an additional non-trivial code. We can do this in beta2.
@@ -1068,8 +1068,13 @@ gc_enable_impl(PyObject *module) | |||
/*[clinic end generated code: output=45a427e9dce9155c input=81ac4940ca579707]*/ | |||
{ | |||
if(_PyRuntime.gc.disabled_threads){ |
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 fix the style of this line too.
if (ret == NULL) { | ||
return NULL; | ||
} | ||
Py_DECREF(ret); |
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.
You could just return ret
.
@1st1 Sorry, 3.7.0b1 is finished. Unless there is a consensus that this needs an emergency fix because 3.7.0b1 is unusable, it will have to wait for the scheduled release of 3.7.0b2 in 4 weeks. |
@@ -1530,8 +1535,13 @@ ensure_disabled__enter__method(ensure_disabled_object *self, PyObject *args) | |||
PyGILState_STATE gstate = PyGILState_Ensure(); | |||
++_PyRuntime.gc.disabled_threads; | |||
self->previous_gc_state = _PyRuntime.gc.enabled; | |||
gc_disable_impl(NULL); | |||
|
|||
PyObject *ret = gc_disable_impl(NULL); | |||
PyGILState_Release(gstate); |
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.
here and below, the
PyGILState_Release(gstate);
if (ret == NULL) {
return NULL;
}
Py_DECREF(ret);
blocks should be replaced with
Py_XDECREF(ret);
PyGILState_Release(gstate);
if (ret == NULL) {
return NULL;
}
The GIL must be held for the decref.
When you're done making the requested changes, leave the comment: |
@serhiy-storchaka @gpshead Can you explain this ^^? |
@ned-deily Can you run |
Moreover, currently |
@ned-deily Sure. See new comments from Serhiy and me in the issue. |
Closing this one as it was decided that we'll simply revert the original PR instead of fixing it. Thanks! |
https://bugs.python.org/issue31356