Skip to content

Commit 06bb693

Browse files
committed
back to lock acquiring
1 parent 573d890 commit 06bb693

File tree

1 file changed

+18
-20
lines changed

1 file changed

+18
-20
lines changed

src/random.rs

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,11 @@ unsafe impl PyTypeInfo for PyBitGenerator {
9595
/// Methods for [`PyBitGenerator`].
9696
pub trait PyBitGeneratorMethods<'py> {
9797
/// Acquire a lock on the BitGenerator to allow calling its methods in.
98-
fn lock(&self) -> PyResult<PyBitGeneratorGuard<'py>>;
98+
fn lock(&self) -> PyResult<PyBitGeneratorGuard>;
9999
}
100100

101101
impl<'py> PyBitGeneratorMethods<'py> for Bound<'py, PyBitGenerator> {
102-
fn lock(&self) -> PyResult<PyBitGeneratorGuard<'py>> {
102+
fn lock(&self) -> PyResult<PyBitGeneratorGuard> {
103103
let capsule = self.getattr("capsule")?.downcast_into::<PyCapsule>()?;
104104
let lock = self.getattr("lock")?;
105105
if lock.call_method0("locked")?.extract()? {
@@ -120,48 +120,46 @@ impl<'py> PyBitGeneratorMethods<'py> for Bound<'py, PyBitGenerator> {
120120
raw_bitgen: non_null,
121121
_capsule: capsule.unbind(),
122122
lock: lock.unbind(),
123-
py: self.py(),
124123
})
125124
}
126125
}
127126

128-
impl<'py> TryFrom<&Bound<'py, PyBitGenerator>> for PyBitGeneratorGuard<'py> {
127+
impl<'py> TryFrom<&Bound<'py, PyBitGenerator>> for PyBitGeneratorGuard {
129128
type Error = PyErr;
130129
fn try_from(value: &Bound<'py, PyBitGenerator>) -> Result<Self, Self::Error> {
131130
value.lock()
132131
}
133132
}
134133

135134
/// [`PyBitGenerator`] lock allowing to access its methods without holding the GIL.
136-
pub struct PyBitGeneratorGuard<'py> {
135+
pub struct PyBitGeneratorGuard {
137136
raw_bitgen: NonNull<npy_bitgen>,
138137
/// This field makes sure the `raw_bitgen` inside the capsule doesn’t get deallocated.
139138
_capsule: Py<PyCapsule>,
140139
/// This lock makes sure no other threads try to use the BitGenerator while we do.
141140
lock: Py<PyAny>,
142-
/// This should be an unsafe field (https://github.com/rust-lang/rust/issues/132922)
143-
///
144-
/// SAFETY: only use this in `Drop::drop` (when we are sure the GIL is held).
145-
py: Python<'py>,
146141
}
147142

148143
// SAFETY: we can’t have public APIs that access the Python objects,
149144
// only the `raw_bitgen` pointer.
150-
unsafe impl Send for PyBitGeneratorGuard<'_> {}
145+
unsafe impl Send for PyBitGeneratorGuard {}
151146

152-
impl Drop for PyBitGeneratorGuard<'_> {
147+
impl Drop for PyBitGeneratorGuard {
153148
fn drop(&mut self) {
154-
// ignore errors. This includes when `try_drop` was called manually
155-
let _ = self.lock.bind(self.py).call_method0("release");
149+
// ignore errors. This includes when `try_release` was called manually.
150+
let _ = Python::with_gil(|py| -> PyResult<_> {
151+
self.lock.bind(py).call_method0("release")?;
152+
Ok(())
153+
});
156154
}
157155
}
158156

159157
// SAFETY: We hold the `BitGenerator.lock`,
160158
// so nothing apart from us is allowed to change its state.
161-
impl<'py> PyBitGeneratorGuard<'py> {
162-
/// Drop the lock manually before `Drop::drop` tries to do it (used for testing).
159+
impl<'py> PyBitGeneratorGuard {
160+
/// Release the lock, allowing for checking for errors.
163161
#[allow(dead_code)]
164-
fn try_drop(self, py: Python<'py>) -> PyResult<()> {
162+
pub fn try_release(self, py: Python<'py>) -> PyResult<()> {
165163
self.lock.bind(py).call_method0("release")?;
166164
Ok(())
167165
}
@@ -197,7 +195,7 @@ impl<'py> PyBitGeneratorGuard<'py> {
197195
}
198196

199197
#[cfg(feature = "rand")]
200-
impl rand::RngCore for PyBitGeneratorGuard<'_> {
198+
impl rand::RngCore for PyBitGeneratorGuard {
201199
fn next_u32(&mut self) -> u32 {
202200
self.next_uint32()
203201
}
@@ -229,7 +227,7 @@ mod tests {
229227
py.allow_threads(|| {
230228
let _ = bitgen.next_raw();
231229
});
232-
assert!(bitgen.try_drop(py).is_ok());
230+
assert!(bitgen.try_release(py).is_ok());
233231
Ok(())
234232
})
235233
}
@@ -278,7 +276,7 @@ mod tests {
278276
assert!(bitgen.random_ratio(1, 1));
279277
assert!(!bitgen.random_ratio(0, 1));
280278
});
281-
assert!(bitgen.try_drop(py).is_ok());
279+
assert!(bitgen.try_release(py).is_ok());
282280
Ok(())
283281
})
284282
}
@@ -289,7 +287,7 @@ mod tests {
289287
let generator = get_bit_generator(py)?;
290288
let bitgen = generator.lock()?;
291289
assert!(generator.lock().is_err());
292-
assert!(bitgen.try_drop(py).is_ok());
290+
assert!(bitgen.try_release(py).is_ok());
293291
Ok(())
294292
})
295293
}

0 commit comments

Comments
 (0)