##// END OF EJS Templates
rust-cpython: mark unsafe functions as such...
Yuya Nishihara -
r43117:64e28b89 default
parent child Browse files
Show More
@@ -86,7 +86,7 b' py_class!(pub class Dirs |py| {'
86 })
86 })
87 }
87 }
88 def __iter__(&self) -> PyResult<DirsMultisetKeysIterator> {
88 def __iter__(&self) -> PyResult<DirsMultisetKeysIterator> {
89 let (leak_handle, leaked_ref) = self.leak_immutable(py)?;
89 let (leak_handle, leaked_ref) = unsafe { self.leak_immutable(py)? };
90 DirsMultisetKeysIterator::create_instance(
90 DirsMultisetKeysIterator::create_instance(
91 py,
91 py,
92 RefCell::new(Some(leak_handle)),
92 RefCell::new(Some(leak_handle)),
@@ -319,7 +319,7 b' py_class!(pub class DirstateMap |py| {'
319 }
319 }
320
320
321 def keys(&self) -> PyResult<DirstateMapKeysIterator> {
321 def keys(&self) -> PyResult<DirstateMapKeysIterator> {
322 let (leak_handle, leaked_ref) = self.leak_immutable(py)?;
322 let (leak_handle, leaked_ref) = unsafe { self.leak_immutable(py)? };
323 DirstateMapKeysIterator::from_inner(
323 DirstateMapKeysIterator::from_inner(
324 py,
324 py,
325 Some(leak_handle),
325 Some(leak_handle),
@@ -328,7 +328,7 b' py_class!(pub class DirstateMap |py| {'
328 }
328 }
329
329
330 def items(&self) -> PyResult<DirstateMapItemsIterator> {
330 def items(&self) -> PyResult<DirstateMapItemsIterator> {
331 let (leak_handle, leaked_ref) = self.leak_immutable(py)?;
331 let (leak_handle, leaked_ref) = unsafe { self.leak_immutable(py)? };
332 DirstateMapItemsIterator::from_inner(
332 DirstateMapItemsIterator::from_inner(
333 py,
333 py,
334 Some(leak_handle),
334 Some(leak_handle),
@@ -337,7 +337,7 b' py_class!(pub class DirstateMap |py| {'
337 }
337 }
338
338
339 def __iter__(&self) -> PyResult<DirstateMapKeysIterator> {
339 def __iter__(&self) -> PyResult<DirstateMapKeysIterator> {
340 let (leak_handle, leaked_ref) = self.leak_immutable(py)?;
340 let (leak_handle, leaked_ref) = unsafe { self.leak_immutable(py)? };
341 DirstateMapKeysIterator::from_inner(
341 DirstateMapKeysIterator::from_inner(
342 py,
342 py,
343 Some(leak_handle),
343 Some(leak_handle),
@@ -434,7 +434,7 b' py_class!(pub class DirstateMap |py| {'
434 }
434 }
435
435
436 def copymapiter(&self) -> PyResult<CopyMapKeysIterator> {
436 def copymapiter(&self) -> PyResult<CopyMapKeysIterator> {
437 let (leak_handle, leaked_ref) = self.leak_immutable(py)?;
437 let (leak_handle, leaked_ref) = unsafe { self.leak_immutable(py)? };
438 CopyMapKeysIterator::from_inner(
438 CopyMapKeysIterator::from_inner(
439 py,
439 py,
440 Some(leak_handle),
440 Some(leak_handle),
@@ -443,7 +443,7 b' py_class!(pub class DirstateMap |py| {'
443 }
443 }
444
444
445 def copymapitemsiter(&self) -> PyResult<CopyMapItemsIterator> {
445 def copymapitemsiter(&self) -> PyResult<CopyMapItemsIterator> {
446 let (leak_handle, leaked_ref) = self.leak_immutable(py)?;
446 let (leak_handle, leaked_ref) = unsafe { self.leak_immutable(py)? };
447 CopyMapItemsIterator::from_inner(
447 CopyMapItemsIterator::from_inner(
448 py,
448 py,
449 Some(leak_handle),
449 Some(leak_handle),
@@ -58,7 +58,12 b' impl PySharedState {'
58 /// Return a reference to the wrapped data with an artificial static
58 /// Return a reference to the wrapped data with an artificial static
59 /// lifetime.
59 /// lifetime.
60 /// We need to be protected by the GIL for thread-safety.
60 /// We need to be protected by the GIL for thread-safety.
61 pub fn leak_immutable<T>(
61 ///
62 /// # Safety
63 ///
64 /// This is highly unsafe since the lifetime of the given data can be
65 /// extended. Do not call this function directly.
66 pub unsafe fn leak_immutable<T>(
62 &self,
67 &self,
63 py: Python,
68 py: Python,
64 data: &PySharedRefCell<T>,
69 data: &PySharedRefCell<T>,
@@ -72,10 +77,14 b' impl PySharedState {'
72 }
77 }
73 let ptr = data.as_ptr();
78 let ptr = data.as_ptr();
74 self.leak_count.replace(self.leak_count.get() + 1);
79 self.leak_count.replace(self.leak_count.get() + 1);
75 unsafe { Ok(&*ptr) }
80 Ok(&*ptr)
76 }
81 }
77
82
78 pub fn decrease_leak_count(&self, _py: Python, mutable: bool) {
83 /// # Safety
84 ///
85 /// It's unsafe to update the reference count without knowing the
86 /// reference is deleted. Do not call this function directly.
87 pub unsafe fn decrease_leak_count(&self, _py: Python, mutable: bool) {
79 self.leak_count
88 self.leak_count
80 .replace(self.leak_count.get().saturating_sub(1));
89 .replace(self.leak_count.get().saturating_sub(1));
81 if mutable {
90 if mutable {
@@ -123,6 +132,8 b" pub struct PyRefMut<'a, T> {"
123 }
132 }
124
133
125 impl<'a, T> PyRefMut<'a, T> {
134 impl<'a, T> PyRefMut<'a, T> {
135 // Must be constructed by PySharedState after checking its leak_count.
136 // Otherwise, drop() would incorrectly update the state.
126 fn new(
137 fn new(
127 _py: Python<'a>,
138 _py: Python<'a>,
128 inner: RefMut<'a, T>,
139 inner: RefMut<'a, T>,
@@ -152,7 +163,9 b" impl<'a, T> Drop for PyRefMut<'a, T> {"
152 fn drop(&mut self) {
163 fn drop(&mut self) {
153 let gil = Python::acquire_gil();
164 let gil = Python::acquire_gil();
154 let py = gil.python();
165 let py = gil.python();
155 self.py_shared_state.decrease_leak_count(py, true);
166 unsafe {
167 self.py_shared_state.decrease_leak_count(py, true);
168 }
156 }
169 }
157 }
170 }
158
171
@@ -223,7 +236,7 b' macro_rules! py_shared_ref {'
223 /// It's up to you to make sure that the management object lives
236 /// It's up to you to make sure that the management object lives
224 /// longer than the leaked reference. Otherwise, you'll get a
237 /// longer than the leaked reference. Otherwise, you'll get a
225 /// dangling reference.
238 /// dangling reference.
226 fn leak_immutable<'a>(
239 unsafe fn leak_immutable<'a>(
227 &'a self,
240 &'a self,
228 py: Python<'a>,
241 py: Python<'a>,
229 ) -> PyResult<($leaked, &'static $inner_struct)> {
242 ) -> PyResult<($leaked, &'static $inner_struct)> {
@@ -247,7 +260,9 b' macro_rules! py_shared_ref {'
247 }
260 }
248
261
249 impl $leaked {
262 impl $leaked {
250 fn new(py: Python, inner: &$name) -> Self {
263 // Marked as unsafe so client code wouldn't construct $leaked
264 // struct by mistake. Its drop() is unsafe.
265 unsafe fn new(py: Python, inner: &$name) -> Self {
251 Self {
266 Self {
252 inner: inner.clone_ref(py),
267 inner: inner.clone_ref(py),
253 }
268 }
@@ -258,9 +273,10 b' macro_rules! py_shared_ref {'
258 fn drop(&mut self) {
273 fn drop(&mut self) {
259 let gil = Python::acquire_gil();
274 let gil = Python::acquire_gil();
260 let py = gil.python();
275 let py = gil.python();
261 self.inner
276 let state = self.inner.py_shared_state(py);
262 .py_shared_state(py)
277 unsafe {
263 .decrease_leak_count(py, false);
278 state.decrease_leak_count(py, false);
279 }
264 }
280 }
265 }
281 }
266 };
282 };
@@ -346,7 +362,7 b' macro_rules! py_shared_iterator_impl {'
346 /// data py_shared_state: PySharedState;
362 /// data py_shared_state: PySharedState;
347 ///
363 ///
348 /// def __iter__(&self) -> PyResult<MyTypeItemsIterator> {
364 /// def __iter__(&self) -> PyResult<MyTypeItemsIterator> {
349 /// let (leak_handle, leaked_ref) = self.leak_immutable(py)?;
365 /// let (leak_handle, leaked_ref) = unsafe { self.leak_immutable(py)? };
350 /// MyTypeItemsIterator::create_instance(
366 /// MyTypeItemsIterator::create_instance(
351 /// py,
367 /// py,
352 /// RefCell::new(Some(leak_handle)),
368 /// RefCell::new(Some(leak_handle)),
General Comments 0
You need to be logged in to leave comments. Login now