jvmti_rs/wrapper/jvmtifns/
thread.rs

1use 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}