|
1 | 1 | //! Interaction with Python's global interpreter lock |
2 | 2 |
|
3 | | -use crate::impl_::not_send::{NotSend, NOT_SEND}; |
4 | | -use crate::{ffi, Python}; |
5 | | -use parking_lot::{const_mutex, Mutex, Once}; |
6 | | -use std::cell::Cell; |
7 | 3 | #[cfg(debug_assertions)] |
8 | 4 | use std::cell::RefCell; |
9 | 5 | #[cfg(not(debug_assertions))] |
10 | 6 | use std::cell::UnsafeCell; |
11 | | -use std::{mem, ptr::NonNull}; |
| 7 | +use std::{cell::Cell, mem, ptr::NonNull}; |
| 8 | + |
| 9 | +use parking_lot::{const_mutex, Mutex, Once}; |
| 10 | + |
| 11 | +use crate::{ |
| 12 | + ffi, |
| 13 | + impl_::not_send::{NotSend, NOT_SEND}, |
| 14 | + Python, |
| 15 | +}; |
12 | 16 |
|
13 | 17 | static START: Once = Once::new(); |
14 | 18 |
|
@@ -506,11 +510,13 @@ fn decrement_gil_count() { |
506 | 510 |
|
507 | 511 | #[cfg(test)] |
508 | 512 | mod tests { |
509 | | - use super::{gil_is_acquired, GILPool, GIL_COUNT, OWNED_OBJECTS, POOL}; |
510 | | - use crate::{ffi, gil, PyObject, Python, ToPyObject}; |
| 513 | + use std::ptr::NonNull; |
| 514 | + |
511 | 515 | #[cfg(not(target_arch = "wasm32"))] |
512 | 516 | use parking_lot::{const_mutex, Condvar, Mutex}; |
513 | | - use std::ptr::NonNull; |
| 517 | + |
| 518 | + use super::{gil_is_acquired, GILPool, GIL_COUNT, OWNED_OBJECTS, POOL}; |
| 519 | + use crate::{ffi, gil, PyObject, Python, ToPyObject}; |
514 | 520 |
|
515 | 521 | fn get_object(py: Python<'_>) -> PyObject { |
516 | 522 | // Convenience function for getting a single unique object, using `new_pool` so as to leave |
@@ -786,9 +792,10 @@ mod tests { |
786 | 792 | #[test] |
787 | 793 | #[cfg(not(target_arch = "wasm32"))] // We are building wasm Python with pthreads disabled |
788 | 794 | fn test_clone_without_gil() { |
789 | | - use crate::{Py, PyAny}; |
790 | 795 | use std::{sync::Arc, thread}; |
791 | 796 |
|
| 797 | + use crate::{Py, PyAny}; |
| 798 | + |
792 | 799 | // Some events for synchronizing |
793 | 800 | static GIL_ACQUIRED: Event = Event::new(); |
794 | 801 | static OBJECT_CLONED: Event = Event::new(); |
@@ -851,9 +858,10 @@ mod tests { |
851 | 858 | #[test] |
852 | 859 | #[cfg(not(target_arch = "wasm32"))] // We are building wasm Python with pthreads disabled |
853 | 860 | fn test_clone_in_other_thread() { |
854 | | - use crate::Py; |
855 | 861 | use std::{sync::Arc, thread}; |
856 | 862 |
|
| 863 | + use crate::Py; |
| 864 | + |
857 | 865 | // Some events for synchronizing |
858 | 866 | static OBJECT_CLONED: Event = Event::new(); |
859 | 867 |
|
@@ -925,4 +933,46 @@ mod tests { |
925 | 933 | POOL.update_counts(py); |
926 | 934 | }) |
927 | 935 | } |
| 936 | + |
| 937 | + #[cfg(feature = "macros")] |
| 938 | + #[test] |
| 939 | + fn allow_threads_fn() { |
| 940 | + #[crate::pyfunction(allow_threads, crate = "crate")] |
| 941 | + fn without_gil() { |
| 942 | + GIL_COUNT.with(|c| assert_eq!(c.get(), 0)); |
| 943 | + } |
| 944 | + Python::with_gil(|gil| { |
| 945 | + let without_gil = crate::wrap_pyfunction!(without_gil, gil).unwrap(); |
| 946 | + crate::py_run!(gil, without_gil, "without_gil()"); |
| 947 | + }) |
| 948 | + } |
| 949 | + |
| 950 | + #[cfg(feature = "macros")] |
| 951 | + #[test] |
| 952 | + fn allow_threads_async_fn() { |
| 953 | + #[crate::pyfunction(allow_threads, crate = "crate")] |
| 954 | + async fn without_gil() { |
| 955 | + use std::task::Poll; |
| 956 | + GIL_COUNT.with(|c| assert_eq!(c.get(), 0)); |
| 957 | + let mut ready = false; |
| 958 | + futures::future::poll_fn(|cx| { |
| 959 | + if ready { |
| 960 | + return Poll::Ready(()); |
| 961 | + } |
| 962 | + ready = true; |
| 963 | + cx.waker().wake_by_ref(); |
| 964 | + Poll::Pending |
| 965 | + }) |
| 966 | + .await; |
| 967 | + GIL_COUNT.with(|c| assert_eq!(c.get(), 0)); |
| 968 | + } |
| 969 | + Python::with_gil(|gil| { |
| 970 | + let without_gil = crate::wrap_pyfunction!(without_gil, gil).unwrap(); |
| 971 | + crate::py_run!( |
| 972 | + gil, |
| 973 | + without_gil, |
| 974 | + "import asyncio; asyncio.run(without_gil())" |
| 975 | + ); |
| 976 | + }) |
| 977 | + } |
928 | 978 | } |
0 commit comments