jvmti_rs/wrapper/jvmtifns/
thread.rs1use std::{
2 ffi::c_void,
3 ptr,
4};
5use jni::sys::jobject;
6use crate::{builder::*, errors::*, JThreadInfo, JVMTIEnv, JvmtiError, JvmtiThreadPriority, JvmtiThreadState, objects::*, sys::*};
7
8impl<'a> JVMTIEnv<'a> {
9 pub fn get_thread_state(&self, thread: &JThreadID) -> Result<JvmtiThreadState> {
10 let res = jvmti_call_number_result!(self.jvmti_raw(), jint,
11 GetThreadState,
12 thread.into()
13 );
14 Ok((res as jvmtiThreadState).into())
15 }
16
17 pub fn get_current_thread(&self) -> Result<Option<JThreadID>> {
18 let mut thread_ptr: jthread = ptr::null_mut();
19 let res = jvmti_call_result!(self.jvmti_raw(), GetCurrentThread,
20 &mut thread_ptr
21 );
22
23 jvmti_error_code_to_result(res)?;
24
25 if thread_ptr.is_null() {
26 return Ok(None);
27 }
28 Ok(Some(thread_ptr.into()))
29 }
30
31 pub fn get_all_threads(&self) -> Result<Vec<JThreadID>> {
32 let mut builder: MutAutoDeallocateObjectArrayBuilder<jthread> = MutAutoDeallocateObjectArrayBuilder::new();
33 let res = jvmti_call_result!(self.jvmti_raw(), GetAllThreads,
34 &mut builder.count,
35 &mut builder.items
36 );
37 jvmti_error_code_to_result(res)?;
38 Ok(builder.build(self))
39 }
40
41 pub fn suspend_thread(&self, thread: &JThreadID) -> Result<()> {
42 jvmti_call!(self.jvmti_raw(), SuspendThread,
43 thread.into()
44 )
45 }
46
47 pub fn resume_thread(&self, thread: &JThreadID) -> Result<()> {
48 jvmti_call!(self.jvmti_raw(), ResumeThread,
49 thread.into()
50 )
51 }
52
53 pub fn stop_thread(&self, thread: &JThreadID, exception: &JThrowable) -> Result<()> {
54 jvmti_call!(self.jvmti_raw(), StopThread,
55 thread.into(),
56 exception.into_inner()
57 )
58 }
59
60 pub fn interrupt_thread(&self, thread: &JThreadID) -> Result<()> {
61 jvmti_call!(self.jvmti_raw(), InterruptThread,
62 thread.into()
63 )
64 }
65
66 pub fn suspend_thread_list(&self, threads: &Vec<JThreadID>) -> Result<JvmtiError> {
67 if threads.is_empty() {
68 return Ok(JvmtiError::EmptyArgument);
69 }
70 let thread_ids: Vec<jthread> = threads.iter().map(|&e| e.into()).collect();
71 let res = jvmti_call_number_result!(self.jvmti_raw(), jvmtiError,
72 SuspendThreadList,
73 thread_ids.len() as jint,
74 thread_ids.as_ptr()
75 );
76 Ok(res.into())
77 }
78
79 pub fn resume_thread_list(&self, threads: &Vec<JThreadID>) -> Result<JvmtiError> {
80 if threads.is_empty() {
81 return Ok(JvmtiError::EmptyArgument);
82 }
83 let thread_ids: Vec<jthread> = threads.iter().map(|&e| e.into()).collect();
84 let res = jvmti_call_number_result!(self.jvmti_raw(), jvmtiError,
85 ResumeThreadList,
86 thread_ids.len() as jint,
87 thread_ids.as_ptr()
88 );
89 Ok(res.into())
90 }
91
92 pub fn get_thread_info(&self, thread: &JThreadID) -> Result<JThreadInfo> {
93 let mut into = JThreadInfo::empty_raw();
94 let res = jvmti_call_result!(self.jvmti_raw(), GetThreadInfo,
95 thread.into(),
96 &mut into
97 );
98 jvmti_error_code_to_result(res)?;
99 Ok(JThreadInfo::new(into))
100 }
101
102 pub fn get_owned_monitor_info(&self, thread: &JThreadID) -> Result<Vec<JObject>> {
103 let mut builder: MutAutoDeallocateObjectArrayBuilder<jobject> = MutAutoDeallocateObjectArrayBuilder::new();
104 let res = jvmti_call_result!(self.jvmti_raw(), GetOwnedMonitorInfo,
105 thread.into(),
106 &mut builder.count,
107 &mut builder.items
108 );
109 jvmti_error_code_to_result(res)?;
110 Ok(builder.build(self))
111 }
112
113 pub fn get_owned_monitor_stack_depth_info(&self, thread: &JThreadID) -> Result<Vec<JMonitorStackDepthInfo>> {
114 let mut builder: MutAutoDeallocateObjectArrayBuilder<jvmtiMonitorStackDepthInfo> = MutAutoDeallocateObjectArrayBuilder::new();
115 let res = jvmti_call_result!( self.jvmti_raw(), GetOwnedMonitorStackDepthInfo,
116 thread.into(),
117 &mut builder.count,
118 &mut builder.items
119 );
120 jvmti_error_code_to_result(res)?;
121 Ok(builder.build(self))
122 }
123
124 pub fn get_current_contended_monitor(&self, thread: &JThreadID) -> Result<Option<JObject>> {
125 let res = jvmti_call_ptr_result!(self.jvmti_raw(), jobject,
126 GetCurrentContendedMonitor,
127 thread.into()
128 );
129 if res.is_null() {
130 return Ok(None);
131 }
132 Ok(Some(res.into()))
133 }
134
135 pub fn run_agent_thread(&self, thread: &JThreadID,
136 proc: jvmtiStartFunction,
137 arg: *const c_void,
138 priority: JvmtiThreadPriority,
139 ) -> Result<()> {
140 jvmti_call!(self.jvmti_raw(), RunAgentThread,
141 thread.into(),
142 proc,
143 arg,
144 priority.into()
145 )
146 }
147
148 pub fn get_thread_local_storage(&self, thread: &JThreadID) -> Result<JLocalStorage> {
149 let mut data_ptr: *mut c_void = ptr::null_mut() as *mut c_void;
150 let res = jvmti_call_result!(self.jvmti_raw(), GetThreadLocalStorage,
151 thread.into(),
152 &mut data_ptr
153 );
154 jvmti_error_code_to_result(res)?;
155 Ok(JLocalStorage::new(data_ptr))
156 }
157
158 pub fn set_thread_local_storage(&self, thread: &JThreadID, data: &JLocalStorage) -> Result<()> {
159 jvmti_call!(self.jvmti_raw(), SetThreadLocalStorage,
160 thread.into(),
161 data.as_ptr()
162 )
163 }
164}