-
Notifications
You must be signed in to change notification settings - Fork 1.3k
CPython compatible Drop for PyObjectRc #2128
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
3bc9b78
to
6b479e1
Compare
I'm wondering if it would be better/simpler to define struct PyObjectRc {
inner: Arc<...>
}
impl Drop for PyObjectRc {
fn drop(&mut self) {
if self.inner.strong_count() == 1 {
// call __del__
}
// drop Arc
}
} The only problem i see with this is that there is a race condition if two references are dropped at the same time, but I think a lock(possibly a global lock) just needs to be added to ensure the drop of the Arc and checking of strong count are atomic. But we only need to do that if the object has a del method in the first place. |
Yeah, that's what I was thinking -- we could put a |
@Skinny121 thanks, idk why I didn't think there must be public interface for that. |
The key would be for ManuallyDrop::take(); I don't think it's really feasible to use the thread local VM and call |
And even if we do go with the thread local VM, it's tricky to call Edit: Nevermind, that would probably lead to issues with infinitely recurring into a destructor |
Ok, I got what you meant about ManuallyDrop. About
The thread_local problem: I don't know well about vm, gc and their performance that much. I believe there is an opportunity of better performance for collecting and release. I am thinking of making RustPython as a drop-in-replacement of CPython. One of the common problem is resource releasing timing. Some (wrong) python code is depending of CPython's drop timing, which only can simulated by calling |
6a00126
to
2ea0553
Compare
2ea0553
to
bc02c5f
Compare
ff0b199
to
a3d1d18
Compare
93e8cfd
to
06bc718
Compare
06bc718
to
6eb5daf
Compare
Ah, it's an issue with stuff being dropped while in |
@Skinny121 what do you think? |
vm/src/import.rs
Outdated
@@ -14,45 +14,57 @@ use crate::vm::{InitParameter, VirtualMachine}; | |||
#[cfg(feature = "rustpython-compiler")] | |||
use rustpython_compiler::compile; | |||
|
|||
pub fn init_importlib(vm: &mut VirtualMachine, initialize_parameter: InitParameter) -> PyResult { | |||
pub fn init_importlib( |
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 is receiving vm
as an argument but requries to call enter_vm
. this is only called in initialization step, so it will not make any problem. but this is making a bit uncomfortable feeling.
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.
Should I make init_importlib pub(crate)
?
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.
And yeah, that's definitely a tricky part, I original wanted to have init_importlib take a &vm
, but then it wouldn't be able to set vm.import_func
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 think about pub(crate)
at that time, but it looks like to be. Even if there is a need to manally init importlib, it must be a method of vm or interpreter rather than this kind of function. I think we'd better to list up pub apis. Sometimes internal stuffs are marked as pub just to be shared in the crate.
@@ -1537,29 +1577,76 @@ impl<'vm> Drop for ReprGuard<'vm> { | |||
} | |||
} | |||
|
|||
pub struct Interpreter { |
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.
does Interpreter matche to vm 1-to-1 relationship or is there any other usage of vm?
If it is 1-to-1, I don't feel like we really need a new type for that; we only need the new methods.
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.
The separate struct is so that you can't access the VM except through putting it in the VM stack, otherwise, it wouldn't be guaranteed that the VM would be in stack while using 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.
In that case, will there be any difference if we put interpreters in VM stack instead of VMs?
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 initially did that, but then it was tricky passing an Interpreter to initialize(&mut interp.vm, &interp)
. Definitely could make it happen though, especially if we're making init_importlib crate-private
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.
ah, got it. interface visibility is a good reason.
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 actually feels like a 1-to-n relationship as each thread has it's own vm.
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 seems each thread has its own vm and also its own interpreter. so still vm and interpreter is 1-to-1.
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 was originally thinking that Interpreter would cover all vms across threads for that interpreter instance; like it could have a thread-local value to hold the vm, and it could be Send+Sync and whichever thread you called it from it would get that thread's vm, but I'm not sure how actually useful that would be.
Looks pretty good. |
I added another commit to rework vm initialization a bit; not sure if it's totally on-topic but I think it makes more sense with how the |
ff465b8
to
654ab56
Compare
654ab56
to
c7f5da6
Compare
Should we merge this? |
If the design is good enough, let's go and fix remained problems later. this pr is growing bigger. bigger patch will cause more frequent conflicts for other PRs |
I think the comments here is related to #1940 |
No description provided.