rust/hg-cpython/src/ref_sharing.rs
changeset 44188 1f9e6fbdd3e6
parent 43430 8418b77132c1
child 44189 4a4c3b9fd91b
equal deleted inserted replaced
44187:be52b7372ec2 44188:1f9e6fbdd3e6
   281 ///
   281 ///
   282 /// This reference will be invalidated once the original value is mutably
   282 /// This reference will be invalidated once the original value is mutably
   283 /// borrowed.
   283 /// borrowed.
   284 pub struct PyLeaked<T> {
   284 pub struct PyLeaked<T> {
   285     inner: PyObject,
   285     inner: PyObject,
   286     data: Option<T>,
   286     data: T,
   287     py_shared_state: &'static PySharedState,
   287     py_shared_state: &'static PySharedState,
   288     /// Generation counter of data `T` captured when PyLeaked is created.
   288     /// Generation counter of data `T` captured when PyLeaked is created.
   289     generation: usize,
   289     generation: usize,
   290 }
   290 }
   291 
   291 
   303         data: T,
   303         data: T,
   304         py_shared_state: &'static PySharedState,
   304         py_shared_state: &'static PySharedState,
   305     ) -> Self {
   305     ) -> Self {
   306         Self {
   306         Self {
   307             inner: inner.clone_ref(py),
   307             inner: inner.clone_ref(py),
   308             data: Some(data),
   308             data: data,
   309             py_shared_state,
   309             py_shared_state,
   310             generation: py_shared_state.current_generation(py),
   310             generation: py_shared_state.current_generation(py),
   311         }
   311         }
   312     }
   312     }
   313 
   313 
   319         py: Python<'a>,
   319         py: Python<'a>,
   320     ) -> PyResult<PyLeakedRef<'a, T>> {
   320     ) -> PyResult<PyLeakedRef<'a, T>> {
   321         self.validate_generation(py)?;
   321         self.validate_generation(py)?;
   322         Ok(PyLeakedRef {
   322         Ok(PyLeakedRef {
   323             _borrow: BorrowPyShared::new(py, self.py_shared_state),
   323             _borrow: BorrowPyShared::new(py, self.py_shared_state),
   324             data: self.data.as_ref().unwrap(),
   324             data: &self.data,
   325         })
   325         })
   326     }
   326     }
   327 
   327 
   328     /// Mutably borrows the wrapped value.
   328     /// Mutably borrows the wrapped value.
   329     ///
   329     ///
   336         py: Python<'a>,
   336         py: Python<'a>,
   337     ) -> PyResult<PyLeakedRefMut<'a, T>> {
   337     ) -> PyResult<PyLeakedRefMut<'a, T>> {
   338         self.validate_generation(py)?;
   338         self.validate_generation(py)?;
   339         Ok(PyLeakedRefMut {
   339         Ok(PyLeakedRefMut {
   340             _borrow: BorrowPyShared::new(py, self.py_shared_state),
   340             _borrow: BorrowPyShared::new(py, self.py_shared_state),
   341             data: self.data.as_mut().unwrap(),
   341             data: &mut self.data,
   342         })
   342         })
   343     }
   343     }
   344 
   344 
   345     /// Converts the inner value by the given function.
   345     /// Converts the inner value by the given function.
   346     ///
   346     ///
   359     /// The lifetime of the object passed in to the function `f` is cheated.
   359     /// The lifetime of the object passed in to the function `f` is cheated.
   360     /// It's typically a static reference, but is valid only while the
   360     /// It's typically a static reference, but is valid only while the
   361     /// corresponding `PyLeaked` is alive. Do not copy it out of the
   361     /// corresponding `PyLeaked` is alive. Do not copy it out of the
   362     /// function call.
   362     /// function call.
   363     pub unsafe fn map<U>(
   363     pub unsafe fn map<U>(
   364         mut self,
   364         self,
   365         py: Python,
   365         py: Python,
   366         f: impl FnOnce(T) -> U,
   366         f: impl FnOnce(T) -> U,
   367     ) -> PyLeaked<U> {
   367     ) -> PyLeaked<U> {
   368         // Needs to test the generation value to make sure self.data reference
   368         // Needs to test the generation value to make sure self.data reference
   369         // is still intact.
   369         // is still intact.
   372 
   372 
   373         // f() could make the self.data outlive. That's why map() is unsafe.
   373         // f() could make the self.data outlive. That's why map() is unsafe.
   374         // In order to make this function safe, maybe we'll need a way to
   374         // In order to make this function safe, maybe we'll need a way to
   375         // temporarily restrict the lifetime of self.data and translate the
   375         // temporarily restrict the lifetime of self.data and translate the
   376         // returned object back to Something<'static>.
   376         // returned object back to Something<'static>.
   377         let new_data = f(self.data.take().unwrap());
   377         let new_data = f(self.data);
   378         PyLeaked {
   378         PyLeaked {
   379             inner: self.inner.clone_ref(py),
   379             inner: self.inner,
   380             data: Some(new_data),
   380             data: new_data,
   381             py_shared_state: self.py_shared_state,
   381             py_shared_state: self.py_shared_state,
   382             generation: self.generation,
   382             generation: self.generation,
   383         }
   383         }
   384     }
   384     }
   385 
   385