(py: Python<'py>)
| 119 | |
| 120 | #[cold] |
| 121 | fn insert_shared<'py>(py: Python<'py>) -> PyResult<NonNull<Shared>> { |
| 122 | let module = get_array_module(py)?; |
| 123 | |
| 124 | let capsule = match module.getattr("_RUST_NUMPY_BORROW_CHECKING_API") { |
| 125 | Ok(capsule) => capsule.cast_into::<PyCapsule>()?, |
| 126 | Err(_err) => { |
| 127 | let flags: *mut BorrowFlags = Box::into_raw(Box::default()); |
| 128 | |
| 129 | let shared = Shared { |
| 130 | version: 1, |
| 131 | flags: flags as *mut c_void, |
| 132 | acquire: acquire_shared, |
| 133 | acquire_mut: acquire_mut_shared, |
| 134 | release: release_shared, |
| 135 | release_mut: release_mut_shared, |
| 136 | }; |
| 137 | |
| 138 | let capsule = PyCapsule::new_with_value_and_destructor( |
| 139 | py, |
| 140 | shared, |
| 141 | c"_RUST_NUMPY_BORROW_CHECKING_API", |
| 142 | |shared, _ctx| { |
| 143 | // SAFETY: `shared.flags` was initialized using `Box::into_raw`. |
| 144 | let _ = unsafe { Box::from_raw(shared.flags as *mut BorrowFlags) }; |
| 145 | }, |
| 146 | )?; |
| 147 | module.setattr("_RUST_NUMPY_BORROW_CHECKING_API", &capsule)?; |
| 148 | capsule |
| 149 | } |
| 150 | }; |
| 151 | |
| 152 | // SAFETY: All versions of the shared borrow checking API start with a version field. |
| 153 | let version = unsafe { |
| 154 | *capsule |
| 155 | .pointer_checked(Some(c_str!("_RUST_NUMPY_BORROW_CHECKING_API")))? |
| 156 | .cast::<u64>() |
| 157 | .as_ptr() // FIXME(icxolu): use read on MSRV 1.80 |
| 158 | }; |
| 159 | if version < 1 { |
| 160 | return Err(PyTypeError::new_err(format!( |
| 161 | "Version {version} of borrow checking API is not supported by this version of rust-numpy" |
| 162 | ))); |
| 163 | } |
| 164 | |
| 165 | let ptr = capsule.pointer_checked(Some(c_str!("_RUST_NUMPY_BORROW_CHECKING_API")))?; |
| 166 | |
| 167 | // Intentionally leak a reference to the capsule |
| 168 | // so we can safely cache a pointer into its interior. |
| 169 | forget(capsule); |
| 170 | |
| 171 | Ok(ptr.cast()) |
| 172 | } |
| 173 | |
| 174 | // These entry points will be used to access the shared borrow checking API from this extension: |
| 175 |
no test coverage detected