binaryninja/
background_task.rs1use binaryninjacore_sys::*;
18use std::fmt::Debug;
19
20use std::result;
21
22use crate::rc::*;
23use crate::string::*;
24
25pub type Result<R> = result::Result<R, ()>;
26
27pub struct OwnedBackgroundTaskGuard {
29 pub(crate) task: Ref<BackgroundTask>,
30}
31
32impl OwnedBackgroundTaskGuard {
33 pub fn cancel(&self) {
34 self.task.cancel();
35 }
36
37 pub fn is_cancelled(&self) -> bool {
38 self.task.is_cancelled()
39 }
40
41 pub fn set_progress_text(&self, text: &str) {
42 self.task.set_progress_text(text);
43 }
44}
45
46impl Drop for OwnedBackgroundTaskGuard {
47 fn drop(&mut self) {
48 self.task.finish();
49 }
50}
51
52#[derive(PartialEq, Eq, Hash)]
62pub struct BackgroundTask {
63 pub(crate) handle: *mut BNBackgroundTask,
64}
65
66impl BackgroundTask {
67 pub(crate) unsafe fn from_raw(handle: *mut BNBackgroundTask) -> Self {
68 debug_assert!(!handle.is_null());
69
70 Self { handle }
71 }
72
73 pub fn new(initial_text: &str, can_cancel: bool) -> Ref<Self> {
77 let text = initial_text.to_cstr();
78 let handle = unsafe { BNBeginBackgroundTask(text.as_ptr(), can_cancel) };
79 assert!(!handle.is_null());
81 unsafe { Ref::new(Self { handle }) }
82 }
83
84 pub fn enter(&self) -> OwnedBackgroundTaskGuard {
88 OwnedBackgroundTaskGuard {
89 task: self.to_owned(),
90 }
91 }
92
93 pub fn can_cancel(&self) -> bool {
94 unsafe { BNCanCancelBackgroundTask(self.handle) }
95 }
96
97 pub fn is_cancelled(&self) -> bool {
98 unsafe { BNIsBackgroundTaskCancelled(self.handle) }
99 }
100
101 pub fn cancel(&self) {
102 unsafe { BNCancelBackgroundTask(self.handle) }
103 }
104
105 pub fn is_finished(&self) -> bool {
106 unsafe { BNIsBackgroundTaskFinished(self.handle) }
107 }
108
109 pub fn finish(&self) {
110 unsafe { BNFinishBackgroundTask(self.handle) }
111 }
112
113 pub fn progress_text(&self) -> String {
114 unsafe { BnString::into_string(BNGetBackgroundTaskProgressText(self.handle)) }
115 }
116
117 pub fn set_progress_text(&self, text: &str) {
118 let progress_text = text.to_cstr();
119 unsafe { BNSetBackgroundTaskProgressText(self.handle, progress_text.as_ptr()) }
120 }
121
122 pub fn running_tasks() -> Array<BackgroundTask> {
123 unsafe {
124 let mut count = 0;
125 let handles = BNGetRunningBackgroundTasks(&mut count);
126 Array::new(handles, count, ())
127 }
128 }
129}
130
131impl Debug for BackgroundTask {
132 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
133 f.debug_struct("BackgroundTask")
134 .field("progress_text", &self.progress_text())
135 .field("can_cancel", &self.can_cancel())
136 .field("is_cancelled", &self.is_cancelled())
137 .field("is_finished", &self.is_finished())
138 .finish()
139 }
140}
141
142unsafe impl RefCountable for BackgroundTask {
143 unsafe fn inc_ref(handle: &Self) -> Ref<Self> {
144 Ref::new(Self {
145 handle: BNNewBackgroundTaskReference(handle.handle),
146 })
147 }
148
149 unsafe fn dec_ref(handle: &Self) {
150 BNFreeBackgroundTask(handle.handle);
151 }
152}
153
154impl CoreArrayProvider for BackgroundTask {
155 type Raw = *mut BNBackgroundTask;
156 type Context = ();
157 type Wrapped<'a> = Guard<'a, BackgroundTask>;
158}
159
160unsafe impl CoreArrayProviderInner for BackgroundTask {
161 unsafe fn free(raw: *mut *mut BNBackgroundTask, count: usize, _context: &()) {
162 BNFreeBackgroundTaskList(raw, count);
163 }
164 unsafe fn wrap_raw<'a>(raw: &'a *mut BNBackgroundTask, context: &'a ()) -> Self::Wrapped<'a> {
165 Guard::new(BackgroundTask::from_raw(*raw), context)
166 }
167}
168
169impl ToOwned for BackgroundTask {
170 type Owned = Ref<Self>;
171
172 fn to_owned(&self) -> Self::Owned {
173 unsafe { RefCountable::inc_ref(self) }
174 }
175}
176
177unsafe impl Send for BackgroundTask {}
178unsafe impl Sync for BackgroundTask {}