63 lines
1.5 KiB
Rust
63 lines
1.5 KiB
Rust
#![cfg(feature = "invocation")]
|
|
|
|
use std::{sync::Arc, thread::spawn};
|
|
|
|
use jni::{
|
|
errors::{Error, JniError},
|
|
Executor, JavaVM,
|
|
};
|
|
|
|
mod util;
|
|
use util::jvm;
|
|
|
|
/// Checks if nested attaches are working properly and threads detach themselves
|
|
/// on exit.
|
|
#[test]
|
|
fn nested_attach() {
|
|
let executor = Executor::new(jvm().clone());
|
|
|
|
assert_eq!(jvm().threads_attached(), 0);
|
|
let thread = spawn(|| {
|
|
assert_eq!(jvm().threads_attached(), 0);
|
|
check_nested_attach(jvm(), executor);
|
|
assert_eq!(jvm().threads_attached(), 1);
|
|
});
|
|
thread.join().unwrap();
|
|
assert_eq!(jvm().threads_attached(), 0);
|
|
}
|
|
|
|
/// Checks if nested `with_attached` calls does not detach the thread before the outer-most
|
|
/// call is finished.
|
|
fn check_nested_attach(vm: &Arc<JavaVM>, executor: Executor) {
|
|
check_detached(vm);
|
|
executor
|
|
.with_attached(|_| {
|
|
check_attached(vm);
|
|
executor.with_attached(|_| {
|
|
check_attached(vm);
|
|
Ok(())
|
|
})?;
|
|
check_attached(vm);
|
|
Ok(())
|
|
})
|
|
.unwrap();
|
|
}
|
|
|
|
fn check_attached(vm: &JavaVM) {
|
|
assert!(is_attached(vm));
|
|
}
|
|
|
|
fn check_detached(vm: &JavaVM) {
|
|
assert!(!is_attached(vm));
|
|
}
|
|
|
|
fn is_attached(vm: &JavaVM) -> bool {
|
|
vm.get_env()
|
|
.map(|_| true)
|
|
.or_else(|jni_err| match jni_err {
|
|
Error::JniCall(JniError::ThreadDetached) => Ok(false),
|
|
_ => Err(jni_err),
|
|
})
|
|
.expect("An unexpected JNI error occurred")
|
|
}
|