1 #![cfg(feature = "invocation")]
2
3 mod util;
4 use util::{
5 attach_current_thread, attach_current_thread_as_daemon, attach_current_thread_permanently,
6 call_java_abs, jvm,
7 };
8
9 #[test]
nested_attaches_should_not_detach_guarded_thread()10 pub fn nested_attaches_should_not_detach_guarded_thread() {
11 assert_eq!(jvm().threads_attached(), 0);
12 let mut env = attach_current_thread();
13 let val = call_java_abs(&mut env, -1);
14 assert_eq!(val, 1);
15 assert_eq!(jvm().threads_attached(), 1);
16
17 // Create nested AttachGuard.
18 {
19 let mut env_nested = attach_current_thread();
20 let val = call_java_abs(&mut env_nested, -2);
21 assert_eq!(val, 2);
22 assert_eq!(jvm().threads_attached(), 1);
23 }
24
25 // Call a Java method after nested guard has been dropped to check that
26 // this thread has not been detached.
27 let val = call_java_abs(&mut env, -3);
28 assert_eq!(val, 3);
29 assert_eq!(jvm().threads_attached(), 1);
30
31 // Nested attach_permanently is a no-op.
32 {
33 let mut env_nested = attach_current_thread_permanently();
34 let val = call_java_abs(&mut env_nested, -4);
35 assert_eq!(val, 4);
36 assert_eq!(jvm().threads_attached(), 1);
37 }
38 assert_eq!(jvm().threads_attached(), 1);
39
40 // Nested attach_as_daemon is a no-op.
41 {
42 let mut env_nested = attach_current_thread_as_daemon();
43 let val = call_java_abs(&mut env_nested, -5);
44 assert_eq!(val, 5);
45 assert_eq!(jvm().threads_attached(), 1);
46 }
47 assert_eq!(jvm().threads_attached(), 1);
48
49 // Check that after guard is dropped the thread is properly detached
50 // despite nested "permanent" attaches.
51 drop(env);
52 assert_eq!(jvm().threads_attached(), 0);
53 assert!(jvm().get_env().is_err());
54 }
55